static int dccp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_dccp_info *einfo = (struct xt_dccp_info *)(*match)->data; switch (c) { case '1': if (*flags & XT_DCCP_SRC_PORTS) xtables_error(PARAMETER_PROBLEM, "Only one `--source-port' allowed"); einfo->flags |= XT_DCCP_SRC_PORTS; xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_dccp_ports(optarg, einfo->spts); if (invert) einfo->invflags |= XT_DCCP_SRC_PORTS; *flags |= XT_DCCP_SRC_PORTS; break; case '2': if (*flags & XT_DCCP_DEST_PORTS) xtables_error(PARAMETER_PROBLEM, "Only one `--destination-port' allowed"); einfo->flags |= XT_DCCP_DEST_PORTS; xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_dccp_ports(optarg, einfo->dpts); if (invert) einfo->invflags |= XT_DCCP_DEST_PORTS; *flags |= XT_DCCP_DEST_PORTS; break; case '3': if (*flags & XT_DCCP_TYPE) xtables_error(PARAMETER_PROBLEM, "Only one `--dccp-types' allowed"); einfo->flags |= XT_DCCP_TYPE; xtables_check_inverse(optarg, &invert, &optind, 0, argv); einfo->typemask = parse_dccp_types(optarg); if (invert) einfo->invflags |= XT_DCCP_TYPE; *flags |= XT_DCCP_TYPE; break; case '4': if (*flags & XT_DCCP_OPTION) xtables_error(PARAMETER_PROBLEM, "Only one `--dccp-option' allowed"); einfo->flags |= XT_DCCP_OPTION; xtables_check_inverse(optarg, &invert, &optind, 0, argv); einfo->option = parse_dccp_option(optarg); if (invert) einfo->invflags |= XT_DCCP_OPTION; *flags |= XT_DCCP_OPTION; break; default: return 0; } return 1; }
static int limit_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data; unsigned int num; switch(c) { case '%': if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break; if (!parse_rate(optarg, &r->avg)) xtables_error(PARAMETER_PROBLEM, "bad rate `%s'", optarg); break; case '$': if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break; if (!xtables_strtoui(optarg, NULL, &num, 0, 10000)) xtables_error(PARAMETER_PROBLEM, "bad --limit-burst `%s'", optarg); r->burst = num; break; default: return 0; } if (invert) xtables_error(PARAMETER_PROBLEM, "limit does not support invert"); return 1; }
static int dscp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_dscp_info *dinfo = (struct xt_dscp_info *)(*match)->data; switch (c) { case 'F': if (*flags) xtables_error(PARAMETER_PROBLEM, "DSCP match: Only use --dscp ONCE!"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_dscp(optarg, dinfo); if (invert) dinfo->invert = 1; *flags = 1; break; case 'G': if (*flags) xtables_error(PARAMETER_PROBLEM, "DSCP match: Only use --dscp-class ONCE!"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_class(optarg, dinfo); if (invert) dinfo->invert = 1; *flags = 1; break; } return 1; }
static int addrtype_parse_v0(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_addrtype_info *info = (struct ipt_addrtype_info *) (*match)->data; switch (c) { case '1': if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify src-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0); parse_types(argv[optind-1], &info->source); if (invert) info->invert_source = 1; *flags |= IPT_ADDRTYPE_OPT_SRCTYPE; break; case '2': if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify dst-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0); parse_types(argv[optind-1], &info->dest); if (invert) info->invert_dest = 1; *flags |= IPT_ADDRTYPE_OPT_DSTTYPE; break; default: return 0; } return 1; }
static int udp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_udp *udpinfo = (struct xt_udp *)(*match)->data; switch (c) { case '1': if (*flags & UDP_SRC_PORTS) xtables_error(PARAMETER_PROBLEM, "Only one `--source-port' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_udp_ports(optarg, udpinfo->spts); if (invert) udpinfo->invflags |= XT_UDP_INV_SRCPT; *flags |= UDP_SRC_PORTS; break; case '2': if (*flags & UDP_DST_PORTS) xtables_error(PARAMETER_PROBLEM, "Only one `--destination-port' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_udp_ports(optarg, udpinfo->dpts); if (invert) udpinfo->invflags |= XT_UDP_INV_DSTPT; *flags |= UDP_DST_PORTS; break; default: return 0; } return 1; }
static int hbh_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ip6t_opts *optinfo = (struct ip6t_opts *)(*match)->data; switch (c) { case '1': if (*flags & IP6T_OPTS_LEN) xtables_error(PARAMETER_PROBLEM, "Only one `--hbh-len' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); optinfo->hdrlen = parse_opts_num(optarg, "length"); if (invert) optinfo->invflags |= IP6T_OPTS_INV_LEN; optinfo->flags |= IP6T_OPTS_LEN; *flags |= IP6T_OPTS_LEN; break; case '2': if (*flags & IP6T_OPTS_OPTS) xtables_error(PARAMETER_PROBLEM, "Only one `--hbh-opts' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, " '!' not allowed with `--hbh-opts'"); optinfo->optsnr = parse_options(optarg, optinfo->opts); optinfo->flags |= IP6T_OPTS_OPTS; *flags |= IP6T_OPTS_OPTS; break; } return 1; }
static int ecn_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { unsigned int result; struct ipt_ecn_info *einfo = (struct ipt_ecn_info *)(*match)->data; switch (c) { case 'F': if (*flags & IPT_ECN_OP_MATCH_CWR) xtables_error(PARAMETER_PROBLEM, "ECN match: can only use parameter ONCE!"); xtables_check_inverse(optarg, &invert, &optind, 0); einfo->operation |= IPT_ECN_OP_MATCH_CWR; if (invert) einfo->invert |= IPT_ECN_OP_MATCH_CWR; *flags |= IPT_ECN_OP_MATCH_CWR; break; case 'G': if (*flags & IPT_ECN_OP_MATCH_ECE) xtables_error(PARAMETER_PROBLEM, "ECN match: can only use parameter ONCE!"); xtables_check_inverse(optarg, &invert, &optind, 0); einfo->operation |= IPT_ECN_OP_MATCH_ECE; if (invert) einfo->invert |= IPT_ECN_OP_MATCH_ECE; *flags |= IPT_ECN_OP_MATCH_ECE; break; case 'H': if (*flags & IPT_ECN_OP_MATCH_IP) xtables_error(PARAMETER_PROBLEM, "ECN match: can only use parameter ONCE!"); xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) einfo->invert |= IPT_ECN_OP_MATCH_IP; *flags |= IPT_ECN_OP_MATCH_IP; einfo->operation |= IPT_ECN_OP_MATCH_IP; if (!xtables_strtoui(optarg, NULL, &result, 0, 3)) xtables_error(PARAMETER_PROBLEM, "ECN match: Value out of range"); einfo->ip_ect = result; break; default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int __multiport_parse(int c, char **argv, int invert, unsigned int *flags, struct xt_entry_match **match, u_int16_t pnum, u_int8_t invflags) { const char *proto; struct xt_multiport *multiinfo = (struct xt_multiport *)(*match)->data; switch (c) { case '1': xtables_check_inverse(optarg, &invert, &optind, 0, argv); proto = check_proto(pnum, invflags); multiinfo->count = parse_multi_ports(optarg, multiinfo->ports, proto); multiinfo->flags = XT_MULTIPORT_SOURCE; break; case '2': xtables_check_inverse(optarg, &invert, &optind, 0, argv); proto = check_proto(pnum, invflags); multiinfo->count = parse_multi_ports(optarg, multiinfo->ports, proto); multiinfo->flags = XT_MULTIPORT_DESTINATION; break; case '3': xtables_check_inverse(optarg, &invert, &optind, 0, argv); proto = check_proto(pnum, invflags); multiinfo->count = parse_multi_ports(optarg, multiinfo->ports, proto); multiinfo->flags = XT_MULTIPORT_EITHER; break; default: return 0; } if (invert) xtables_error(PARAMETER_PROBLEM, "multiport does not support invert"); if (*flags) xtables_error(PARAMETER_PROBLEM, "multiport can only have one option"); *flags = 1; return 1; }
static int addrtype_parse_v1(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_addrtype_info_v1 *info = (struct ipt_addrtype_info_v1 *) (*match)->data; switch (c) { case '1': if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify src-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0); parse_types(argv[optind-1], &info->source); if (invert) info->flags |= IPT_ADDRTYPE_INVERT_SOURCE; *flags |= IPT_ADDRTYPE_OPT_SRCTYPE; break; case '2': if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify dst-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0); parse_types(argv[optind-1], &info->dest); if (invert) info->flags |= IPT_ADDRTYPE_INVERT_DEST; *flags |= IPT_ADDRTYPE_OPT_DSTTYPE; break; case '3': if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify limit-iface-in twice"); info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN; *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN; break; case '4': if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify limit-iface-out twice"); info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT; *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT; break; default: return 0; } return 1; }
static int mark_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_mark_info *markinfo = (struct xt_mark_info *)(*match)->data; switch (c) { char *end; case '1': xtables_check_inverse(optarg, &invert, &optind, 0); markinfo->mark = strtoul(optarg, &end, 0); if (*end == '/') { markinfo->mask = strtoul(end+1, &end, 0); } else markinfo->mask = 0xffffffff; if (*end != '\0' || end == optarg) xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); if (invert) markinfo->invert = 1; *flags = 1; break; default: return 0; } return 1; }
static void parse_target(char **argv, int invert, unsigned int *flags, struct ipt_set_info *info, const char *what) { if (info->flags[0]) xtables_error(PARAMETER_PROBLEM, "--%s can be specified only once", what); if (xtables_check_inverse(optarg, &invert, NULL, 0)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s", what); if (!argv[optind] || argv[optind][0] == '-' || argv[optind][0] == '!') xtables_error(PARAMETER_PROBLEM, "--%s requires two args.", what); if (strlen(argv[optind-1]) > IP_SET_MAXNAMELEN - 1) xtables_error(PARAMETER_PROBLEM, "setname `%s' too long, max %d characters.", argv[optind-1], IP_SET_MAXNAMELEN - 1); get_set_byname(argv[optind - 1], info); parse_bindings(argv[optind], info); optind++; *flags = 1; }
static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; static const unsigned int limit = ARRAY_SIZE(reject_table); unsigned int i; switch(c) { case '1': if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --reject-with"); for (i = 0; i < limit; i++) { if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { reject->with = reject_table[i].with; return 1; } } /* This due to be dropped late in 2.4 pre-release cycle --RR */ if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) fprintf(stderr, "--reject-with echo-reply no longer" " supported\n"); xtables_error(PARAMETER_PROBLEM, "unknown reject type \"%s\"", optarg); default: /* Fall through */ break; } return 0; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char ** argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match ** match)//lint !e830 { if(NULL == (*match)) { xtables_error(OTHER_PROBLEM,"*match is NULL"); } URL_STRING_ST *dnsinfo = (URL_STRING_ST *)((*match)->data); //lint !e826 switch (c) { case '1': if (*flags) { xtables_error(PARAMETER_PROBLEM,"Only one `--str' allowed"); } xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_dns_str(argv[optind-1], (char*)(&dnsinfo->acURL), URL_STRING_LEN); if (invert) { dnsinfo->u16Inv = 1; } *flags = 1; break; default: return 0; } return 1; }//lint !e818
static int ttl_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data; unsigned int value; xtables_check_inverse(optarg, &invert, &optind, 0); switch (c) { case '2': if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, "ttl: Expected value between 0 and 255"); if (invert) info->mode = IPT_TTL_NE; else info->mode = IPT_TTL_EQ; /* is 0 allowed? */ info->ttl = value; break; case '3': if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, "ttl: Expected value between 0 and 255"); if (invert) xtables_error(PARAMETER_PROBLEM, "ttl: unexpected `!'"); info->mode = IPT_TTL_LT; info->ttl = value; break; case '4': if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, "ttl: Expected value between 0 and 255"); if (invert) xtables_error(PARAMETER_PROBLEM, "ttl: unexpected `!'"); info->mode = IPT_TTL_GT; info->ttl = value; break; default: return 0; } if (*flags) xtables_error(PARAMETER_PROBLEM, "Can't specify TTL option twice"); *flags = 1; return 1; }
static int TTL_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data; unsigned int value; if (*flags & IPT_TTL_USED) { xtables_error(PARAMETER_PROBLEM, "Can't specify TTL option twice"); } if (!optarg) xtables_error(PARAMETER_PROBLEM, "TTL: You must specify a value"); if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "TTL: unexpected `!'"); if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, "TTL: Expected value between 0 and 255"); switch (c) { case '1': info->mode = IPT_TTL_SET; break; case '2': if (value == 0) { xtables_error(PARAMETER_PROBLEM, "TTL: decreasing by 0?"); } info->mode = IPT_TTL_DEC; break; case '3': if (value == 0) { xtables_error(PARAMETER_PROBLEM, "TTL: increasing by 0?"); } info->mode = IPT_TTL_INC; break; default: return 0; } info->ttl = value; *flags |= IPT_TTL_USED; return 1; }
static int iprange_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_iprange_info *info = (struct ipt_iprange_info *)(*match)->data; union nf_inet_addr range[2]; switch (c) { case '1': if (*flags & IPRANGE_SRC) xtables_error(PARAMETER_PROBLEM, "iprange match: Only use --src-range ONCE!"); *flags |= IPRANGE_SRC; info->flags |= IPRANGE_SRC; xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) info->flags |= IPRANGE_SRC_INV; iprange_parse_range(optarg, range, NFPROTO_IPV4, "--src-range"); info->src.min_ip = range[0].ip; info->src.max_ip = range[1].ip; break; case '2': if (*flags & IPRANGE_DST) xtables_error(PARAMETER_PROBLEM, "iprange match: Only use --dst-range ONCE!"); *flags |= IPRANGE_DST; info->flags |= IPRANGE_DST; xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) info->flags |= IPRANGE_DST_INV; iprange_parse_range(optarg, range, NFPROTO_IPV4, "--dst-range"); info->dst.min_ip = range[0].ip; info->dst.max_ip = range[1].ip; break; default: return 0; } return 1; }
static int hl_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data; u_int8_t value; xtables_check_inverse(optarg, &invert, &optind, 0, argv); value = atoi(optarg); if (*flags) xtables_error(PARAMETER_PROBLEM, "Can't specify HL option twice"); if (!optarg) xtables_error(PARAMETER_PROBLEM, "hl: You must specify a value"); switch (c) { case '2': if (invert) info->mode = IP6T_HL_NE; else info->mode = IP6T_HL_EQ; /* is 0 allowed? */ info->hop_limit = value; *flags = 1; break; case '3': if (invert) xtables_error(PARAMETER_PROBLEM, "hl: unexpected `!'"); info->mode = IP6T_HL_LT; info->hop_limit = value; *flags = 1; break; case '4': if (invert) xtables_error(PARAMETER_PROBLEM, "hl: unexpected `!'"); info->mode = IP6T_HL_GT; info->hop_limit = value; *flags = 1; break; default: return 0; } return 1; }
static int iprange_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_iprange_info *info = (struct ipt_iprange_info *)(*match)->data; switch (c) { case '1': if (*flags & IPRANGE_SRC) xtables_error(PARAMETER_PROBLEM, "iprange match: Only use --src-range ONCE!"); *flags |= IPRANGE_SRC; info->flags |= IPRANGE_SRC; xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) info->flags |= IPRANGE_SRC_INV; parse_iprange(optarg, &info->src); break; case '2': if (*flags & IPRANGE_DST) xtables_error(PARAMETER_PROBLEM, "iprange match: Only use --dst-range ONCE!"); *flags |= IPRANGE_DST; info->flags |= IPRANGE_DST; xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) info->flags |= IPRANGE_DST_INV; parse_iprange(optarg, &info->dst); break; default: return 0; } return 1; }
static int mac_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data; switch (c) { case '1': if (*flags & MAC_SRC) xtables_error(PARAMETER_PROBLEM, "mac match: Only use --mac-source ONCE!"); *flags |= MAC_SRC; macinfo->flags |= MAC_SRC; xtables_check_inverse(optarg, &invert, &optind, 0); if (invert) { macinfo->flags |= MAC_SRC_INV; } parse_mac(optarg, &macinfo->srcaddr); break; case '2': if (*flags & MAC_DST) xtables_error(PARAMETER_PROBLEM, "mac match: Only use --mac-destination ONCE!"); *flags |= MAC_DST; macinfo->flags |= MAC_DST; xtables_check_inverse(optarg, &invert, &optind, 0); if (invert){ macinfo->flags |= MAC_DST_INV; } parse_mac(optarg, &macinfo->dstaddr); break; default: return 0; } return 1; }
static int SNAT_parse(int c, char **argv, int invert, unsigned int *flags, const void *e, struct xt_entry_target **target) { const struct ipt_entry *entry = e; struct ipt_natinfo *info = (void *)*target; int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_SCTP || entry->ip.proto == IPPROTO_DCCP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; switch (c) { case '1': if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-source"); if (*flags & IPT_SNAT_OPT_SOURCE) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) xtables_error(PARAMETER_PROBLEM, "Multiple --to-source not supported"); } *target = parse_to(optarg, portok, info); /* WTF do we need this for?? */ if (*flags & IPT_SNAT_OPT_RANDOM) info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_SNAT_OPT_SOURCE; return 1; case '2': if (*flags & IPT_SNAT_OPT_SOURCE) { info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_SNAT_OPT_RANDOM; } else *flags |= IPT_SNAT_OPT_RANDOM; return 1; case '3': info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT; return 1; default: return 0; } }
static int ah_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ip6t_ah *ahinfo = (struct ip6t_ah *)(*match)->data; switch (c) { case '1': if (*flags & IP6T_AH_SPI) xtables_error(PARAMETER_PROBLEM, "Only one `--ahspi' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_ah_spis(optarg, ahinfo->spis); if (invert) ahinfo->invflags |= IP6T_AH_INV_SPI; *flags |= IP6T_AH_SPI; break; case '2': if (*flags & IP6T_AH_LEN) xtables_error(PARAMETER_PROBLEM, "Only one `--ahlen' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); ahinfo->hdrlen = parse_ah_spi(optarg, "length"); if (invert) ahinfo->invflags |= IP6T_AH_INV_LEN; *flags |= IP6T_AH_LEN; break; case '3': if (*flags & IP6T_AH_RES) xtables_error(PARAMETER_PROBLEM, "Only one `--ahres' allowed"); ahinfo->hdrres = 1; *flags |= IP6T_AH_RES; break; default: return 0; } return 1; }
static int connbytes_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)(*match)->data; unsigned long i; switch (c) { case '1': if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) optind++; parse_range(optarg, sinfo); if (invert) { i = sinfo->count.from; sinfo->count.from = sinfo->count.to; sinfo->count.to = i; } *flags |= 1; break; case '2': if (!strcmp(optarg, "original")) sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL; else if (!strcmp(optarg, "reply")) sinfo->direction = XT_CONNBYTES_DIR_REPLY; else if (!strcmp(optarg, "both")) sinfo->direction = XT_CONNBYTES_DIR_BOTH; else xtables_error(PARAMETER_PROBLEM, "Unknown --connbytes-dir `%s'", optarg); *flags |= 2; break; case '3': if (!strcmp(optarg, "packets")) sinfo->what = XT_CONNBYTES_PKTS; else if (!strcmp(optarg, "bytes")) sinfo->what = XT_CONNBYTES_BYTES; else if (!strcmp(optarg, "avgpkt")) sinfo->what = XT_CONNBYTES_AVGPKT; else xtables_error(PARAMETER_PROBLEM, "Unknown --connbytes-mode `%s'", optarg); *flags |= 4; break; default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int layer7_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_layer7_info *layer7info = (struct xt_layer7_info *)(*match)->data; switch (c) { case '1': xtables_check_inverse(optarg, &invert, &optind, 0); parse_layer7_protocol(argv[optind-1], layer7info); if (invert) layer7info->invert = 1; *flags = 1; break; case '2': /* not going to use this, but maybe we need to strip a ! anyway (?) */ xtables_check_inverse(optarg, &invert, &optind, 0); if(strlen(argv[optind-1]) >= MAX_FN_LEN) xtables_error(PARAMETER_PROBLEM, "directory name too long\n"); strncpy(l7dir, argv[optind-1], MAX_FN_LEN); *flags = 1; break; case '3': layer7info->pkt = 1; break; default: return 0; } return 1; }
static int set_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_set_info_match *myinfo = (struct ipt_set_info_match *) (*match)->data; struct ipt_set_info *info = &myinfo->match_set; switch (c) { case '2': #if 0 fprintf(stderr, "--set option deprecated, please use --match-set\n"); #endif case '1': /* --match-set <set> <flag>[,<flag> */ if (info->flags[0]) xtables_error(PARAMETER_PROBLEM, "--match-set can be specified only once"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) info->flags[0] |= IPSET_MATCH_INV; if (!argv[optind] || argv[optind][0] == '-' || argv[optind][0] == '!') xtables_error(PARAMETER_PROBLEM, "--match-set requires two args."); if (strlen(optarg) > IP_SET_MAXNAMELEN - 1) xtables_error(PARAMETER_PROBLEM, "setname `%s' too long, max %d characters.", optarg, IP_SET_MAXNAMELEN - 1); get_set_byname(optarg, info); parse_bindings(argv[optind], info); DEBUGP("parse: set index %u\n", info->index); optind++; *flags = 1; break; default: return 0; } return 1; }
static int connlimit_parse(int c, char **argv, int invert, unsigned int *flags, struct xt_connlimit_info *info, unsigned int family) { char *err; int i; switch (c) { case 'A': if (*flags & 0x1) xtables_error(PARAMETER_PROBLEM, "--connlimit-above may be given only once"); *flags |= 0x1; xtables_check_inverse(optarg, &invert, &optind, 0, argv); info->limit = strtoul(optarg, NULL, 0); info->inverse = invert; break; case 'M': if (*flags & 0x2) xtables_error(PARAMETER_PROBLEM, "--connlimit-mask may be given only once"); *flags |= 0x2; i = strtoul(optarg, &err, 0); if (family == NFPROTO_IPV6) { if (i > 128 || *err != '\0') xtables_error(PARAMETER_PROBLEM, "--connlimit-mask must be between " "0 and 128"); prefix_to_netmask(info->v6_mask, i); } else { if (i > 32 || *err != '\0') xtables_error(PARAMETER_PROBLEM, "--connlimit-mask must be between " "0 and 32"); if (i == 0) info->v4_mask = 0; else info->v4_mask = htonl(0xFFFFFFFF << (32 - i)); } break; default: return 0; } return 1; }
static int SAME_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_same_info *mr = (struct ipt_same_info *)(*target)->data; unsigned int count; switch (c) { case '1': if (mr->rangesize == IPT_SAME_MAX_RANGE) xtables_error(PARAMETER_PROBLEM, "Too many ranges specified, maximum " "is %i ranges.\n", IPT_SAME_MAX_RANGE); if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to"); parse_to(optarg, &mr->range[mr->rangesize]); /* WTF do we need this for? */ if (*flags & IPT_SAME_OPT_RANDOM) mr->range[mr->rangesize].flags |= IP_NAT_RANGE_PROTO_RANDOM; mr->rangesize++; *flags |= IPT_SAME_OPT_TO; break; case '2': if (*flags & IPT_SAME_OPT_NODST) xtables_error(PARAMETER_PROBLEM, "Can't specify --nodst twice"); mr->info |= IPT_SAME_NODST; *flags |= IPT_SAME_OPT_NODST; break; case '3': *flags |= IPT_SAME_OPT_RANDOM; for (count=0; count < mr->rangesize; count++) mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM; break; } return 1; }
static int REDIRECT_parse(int c, char **argv, int invert, unsigned int *flags, const void *e, struct xt_entry_target **target) { const struct ipt_entry *entry = e; struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)(*target)->data; int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_SCTP || entry->ip.proto == IPPROTO_DCCP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; switch (c) { case '1': if (!portok) xtables_error(PARAMETER_PROBLEM, "Need TCP, UDP, SCTP or DCCP with port specification"); if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-ports"); parse_ports(optarg, mr); if (*flags & IPT_REDIRECT_OPT_RANDOM) mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_REDIRECT_OPT_DEST; return 1; case '2': if (*flags & IPT_REDIRECT_OPT_DEST) { mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_REDIRECT_OPT_RANDOM; } else *flags |= IPT_REDIRECT_OPT_RANDOM; return 1; default: return 0; } }
static int cpu_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_cpu_info *cpuinfo = (struct xt_cpu_info *)(*match)->data; switch (c) { case '1': xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_cpu(optarg, cpuinfo); if (invert) cpuinfo->invert = 1; *flags = 1; break; } return 1; }
static int mh_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ip6t_mh *mhinfo = (struct ip6t_mh *)(*match)->data; switch (c) { case '1': if (*flags & MH_TYPES) xtables_error(PARAMETER_PROBLEM, "Only one `--mh-type' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_mh_types(optarg, mhinfo->types); if (invert) mhinfo->invflags |= IP6T_MH_INV_TYPE; *flags |= MH_TYPES; break; } return 1; }
static int ah_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_ah *ahinfo = (struct ipt_ah *)(*match)->data; switch (c) { case '1': if (*flags & AH_SPI) xtables_error(PARAMETER_PROBLEM, "Only one `--ahspi' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_ah_spis(optarg, ahinfo->spis); if (invert) ahinfo->invflags |= IPT_AH_INV_SPI; *flags |= AH_SPI; break; } return 1; }