From 2535ba7006f22a6470f4c88ea7d30c343a1d8799 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 28 Sep 2017 17:17:45 +0200 Subject: src: get rid of printf This patch introduces nft_print()/nft_gmp_print() functions which have to be used instead of printf to output information that were previously send to stdout. These functions print to a FILE pointer defined in struct output_ctx. It is set by calling: | old_fp = nft_ctx_set_output(ctx, new_fp); Having an application-defined FILE pointer is actually quite flexible: Using fmemopen() or even fopencookie(), an application gains full control over what is printed and where it should go to. Signed-off-by: Eric Leblond Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- src/netlink.c | 126 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 64 insertions(+), 62 deletions(-) (limited to 'src/netlink.c') diff --git a/src/netlink.c b/src/netlink.c index 3183a810..d5d410a8 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -39,6 +39,8 @@ #include #include +#define nft_mon_print(monh, ...) nft_print(monh->ctx->octx, __VA_ARGS__) + const struct input_descriptor indesc_netlink = { .name = "netlink", .type = INDESC_NETLINK, @@ -470,7 +472,7 @@ int netlink_replace_rule_batch(struct netlink_ctx *ctx, const struct handle *h, if (ctx->octx->echo) { err = cache_update(ctx->nf_sock, ctx->cache, CMD_INVALID, ctx->msgs, - ctx->debug_mask & DEBUG_NETLINK); + ctx->debug_mask & DEBUG_NETLINK, ctx->octx); if (err < 0) return err; @@ -504,15 +506,15 @@ int netlink_del_rule_batch(struct netlink_ctx *ctx, const struct handle *h, return err; } -void netlink_dump_rule(const struct nftnl_rule *nlr, unsigned int debug_mask) +void netlink_dump_rule(const struct nftnl_rule *nlr, struct netlink_ctx *ctx) { - char buf[4096]; + FILE *fp = ctx->octx->output_fp; - if (!(debug_mask & DEBUG_NETLINK)) + if (!(ctx->debug_mask & DEBUG_NETLINK) || !fp) return; - nftnl_rule_snprintf(buf, sizeof(buf), nlr, 0, 0); - fprintf(stdout, "%s\n", buf); + nftnl_rule_fprintf(fp, nlr, 0, 0); + fprintf(fp, "\n"); } void netlink_dump_expr(const struct nftnl_expr *nle, @@ -544,7 +546,7 @@ static int list_rule_cb(struct nftnl_rule *nlr, void *arg) (h->chain && strcmp(chain, h->chain) != 0)) return 0; - netlink_dump_rule(nlr, ctx->debug_mask); + netlink_dump_rule(nlr, ctx); rule = netlink_delinearize_rule(ctx, nlr); list_add_tail(&rule->list, &ctx->list); @@ -576,15 +578,15 @@ static int netlink_flush_rules(struct netlink_ctx *ctx, const struct handle *h, return netlink_del_rule_batch(ctx, h, loc); } -void netlink_dump_chain(const struct nftnl_chain *nlc, unsigned int debug_mask) +void netlink_dump_chain(const struct nftnl_chain *nlc, struct netlink_ctx *ctx) { - char buf[4096]; + FILE *fp = ctx->octx->output_fp; - if (!(debug_mask & DEBUG_NETLINK)) + if (!(ctx->debug_mask & DEBUG_NETLINK) || !fp) return; - nftnl_chain_snprintf(buf, sizeof(buf), nlc, 0, 0); - fprintf(stdout, "%s\n", buf); + nftnl_chain_fprintf(fp, nlc, 0, 0); + fprintf(fp, "\n"); } static int netlink_add_chain_compat(struct netlink_ctx *ctx, @@ -610,7 +612,7 @@ static int netlink_add_chain_compat(struct netlink_ctx *ctx, chain->policy); } - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_add(ctx->nf_sock, nlc, flags, ctx->seqnum); nftnl_chain_free(nlc); @@ -646,7 +648,7 @@ static int netlink_add_chain_batch(struct netlink_ctx *ctx, chain->dev); } - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_batch_add(nlc, ctx->batch, flags, ctx->seqnum); nftnl_chain_free(nlc); @@ -676,7 +678,7 @@ static int netlink_rename_chain_compat(struct netlink_ctx *ctx, nlc = alloc_nftnl_chain(h); nftnl_chain_set_str(nlc, NFTNL_CHAIN_NAME, name); - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_add(ctx->nf_sock, nlc, 0, ctx->seqnum); nftnl_chain_free(nlc); @@ -696,7 +698,7 @@ static int netlink_rename_chain_batch(struct netlink_ctx *ctx, nlc = alloc_nftnl_chain(h); nftnl_chain_set_str(nlc, NFTNL_CHAIN_NAME, name); - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_batch_add(nlc, ctx->batch, 0, ctx->seqnum); nftnl_chain_free(nlc); @@ -723,7 +725,7 @@ static int netlink_del_chain_compat(struct netlink_ctx *ctx, int err; nlc = alloc_nftnl_chain(h); - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_delete(ctx->nf_sock, nlc, 0, ctx->seqnum); nftnl_chain_free(nlc); @@ -741,7 +743,7 @@ static int netlink_del_chain_batch(struct netlink_ctx *ctx, int err; nlc = alloc_nftnl_chain(h); - netlink_dump_chain(nlc, ctx->debug_mask); + netlink_dump_chain(nlc, ctx); err = mnl_nft_chain_batch_del(nlc, ctx->batch, 0, ctx->seqnum); nftnl_chain_free(nlc); @@ -1031,15 +1033,15 @@ static const struct datatype *dtype_map_from_kernel(enum nft_data_types type) } } -void netlink_dump_set(const struct nftnl_set *nls, unsigned int debug_mask) +void netlink_dump_set(const struct nftnl_set *nls, struct netlink_ctx *ctx) { - char buf[4096]; + FILE *fp = ctx->octx->output_fp; - if (!(debug_mask & DEBUG_NETLINK)) + if (!(ctx->debug_mask & DEBUG_NETLINK) || !fp) return; - nftnl_set_snprintf(buf, sizeof(buf), nls, 0, 0); - fprintf(stdout, "%s\n", buf); + nftnl_set_fprintf(fp, nls, 0, 0); + fprintf(fp, "\n"); } static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data) @@ -1171,7 +1173,7 @@ static int netlink_add_set_compat(struct netlink_ctx *ctx, nftnl_set_set_u32(nls, NFTNL_SET_DATA_LEN, set->datalen / BITS_PER_BYTE); } - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_set_add(ctx->nf_sock, nls, NLM_F_ECHO | flags, ctx->seqnum); @@ -1242,7 +1244,7 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx, nftnl_udata_buf_len(udbuf)); nftnl_udata_buf_free(udbuf); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_set_batch_add(nls, ctx->batch, flags, ctx->seqnum); if (err < 0) @@ -1357,7 +1359,7 @@ static int netlink_add_setelems_batch(struct netlink_ctx *ctx, nls = alloc_nftnl_set(h); alloc_setelem_cache(expr, nls); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_setelem_batch_add(nls, ctx->batch, flags, ctx->seqnum); nftnl_set_free(nls); @@ -1377,7 +1379,7 @@ static int netlink_add_setelems_compat(struct netlink_ctx *ctx, nls = alloc_nftnl_set(h); alloc_setelem_cache(expr, nls); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_setelem_add(ctx->nf_sock, nls, flags, ctx->seqnum); nftnl_set_free(nls); @@ -1407,7 +1409,7 @@ static int netlink_del_setelems_batch(struct netlink_ctx *ctx, nls = alloc_nftnl_set(h); if (expr) alloc_setelem_cache(expr, nls); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_setelem_batch_del(nls, ctx->batch, 0, ctx->seqnum); nftnl_set_free(nls); @@ -1427,7 +1429,7 @@ static int netlink_del_setelems_compat(struct netlink_ctx *ctx, nls = alloc_nftnl_set(h); alloc_setelem_cache(expr, nls); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_setelem_delete(ctx->nf_sock, nls, 0, ctx->seqnum); nftnl_set_free(nls); @@ -1445,7 +1447,7 @@ int netlink_flush_setelems(struct netlink_ctx *ctx, const struct handle *h, int err; nls = alloc_nftnl_set(h); - netlink_dump_set(nls, ctx->debug_mask); + netlink_dump_set(nls, ctx); err = mnl_nft_setelem_batch_flush(nls, ctx->batch, 0, ctx->seqnum); nftnl_set_free(nls); @@ -1657,15 +1659,15 @@ out: return err; } -void netlink_dump_obj(struct nftnl_obj *nln, unsigned int debug_mask) +void netlink_dump_obj(struct nftnl_obj *nln, struct netlink_ctx *ctx) { - char buf[4096]; + FILE *fp = ctx->octx->output_fp; - if (!(debug_mask & DEBUG_NETLINK)) + if (!(ctx->debug_mask & DEBUG_NETLINK) || !fp) return; - nftnl_obj_snprintf(buf, sizeof(buf), nln, 0, 0); - fprintf(stdout, "%s\n", buf); + nftnl_obj_fprintf(fp, nln, 0, 0); + fprintf(fp, "\n"); } int netlink_add_obj(struct netlink_ctx *ctx, const struct handle *h, @@ -1675,7 +1677,7 @@ int netlink_add_obj(struct netlink_ctx *ctx, const struct handle *h, int err; nlo = alloc_nftnl_obj(h, obj); - netlink_dump_obj(nlo, ctx->debug_mask); + netlink_dump_obj(nlo, ctx); err = mnl_nft_obj_batch_add(nlo, ctx->batch, flags, ctx->seqnum); if (err < 0) @@ -1693,7 +1695,7 @@ int netlink_delete_obj(struct netlink_ctx *ctx, const struct handle *h, int err; nlo = __alloc_nftnl_obj(h, type); - netlink_dump_obj(nlo, ctx->debug_mask); + netlink_dump_obj(nlo, ctx); err = mnl_nft_obj_batch_del(nlo, ctx->batch, 0, ctx->seqnum); if (err < 0) @@ -1999,16 +2001,16 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type, case NFTNL_OUTPUT_DEFAULT: if (type == NFT_MSG_NEWTABLE) { if (nlh->nlmsg_flags & NLM_F_EXCL) - printf("update table "); + nft_mon_print(monh, "update table "); else - printf("add table "); + nft_mon_print(monh, "add table "); } else { - printf("delete table "); + nft_mon_print(monh, "delete table "); } family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY); - printf("%s %s\n", family2str(family), + nft_mon_print(monh, "%s %s\n", family2str(family), nftnl_table_get_str(nlt, NFTNL_TABLE_NAME)); break; case NFTNL_OUTPUT_XML: @@ -2037,17 +2039,17 @@ static int netlink_events_chain_cb(const struct nlmsghdr *nlh, int type, switch (type) { case NFT_MSG_NEWCHAIN: if (nlh->nlmsg_flags & NLM_F_EXCL) - printf("update "); + nft_mon_print(monh, "update "); else - printf("add "); + nft_mon_print(monh, "add "); c = netlink_delinearize_chain(monh->ctx, nlc); - chain_print_plain(c); + chain_print_plain(c, monh->ctx->octx); chain_free(c); break; case NFT_MSG_DELCHAIN: family = nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY); - printf("delete chain %s %s %s\n", family2str(family), + nft_mon_print(monh, "delete chain %s %s %s\n", family2str(family), nftnl_chain_get_str(nlc, NFTNL_CHAIN_TABLE), nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME)); break; @@ -2081,7 +2083,7 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type, case NFTNL_OUTPUT_DEFAULT: switch (type) { case NFT_MSG_NEWSET: - printf("add "); + nft_mon_print(monh, "add "); set = netlink_delinearize_set(monh->ctx, nls); if (set == NULL) { nftnl_set_free(nls); @@ -2089,11 +2091,11 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type, } set_print_plain(set, monh->ctx->octx); set_free(set); - printf("\n"); + nft_mon_print(monh, "\n"); break; case NFT_MSG_DELSET: family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY); - printf("delete set %s %s %s\n", + nft_mon_print(monh, "delete set %s %s %s\n", family2str(family), nftnl_set_get_str(nls, NFTNL_SET_TABLE), nftnl_set_get_str(nls, NFTNL_SET_NAME)); @@ -2234,18 +2236,18 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, switch (type) { case NFT_MSG_NEWSETELEM: - printf("add "); + nft_mon_print(monh, "add "); break; case NFT_MSG_DELSETELEM: - printf("delete "); + nft_mon_print(monh, "delete "); break; default: set_free(dummyset); goto out; } - printf("element %s %s %s ", family2str(family), table, setname); + nft_mon_print(monh, "element %s %s %s ", family2str(family), table, setname); expr_print(dummyset->init, monh->ctx->octx); - printf("\n"); + nft_mon_print(monh, "\n"); set_free(dummyset); break; @@ -2274,7 +2276,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, case NFTNL_OUTPUT_DEFAULT: switch (type) { case NFT_MSG_NEWOBJ: - printf("add "); + nft_mon_print(monh, "add "); obj = netlink_delinearize_obj(monh->ctx, nlo); if (obj == NULL) { nftnl_obj_free(nlo); @@ -2282,11 +2284,11 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, } obj_print_plain(obj, monh->ctx->octx); obj_free(obj); - printf("\n"); + nft_mon_print(monh, "\n"); break; case NFT_MSG_DELOBJ: family = nftnl_obj_get_u32(nlo, NFTNL_OBJ_FAMILY); - printf("delete %s %s %s %s\n", + nft_mon_print(monh, "delete %s %s %s %s\n", obj_type_name(nftnl_obj_get_u32(nlo, NFTNL_OBJ_TYPE)), family2str(family), nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE), @@ -2338,14 +2340,14 @@ static int netlink_events_rule_cb(const struct nlmsghdr *nlh, int type, nlr_for_each_set(nlr, rule_map_decompose_cb, NULL, monh->cache); - printf("add rule %s %s %s ", family, table, chain); + nft_mon_print(monh, "add rule %s %s %s ", family, table, chain); rule_print(r, monh->ctx->octx); - printf("\n"); + nft_mon_print(monh, "\n"); rule_free(r); break; case NFT_MSG_DELRULE: - printf("delete rule %s %s %s handle %u\n", + nft_mon_print(monh, "delete rule %s %s %s handle %u\n", family, table, chain, (unsigned int)handle); break; } @@ -2923,13 +2925,13 @@ static int netlink_events_newgen_cb(const struct nlmsghdr *nlh, int type, } } if (genid >= 0) { - printf("# new generation %d", genid); + nft_mon_print(monh, "# new generation %d", genid); if (pid >= 0) { - printf(" by process %d", pid); + nft_mon_print(monh, " by process %d", pid); if (!monh->ctx->octx->numeric) - printf(" (%s)", name); + nft_mon_print(monh, " (%s)", name); } - printf("\n"); + nft_mon_print(monh, "\n"); } return MNL_CB_OK; -- cgit v1.2.3