static void ipvs_mt_parse_addr_and_mask(const char *arg, union nf_inet_addr *address, union nf_inet_addr *mask, unsigned int family) { struct in_addr *addr = NULL; struct in6_addr *addr6 = NULL; unsigned int naddrs = 0; if (family == NFPROTO_IPV4) { xtables_ipparse_any(arg, &addr, &mask->in, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&address->in, addr, sizeof(*addr)); } else if (family == NFPROTO_IPV6) { xtables_ip6parse_any(arg, &addr6, &mask->in6, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&address->in6, addr6, sizeof(*addr6)); } else { /* Hu? */ assert(false); } }
static int ipaddr_mt4_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_ipaddr_mtinfo *info = (void *)(*match)->data; struct in_addr *addrs, mask; unsigned int naddrs; switch (c) { case '1': /* --ipsrc */ if (*flags & XT_IPADDR_SRC) xtables_error(PARAMETER_PROBLEM, "xt_ipaddr: " "Only use \"--ipsrc\" once!"); *flags |= XT_IPADDR_SRC; info->flags |= XT_IPADDR_SRC; if (invert) info->flags |= XT_IPADDR_SRC_INV; xtables_ipparse_any(optarg, &addrs, &mask, &naddrs); if (naddrs != 1) xtables_error(PARAMETER_PROBLEM, "%s does not resolves to exactly " "one address", optarg); /* Copy the single address */ memcpy(&info->src.in, addrs, sizeof(*addrs)); return true; case '2': /* --ipdst */ if (*flags & XT_IPADDR_DST) xtables_error(PARAMETER_PROBLEM, "xt_ipaddr: " "Only use \"--ipdst\" once!"); *flags |= XT_IPADDR_DST; info->flags |= XT_IPADDR_DST; if (invert) info->flags |= XT_IPADDR_DST_INV; // addrs = xtables_numeric_to_ipaddr(optarg, &info->dst.in); addrs = &info->dst.in; if (addrs == NULL) xtables_error(PARAMETER_PROBLEM, "Parse error at %s\n", optarg); memcpy(&info->dst.in, addrs, sizeof(*addrs)); return true; } return false; }
static PyObject * py_ipt_entry_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"source", "destination", "jump", "in_interface", "out_interface", NULL}; PyIPTEntryObject *self = NULL; char *source = NULL; char *destination = NULL; char *jump = NULL; char *in_interface = NULL; char *out_interface = NULL; unsigned int n_source_addresses = 0; unsigned int n_destination_addresses = 0; if (!PyArg_ParseTupleAndKeywords (args, kwds, "|zzzzz", kwlist, &source, &destination, &jump, &in_interface, &out_interface)) goto error; self = (PyIPTEntryObject *) type->tp_alloc (type, 0); if (self == NULL) goto error; self->source = NULL; self->destination = NULL; self->jump = NULL; self->in_interface = NULL; self->out_interface = NULL; self->matches = NULL; self->target = NULL; if (source == NULL) source = "0.0.0.0/0"; xtables_ipparse_any (source, &self->source, &self->entry.ip.smsk, &n_source_addresses); if (n_source_addresses == 0) { self->source = NULL; PyErr_SetString (PyIPTException, "invalid source address."); goto error; } else if (n_source_addresses > 1) { PyErr_SetString (PyIPTException, "multiple source addresses are not allowed."); goto error; } if (destination == NULL) destination = "0.0.0.0/0"; xtables_ipparse_any (destination, &self->destination, &self->entry.ip.dmsk, &n_destination_addresses); if (n_destination_addresses != 1) { self->destination = NULL; PyErr_SetString (PyIPTException, "invalid destination address."); goto error; } else if (n_destination_addresses != 1) { PyErr_SetString (PyIPTException, "multiple destination addresses are not allowed."); goto error; } if (in_interface) { xtables_parse_interface(in_interface, self->entry.ip.iniface, self->entry.ip.iniface_mask); if (py_ipt_xt_get_error ()) { PyErr_SetString (PyIPTException, py_ipt_xt_get_error_message ()); goto error; } } if (out_interface) { xtables_parse_interface(out_interface, self->entry.ip.outiface, self->entry.ip.outiface_mask); if (py_ipt_xt_get_error ()) { PyErr_SetString (PyIPTException, py_ipt_xt_get_error_message ()); goto error; } } if (jump) self->jump = strdup (jump); if (in_interface) self->in_interface = strdup (in_interface); if (out_interface) self->out_interface = strdup (out_interface); self->matches = PyList_New (0); return (PyObject *) self; error: Py_XDECREF (self); return NULL; }
static int policy_parse(int c, int invert, unsigned int *flags, struct xt_policy_info *info, uint8_t family) { struct xt_policy_elem *e = &info->pol[info->len]; struct in_addr *addr = NULL, mask; struct in6_addr *addr6 = NULL, mask6; unsigned int naddr = 0, num; int mode; xtables_check_inverse(optarg, &invert, &optind, 0); switch (c) { case '1': if (info->flags & (XT_POLICY_MATCH_IN | XT_POLICY_MATCH_OUT)) xtables_error(PARAMETER_PROBLEM, "policy match: double --dir option"); if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --dir option"); info->flags |= parse_direction(optarg); break; case '2': if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --policy option"); info->flags |= parse_policy(optarg); break; case '3': if (info->flags & XT_POLICY_MATCH_STRICT) xtables_error(PARAMETER_PROBLEM, "policy match: double --strict option"); if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --strict option"); info->flags |= XT_POLICY_MATCH_STRICT; break; case '4': if (e->match.reqid) xtables_error(PARAMETER_PROBLEM, "policy match: double --reqid option"); e->match.reqid = 1; e->invert.reqid = invert; if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg); e->reqid = num; break; case '5': if (e->match.spi) xtables_error(PARAMETER_PROBLEM, "policy match: double --spi option"); e->match.spi = 1; e->invert.spi = invert; if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg); e->spi = num; break; case '6': if (e->match.saddr) xtables_error(PARAMETER_PROBLEM, "policy match: double --tunnel-src option"); if (family == NFPROTO_IPV6) xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr); else xtables_ipparse_any(optarg, &addr, &mask, &naddr); if (naddr > 1) xtables_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.saddr = 1; e->invert.saddr = invert; if (family == NFPROTO_IPV6) { memcpy(&e->saddr.a6, addr6, sizeof(*addr6)); memcpy(&e->smask.a6, &mask6, sizeof(mask6)); } else { e->saddr.a4 = addr[0]; e->smask.a4 = mask; } break; case '7': if (e->match.daddr) xtables_error(PARAMETER_PROBLEM, "policy match: double --tunnel-dst option"); if (family == NFPROTO_IPV6) xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr); else xtables_ipparse_any(optarg, &addr, &mask, &naddr); if (naddr > 1) xtables_error(PARAMETER_PROBLEM, "policy match: name resolves to multiple IPs"); e->match.daddr = 1; e->invert.daddr = invert; if (family == NFPROTO_IPV6) { memcpy(&e->daddr.a6, addr6, sizeof(*addr6)); memcpy(&e->dmask.a6, &mask6, sizeof(mask6)); } else { e->daddr.a4 = addr[0]; e->dmask.a4 = mask; } break; case '8': if (e->match.proto) xtables_error(PARAMETER_PROBLEM, "policy match: double --proto option"); e->proto = xtables_parse_protocol(optarg); if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP && e->proto != IPPROTO_COMP) xtables_error(PARAMETER_PROBLEM, "policy match: protocol must ah/esp/ipcomp"); e->match.proto = 1; e->invert.proto = invert; break; case '9': if (e->match.mode) xtables_error(PARAMETER_PROBLEM, "policy match: double --mode option"); mode = parse_mode(optarg); e->match.mode = 1; e->invert.mode = invert; e->mode = mode; break; case 'a': if (invert) xtables_error(PARAMETER_PROBLEM, "policy match: can't invert --next option"); if (++info->len == XT_POLICY_MAX_ELEM) xtables_error(PARAMETER_PROBLEM, "policy match: maximum policy depth reached"); break; default: return 0; } return 1; }
static int conntrack_mt4_parse(int c, bool invert, unsigned int *flags, struct xt_conntrack_mtinfo2 *info) { struct in_addr *addr = NULL; unsigned int naddrs = 0; switch (c) { case '3': /* --ctorigsrc */ xtables_ipparse_any(optarg, &addr, &info->origsrc_mask.in, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&info->origsrc_addr.in, addr, sizeof(*addr)); info->match_flags |= XT_CONNTRACK_ORIGSRC; if (invert) info->invert_flags |= XT_CONNTRACK_ORIGSRC; break; case '4': /* --ctorigdst */ xtables_ipparse_any(optarg, &addr, &info->origdst_mask.in, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&info->origdst_addr.in, addr, sizeof(*addr)); info->match_flags |= XT_CONNTRACK_ORIGDST; if (invert) info->invert_flags |= XT_CONNTRACK_ORIGDST; break; case '5': /* --ctreplsrc */ xtables_ipparse_any(optarg, &addr, &info->replsrc_mask.in, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&info->replsrc_addr.in, addr, sizeof(*addr)); info->match_flags |= XT_CONNTRACK_REPLSRC; if (invert) info->invert_flags |= XT_CONNTRACK_REPLSRC; break; case '6': /* --ctrepldst */ xtables_ipparse_any(optarg, &addr, &info->repldst_mask.in, &naddrs); if (naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if (naddrs == 1) memcpy(&info->repldst_addr.in, addr, sizeof(*addr)); info->match_flags |= XT_CONNTRACK_REPLDST; if (invert) info->invert_flags |= XT_CONNTRACK_REPLDST; break; default: return conntrack_mt_parse(c, invert, flags, info); } *flags = info->match_flags; return true; }
static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_conntrack_info *sinfo = (void *)(*match)->data; char *protocol = NULL; unsigned int naddrs = 0; struct in_addr *addrs = NULL; switch (c) { case '1': xtables_check_inverse(optarg, &invert, &optind, 0); parse_states(argv[optind-1], sinfo); if (invert) { sinfo->invflags |= XT_CONNTRACK_STATE; } sinfo->flags |= XT_CONNTRACK_STATE; break; case '2': xtables_check_inverse(optarg, &invert, &optind, 0); if(invert) sinfo->invflags |= XT_CONNTRACK_PROTO; /* Canonicalize into lower case */ for (protocol = argv[optind-1]; *protocol; protocol++) *protocol = tolower(*protocol); protocol = argv[optind-1]; sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = xtables_parse_protocol(protocol); if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0 && (sinfo->invflags & XT_INV_PROTO)) xtables_error(PARAMETER_PROBLEM, "rule would never match protocol"); sinfo->flags |= XT_CONNTRACK_PROTO; break; case '3': xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) sinfo->invflags |= XT_CONNTRACK_ORIGSRC; xtables_ipparse_any(argv[optind-1], &addrs, &sinfo->sipmsk[IP_CT_DIR_ORIGINAL], &naddrs); if(naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if(naddrs == 1) { sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip = addrs[0].s_addr; } sinfo->flags |= XT_CONNTRACK_ORIGSRC; break; case '4': xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) sinfo->invflags |= XT_CONNTRACK_ORIGDST; xtables_ipparse_any(argv[optind-1], &addrs, &sinfo->dipmsk[IP_CT_DIR_ORIGINAL], &naddrs); if(naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if(naddrs == 1) { sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip = addrs[0].s_addr; } sinfo->flags |= XT_CONNTRACK_ORIGDST; break; case '5': xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) sinfo->invflags |= XT_CONNTRACK_REPLSRC; xtables_ipparse_any(argv[optind-1], &addrs, &sinfo->sipmsk[IP_CT_DIR_REPLY], &naddrs); if(naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if(naddrs == 1) { sinfo->tuple[IP_CT_DIR_REPLY].src.ip = addrs[0].s_addr; } sinfo->flags |= XT_CONNTRACK_REPLSRC; break; case '6': xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) sinfo->invflags |= XT_CONNTRACK_REPLDST; xtables_ipparse_any(argv[optind-1], &addrs, &sinfo->dipmsk[IP_CT_DIR_REPLY], &naddrs); if(naddrs > 1) xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); if(naddrs == 1) { sinfo->tuple[IP_CT_DIR_REPLY].dst.ip = addrs[0].s_addr; } sinfo->flags |= XT_CONNTRACK_REPLDST; break; case '7': xtables_check_inverse(optarg, &invert, &optind, 0); parse_statuses(argv[optind-1], sinfo); if (invert) { sinfo->invflags |= XT_CONNTRACK_STATUS; } sinfo->flags |= XT_CONNTRACK_STATUS; break; case '8': xtables_check_inverse(optarg, &invert, &optind, 0); parse_expires(argv[optind-1], sinfo); if (invert) { sinfo->invflags |= XT_CONNTRACK_EXPIRES; } sinfo->flags |= XT_CONNTRACK_EXPIRES; break; default: return 0; } *flags = sinfo->flags; return 1; }
int nat64_tg4_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_nat64_tginfo *info = (void *)(*target)->data; struct in_addr *addrs, mask; char out_dev[IFNAMSIZ]; unsigned char out_dev_mask[IFNAMSIZ]; unsigned int naddrs; switch (c) { case '1': /* --ipsrc */ if (*flags & XT_NAT64_IP_SRC) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "Only use \"--ipsrc\" once!"); *flags |= XT_NAT64_IP_SRC; info->flags |= XT_NAT64_IP_SRC; if (invert) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "I'm sorry, the invert flag isn't available yet"); xtables_ipparse_any(optarg, &addrs, &mask, &naddrs); if (naddrs != 1) xtables_error(PARAMETER_PROBLEM, "%s does not resolves to exactly " "one address", optarg); /* Copy the single address */ memcpy(&info->ipsrc.in, addrs, sizeof(*addrs)); return true; case '2': /* --ipdst */ if (*flags & XT_NAT64_IP_DST) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "Only use \"--ipdst\" once!"); *flags |= XT_NAT64_IP_DST; info->flags |= XT_NAT64_IP_DST; if (invert) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "I'm sorry, the invert flag isn't available yet"); xtables_ipparse_any(optarg, &addrs, &mask, &naddrs); if (naddrs != 1) xtables_error(PARAMETER_PROBLEM, "%s does not resolves to exactly " "one address", optarg); if (addrs == NULL) xtables_error(PARAMETER_PROBLEM, "Parse error at %s\n", optarg); memcpy(&info->ipdst.in, addrs, sizeof(*addrs)); return true; case '3': /* --oudev */ if (*flags & XT_NAT64_OUT_DEV) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "Only use \"--outdev\" once!"); *flags |= XT_NAT64_OUT_DEV; info->flags |= XT_NAT64_OUT_DEV; if (invert) xtables_error(PARAMETER_PROBLEM, "xt_nat64: " "I'm sorry, the invert flag isn't available yet"); xtables_parse_interface(optarg, out_dev, out_dev_mask); if (out_dev == NULL) xtables_error(PARAMETER_PROBLEM, "Parse error at %s\n", optarg); memcpy(&info->out_dev, out_dev, sizeof(char) * IFNAMSIZ); memcpy(&info->out_dev_mask, out_dev_mask, sizeof(unsigned char) * IFNAMSIZ); return true; } return false; }