void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) { int verdict = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_VERDICT); const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN); struct nft_family_ops *ops; const char *jumpto = NULL; bool nft_goto = false; void *data = nft_get_data(ctx); /* Standard target? */ switch(verdict) { case NF_ACCEPT: jumpto = "ACCEPT"; break; case NF_DROP: jumpto = "DROP"; break; case NFT_RETURN: jumpto = "RETURN"; break;; case NFT_GOTO: nft_goto = true; case NFT_JUMP: jumpto = chain; break; } ops = nft_family_ops_lookup(ctx->family); ops->parse_immediate(jumpto, nft_goto, data); }
void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e) { uint32_t tg_len; const char *targname = nftnl_expr_get_str(e, NFTNL_EXPR_TG_NAME); const void *targinfo = nftnl_expr_get(e, NFTNL_EXPR_TG_INFO, &tg_len); struct xtables_target *target; struct xt_entry_target *t; size_t size; struct nft_family_ops *ops; void *data = nft_get_data(ctx); target = xtables_find_target(targname, XTF_TRY_LOAD); if (target == NULL) return; size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len; t = calloc(1, size); if (t == NULL) { fprintf(stderr, "OOM"); exit(EXIT_FAILURE); } memcpy(&t->data, targinfo, tg_len); t->u.target_size = size; t->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV); strcpy(t->u.user.name, target->name); target->t = t; ops = nft_family_ops_lookup(ctx->family); ops->parse_target(target, data); }
static int rule_expr_cb(struct nftnl_expr *expr, void *data) { struct callback_data *cb = data; const char *name; name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); if (strcmp(name, "counter")) { cb->value = nftnl_expr_get_u64(expr, NFTNL_EXPR_CTR_BYTES); cb->success = true; } return 0; }
void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e) { uint32_t mt_len; const char *mt_name = nftnl_expr_get_str(e, NFTNL_EXPR_MT_NAME); const void *mt_info = nftnl_expr_get(e, NFTNL_EXPR_MT_INFO, &mt_len); struct xtables_match *match; struct xtables_rule_match **matches; struct xt_entry_match *m; struct nft_family_ops *ops; switch (ctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: matches = &ctx->state.cs->matches; break; case NFPROTO_BRIDGE: matches = &ctx->state.cs_eb->matches; break; default: fprintf(stderr, "BUG: nft_parse_match() unknown family %d\n", ctx->family); exit(EXIT_FAILURE); } match = xtables_find_match(mt_name, XTF_TRY_LOAD, matches); if (match == NULL) return; m = calloc(1, sizeof(struct xt_entry_match) + mt_len); if (m == NULL) { fprintf(stderr, "OOM"); exit(EXIT_FAILURE); } memcpy(&m->data, mt_info, mt_len); m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match)); m->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV); strcpy(m->u.user.name, match->name); match->m = m; ops = nft_family_ops_lookup(ctx->family); if (ops->parse_match != NULL) ops->parse_match(match, nft_get_data(ctx)); }
void nft_rule_to_iptables_command_state(struct nftnl_rule *r, struct iptables_command_state *cs) { struct nftnl_expr_iter *iter; struct nftnl_expr *expr; int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY); struct nft_xt_ctx ctx = { .state.cs = cs, .family = family, }; iter = nftnl_expr_iter_create(r); if (iter == NULL) return; ctx.iter = iter; expr = nftnl_expr_iter_next(iter); while (expr != NULL) { const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); if (strcmp(name, "counter") == 0) nft_parse_counter(expr, &ctx.state.cs->counters); else if (strcmp(name, "payload") == 0) nft_parse_payload(&ctx, expr); else if (strcmp(name, "meta") == 0) nft_parse_meta(&ctx, expr); else if (strcmp(name, "bitwise") == 0) nft_parse_bitwise(&ctx, expr); else if (strcmp(name, "cmp") == 0) nft_parse_cmp(&ctx, expr); else if (strcmp(name, "immediate") == 0) nft_parse_immediate(&ctx, expr); else if (strcmp(name, "match") == 0) nft_parse_match(&ctx, expr); else if (strcmp(name, "target") == 0) nft_parse_target(&ctx, expr); expr = nftnl_expr_iter_next(iter); } nftnl_expr_iter_destroy(iter); if (cs->target != NULL) cs->jumpto = cs->target->name; else if (cs->jumpto != NULL) cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); else cs->jumpto = ""; } void print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, bool basechain, uint32_t refs) { printf("Chain %s", chain); if (basechain) { printf(" (policy %s", pol); if (!(format & FMT_NOCOUNTS)) { fputc(' ', stdout); xtables_print_num(counters->pcnt, (format|FMT_NOTABLE)); fputs("packets, ", stdout); xtables_print_num(counters->bcnt, (format|FMT_NOTABLE)); fputs("bytes", stdout); } printf(")\n"); } else { printf(" (%u references)\n", refs); } if (format & FMT_LINENUMBERS) printf(FMT("%-4s ", "%s "), "num"); if (!(format & FMT_NOCOUNTS)) { if (format & FMT_KILOMEGAGIGA) { printf(FMT("%5s ","%s "), "pkts"); printf(FMT("%5s ","%s "), "bytes"); } else { printf(FMT("%8s ","%s "), "pkts"); printf(FMT("%10s ","%s "), "bytes"); } } if (!(format & FMT_NOTARGET)) printf(FMT("%-9s ","%s "), "target"); fputs(" prot ", stdout); if (format & FMT_OPTIONS) fputs("opt", stdout); if (format & FMT_VIA) { printf(FMT(" %-6s ","%s "), "in"); printf(FMT("%-6s ","%s "), "out"); } printf(FMT(" %-19s ","%s "), "source"); printf(FMT(" %-19s "," %s "), "destination"); printf("\n"); }
void nft_rule_to_iptables_command_state(struct nftnl_rule *r, struct iptables_command_state *cs) { struct nftnl_expr_iter *iter; struct nftnl_expr *expr; int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY); struct nft_xt_ctx ctx = { .state.cs = cs, .family = family, }; iter = nftnl_expr_iter_create(r); if (iter == NULL) return; ctx.iter = iter; expr = nftnl_expr_iter_next(iter); while (expr != NULL) { const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); if (strcmp(name, "counter") == 0) nft_parse_counter(expr, &ctx.state.cs->counters); else if (strcmp(name, "payload") == 0) nft_parse_payload(&ctx, expr); else if (strcmp(name, "meta") == 0) nft_parse_meta(&ctx, expr); else if (strcmp(name, "bitwise") == 0) nft_parse_bitwise(&ctx, expr); else if (strcmp(name, "cmp") == 0) nft_parse_cmp(&ctx, expr); else if (strcmp(name, "immediate") == 0) nft_parse_immediate(&ctx, expr); else if (strcmp(name, "match") == 0) nft_parse_match(&ctx, expr); else if (strcmp(name, "target") == 0) nft_parse_target(&ctx, expr); expr = nftnl_expr_iter_next(iter); } nftnl_expr_iter_destroy(iter); if (nftnl_rule_is_set(r, NFTNL_RULE_USERDATA)) { const void *data; uint32_t len; struct xtables_match *match; struct xt_entry_match *m; data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len); match = xtables_find_match("comment", XTF_TRY_LOAD, &cs->matches); if (match == NULL) return; m = calloc(1, sizeof(struct xt_entry_match) + len); if (m == NULL) { fprintf(stderr, "OOM"); exit(EXIT_FAILURE); } memcpy(&m->data, get_comment(data, len), len); m->u.match_size = len + XT_ALIGN(sizeof(struct xt_entry_match)); m->u.user.revision = 0; strcpy(m->u.user.name, match->name); match->m = m; } if (cs->target != NULL) cs->jumpto = cs->target->name; else if (cs->jumpto != NULL) cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); else cs->jumpto = ""; } void print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, bool basechain, uint32_t refs) { printf("Chain %s", chain); if (basechain) { printf(" (policy %s", pol); if (!(format & FMT_NOCOUNTS)) { fputc(' ', stdout); xtables_print_num(counters->pcnt, (format|FMT_NOTABLE)); fputs("packets, ", stdout); xtables_print_num(counters->bcnt, (format|FMT_NOTABLE)); fputs("bytes", stdout); } printf(")\n"); } else { printf(" (%u references)\n", refs); } if (format & FMT_LINENUMBERS) printf(FMT("%-4s ", "%s "), "num"); if (!(format & FMT_NOCOUNTS)) { if (format & FMT_KILOMEGAGIGA) { printf(FMT("%5s ","%s "), "pkts"); printf(FMT("%5s ","%s "), "bytes"); } else { printf(FMT("%8s ","%s "), "pkts"); printf(FMT("%10s ","%s "), "bytes"); } } if (!(format & FMT_NOTARGET)) printf(FMT("%-9s ","%s "), "target"); fputs(" prot ", stdout); if (format & FMT_OPTIONS) fputs("opt", stdout); if (format & FMT_VIA) { printf(FMT(" %-6s ","%s "), "in"); printf(FMT("%-6s ","%s "), "out"); } printf(FMT(" %-19s ","%s "), "source"); printf(FMT(" %-19s "," %s "), "destination"); printf("\n"); }