void nl_cli_ct_parse_family(struct nfnl_ct *ct, char *arg) { int family; if ((family = nl_str2af(arg)) == AF_UNSPEC) nl_cli_fatal(EINVAL, "Unable to nl_cli_ct_parse family \"%s\": %s", arg, nl_geterror(NLE_INVAL)); nfnl_ct_set_family(ct, family); }
static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, int attr, struct nl_addr ** ct_addr) { if (ct->ce_mask & CT_ATTR_FAMILY) { if (addr->a_family != ct->ct_family) return -NLE_AF_MISMATCH; } else nfnl_ct_set_family(ct, addr->a_family); if (*ct_addr) nl_addr_put(*ct_addr); nl_addr_get(addr); *ct_addr = addr; ct->ce_mask |= attr; return 0; }
int main(int argc, char *argv[]) { struct nl_sock *sock; struct nfnl_ct *ct; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, nlflags = NLM_F_CREATE; ct = nl_cli_ct_alloc(); for (;;) { int c, optidx = 0; enum { ARG_ORIG_SRC = 257, ARG_ORIG_SPORT = 258, ARG_ORIG_DST, ARG_ORIG_DPORT, ARG_REPLY_SRC, ARG_REPLY_SPORT, ARG_REPLY_DST, ARG_REPLY_DPORT, ARG_MARK, ARG_TIMEOUT, ARG_STATUS, ARG_ZONE, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "proto", 1, 0, 'p' }, { "orig-src", 1, 0, ARG_ORIG_SRC }, { "orig-sport", 1, 0, ARG_ORIG_SPORT }, { "orig-dst", 1, 0, ARG_ORIG_DST }, { "orig-dport", 1, 0, ARG_ORIG_DPORT }, { "reply-src", 1, 0, ARG_REPLY_SRC }, { "reply-sport", 1, 0, ARG_REPLY_SPORT }, { "reply-dst", 1, 0, ARG_REPLY_DST }, { "reply-dport", 1, 0, ARG_REPLY_DPORT }, { "family", 1, 0, 'F' }, { "mark", 1, 0, ARG_MARK }, { "timeout", 1, 0, ARG_TIMEOUT }, { "status", 1, 0, ARG_STATUS }, { "zone", 1, 0, ARG_ZONE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46q:hv:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case 'q': quiet = 1; break; case '4': nfnl_ct_set_family(ct, AF_INET); break; case '6': nfnl_ct_set_family(ct, AF_INET6); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'p': nl_cli_ct_parse_protocol(ct, optarg); break; case ARG_ORIG_SRC: nl_cli_ct_parse_src(ct, 0, optarg); break; case ARG_ORIG_SPORT: nl_cli_ct_parse_src_port(ct, 0, optarg); break; case ARG_ORIG_DST: nl_cli_ct_parse_dst(ct, 0, optarg); break; case ARG_ORIG_DPORT: nl_cli_ct_parse_dst_port(ct, 0, optarg); break; case ARG_REPLY_SRC: nl_cli_ct_parse_src(ct, 1, optarg); break; case ARG_REPLY_SPORT: nl_cli_ct_parse_src_port(ct, 1, optarg); break; case ARG_REPLY_DST: nl_cli_ct_parse_dst(ct, 1, optarg); break; case ARG_REPLY_DPORT: nl_cli_ct_parse_dst_port(ct, 1, optarg); break; case 'F': nl_cli_ct_parse_family(ct, optarg); break; case ARG_MARK: nl_cli_ct_parse_mark(ct, optarg); break; case ARG_TIMEOUT: nl_cli_ct_parse_timeout(ct, optarg); break; case ARG_STATUS: nl_cli_ct_parse_status(ct, optarg); break; case ARG_ZONE: nl_cli_ct_parse_zone(ct, optarg); break; } } if (!quiet) { printf("Adding "); nl_object_dump(OBJ_CAST(ct), ¶ms); } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); if ((err = nfnl_ct_add(sock, ct, nlflags)) < 0) nl_cli_fatal(err, "Unable to add conntrack: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(ct), ¶ms); } return 0; }
int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) { struct nfnl_ct *ct; struct nlattr *tb[CTA_MAX+1]; int err; ct = nfnl_ct_alloc(); if (!ct) return -NLE_NOMEM; ct->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX, ct_policy); if (err < 0) goto errout; nfnl_ct_set_family(ct, nfnlmsg_family(nlh)); if (tb[CTA_TUPLE_ORIG]) { err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]); if (err < 0) goto errout; } if (tb[CTA_TUPLE_REPLY]) { err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]); if (err < 0) goto errout; } if (tb[CTA_PROTOINFO]) { err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]); if (err < 0) goto errout; } if (tb[CTA_STATUS]) nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS]))); if (tb[CTA_TIMEOUT]) nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT]))); if (tb[CTA_MARK]) nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK]))); if (tb[CTA_USE]) nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE]))); if (tb[CTA_ID]) nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID]))); if (tb[CTA_ZONE]) nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE]))); if (tb[CTA_COUNTERS_ORIG]) { err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]); if (err < 0) goto errout; } if (tb[CTA_COUNTERS_REPLY]) { err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]); if (err < 0) goto errout; } if (tb[CTA_TIMESTAMP]) { err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]); if (err < 0) goto errout; } *result = ct; return 0; errout: nfnl_ct_put(ct); return err; }