/* Parses ports */ static void parse_ports(const char *arg, struct nf_nat_multi_range *mr) { char *end; unsigned int port, maxport; mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX)) xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); switch (*end) { case '\0': mr->range[0].min.tcp.port = mr->range[0].max.tcp.port = htons(port); return; case '-': if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX)) break; if (maxport < port) break; mr->range[0].min.tcp.port = htons(port); mr->range[0].max.tcp.port = htons(maxport); return; default: break; } xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); }
/* Parses ports */ static void parse_ports(const char *arg, struct nf_nat_range *range) { char *end = ""; unsigned int port, maxport; range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) && (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1) xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg); switch (*end) { case '\0': range->min_proto.tcp.port = range->max_proto.tcp.port = htons(port); return; case '-': if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) && (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1) break; if (maxport < port) break; range->min_proto.tcp.port = htons(port); range->max_proto.tcp.port = htons(maxport); return; default: break; } xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg); }
static int idletimer_tg_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct idletimer_tg_info *info = (struct idletimer_tg_info *)(*target)->data; switch (c) { case 't': xtables_param_act(XTF_ONLY_ONCE, "IDLETIMER", "--timeout", *flags & IDLETIMER_TG_OPT_TIMEOUT); info->timeout = atoi(optarg); *flags |= IDLETIMER_TG_OPT_TIMEOUT; break; case 'l': xtables_param_act(XTF_ONLY_ONCE, "IDLETIMER", "--label", *flags & IDLETIMER_TG_OPT_TIMEOUT); if (strlen(optarg) > MAX_IDLETIMER_LABEL_SIZE - 1) xtables_param_act(XTF_BAD_VALUE, "IDLETIMER", "--label", optarg); strcpy(info->label, optarg); *flags |= IDLETIMER_TG_OPT_LABEL; break; } return true; }
static void iprange_parse_spec(const char *from, const char *to, union nf_inet_addr *range, uint8_t family, const char *optname) { const char *spec[2] = {from, to}; struct in6_addr *ia6; struct in_addr *ia4; unsigned int i; memset(range, 0, sizeof(union nf_inet_addr) * 2); if (family == NFPROTO_IPV6) { for (i = 0; i < ARRAY_SIZE(spec); ++i) { ia6 = xtables_numeric_to_ip6addr(spec[i]); if (ia6 == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", optname, spec[i]); range[i].in6 = *ia6; } } else { for (i = 0; i < ARRAY_SIZE(spec); ++i) { ia4 = xtables_numeric_to_ipaddr(spec[i]); if (ia4 == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", optname, spec[i]); range[i].in = *ia4; } } }
static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_mark_mtinfo1 *info = (void *)(*match)->data; unsigned int mark, mask = UINT32_MAX; char *end; switch (c) { case '1': /* --mark */ xtables_param_act(XTF_ONLY_ONCE, "mark", "--mark", *flags & F_MARK); if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); if (*end == '/') if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); if (invert) info->invert = true; info->mark = mark; info->mask = mask; *flags |= F_MARK; return true; } return false; }
static int owner_mt_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_owner_match_info *info = (void *)(*match)->data; struct passwd *pwd; struct group *grp; unsigned int from, to; switch (c) { case 'u': xtables_param_act(XTF_ONLY_ONCE, "owner", "--uid-owner", *flags & FLAG_UID_OWNER); if ((pwd = getpwnam(optarg)) != NULL) from = to = pwd->pw_uid; else owner_parse_range(optarg, &from, &to, "--uid-owner"); if (invert) info->invert |= XT_OWNER_UID; info->match |= XT_OWNER_UID; info->uid_min = from; info->uid_max = to; *flags |= FLAG_UID_OWNER; return true; case 'g': xtables_param_act(XTF_ONLY_ONCE, "owner", "--gid-owner", *flags & FLAG_GID_OWNER); if ((grp = getgrnam(optarg)) != NULL) from = to = grp->gr_gid; else owner_parse_range(optarg, &from, &to, "--gid-owner"); if (invert) info->invert |= XT_OWNER_GID; info->match |= XT_OWNER_GID; info->gid_min = from; info->gid_max = to; *flags |= FLAG_GID_OWNER; return true; case 'k': xtables_param_act(XTF_ONLY_ONCE, "owner", "--socket-exists", *flags & FLAG_SOCKET_EXISTS); if (invert) info->invert |= XT_OWNER_SOCKET; info->match |= XT_OWNER_SOCKET; *flags |= FLAG_SOCKET_EXISTS; return true; } return false; }
static void parse_cpu(const char *s, struct xt_cpu_info *info) { unsigned int cpu; char *end; if (!xtables_strtoui(s, &end, &cpu, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "cpu", "--cpu", s); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "cpu", "--cpu", s); info->cpu = cpu; }
static void owner_parse_range(const char *s, unsigned int *from, unsigned int *to, const char *opt) { char *end; /* -1 is reversed, so the max is one less than that. */ if (!xtables_strtoui(s, &end, from, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); *to = *from; if (*end == '-' || *end == ':') if (!xtables_strtoui(end + 1, &end, to, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); }
static void parse_tproxy_mark(char *s, uint32_t *markp, uint32_t *maskp) { unsigned int value, mask = UINT32_MAX; char *end; if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); if (*end == '/') if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); *markp = value; *maskp = mask; }
static void parse_tproxy_mark(char *s, struct xt_tproxy_target_info *info) { unsigned int value, mask = UINT32_MAX; char *end; if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); if (*end == '/') if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); info->mark_mask = mask; info->mark_value = value; }
static void owner_mt_parse_v0(struct xt_option_call *cb) { struct ipt_owner_info *info = cb->data; struct passwd *pwd; struct group *grp; unsigned int id; xtables_option_parse(cb); switch (cb->entry->id) { case O_USER: if ((pwd = getpwnam(cb->arg)) != NULL) id = pwd->pw_uid; else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", cb->arg); if (cb->invert) info->invert |= IPT_OWNER_UID; info->match |= IPT_OWNER_UID; info->uid = id; break; case O_GROUP: if ((grp = getgrnam(cb->arg)) != NULL) id = grp->gr_gid; else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", cb->arg); if (cb->invert) info->invert |= IPT_OWNER_GID; info->match |= IPT_OWNER_GID; info->gid = id; break; case O_PROCESS: if (cb->invert) info->invert |= IPT_OWNER_PID; info->match |= IPT_OWNER_PID; break; case O_SESSION: if (cb->invert) info->invert |= IPT_OWNER_SID; info->match |= IPT_OWNER_SID; break; case O_COMM: if (cb->invert) info->invert |= IPT_OWNER_COMM; info->match |= IPT_OWNER_COMM; break; } }
static void parse_tproxy_lport(const char *s, uint16_t *portp) { unsigned int lport; if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX)) *portp = htons(lport); else xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s); }
static void parse_tproxy_laddr(const char *s, struct xt_tproxy_target_info *info) { struct in_addr *laddr; if ((laddr = xtables_numeric_to_ipaddr(s)) == NULL) xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s); info->laddr = laddr->s_addr; }
static void parse_tproxy_lport(const char *s, struct xt_tproxy_target_info *info) { unsigned int lport; if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX)) info->lport = htons(lport); else xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s); }
static int length_mt_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_length_mtinfo2 *info = (void *)(*match)->data; unsigned int from, to; char *end; switch (c) { case '3': /* --layer3 */ xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER); info->flags &= ~XT_LENGTH_LAYER_MASK; info->flags |= XT_LENGTH_LAYER3; *flags |= F_LAYER; return true; case '4': /* --layer4 */ xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER); info->flags &= ~XT_LENGTH_LAYER_MASK; info->flags |= XT_LENGTH_LAYER4; *flags |= F_LAYER; return true; case '5': /* --layer5 */ xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER); info->flags &= ~XT_LENGTH_LAYER_MASK; info->flags |= XT_LENGTH_LAYER5; *flags |= F_LAYER; return true; case '7': /* --layer7 */ xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER); info->flags &= ~XT_LENGTH_LAYER_MASK; info->flags |= XT_LENGTH_LAYER7; *flags |= F_LAYER; return true; case '=': /* --length */ xtables_param_act(XTF_ONLY_ONCE, "length", "--length", *flags & F_LENGTH); if (invert) info->flags |= XT_LENGTH_INVERT; if (!xtables_strtoui(optarg, &end, &from, 0, ~0U)) xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg); to = from; if (*end == ':') if (!xtables_strtoui(end + 1, &end, &to, 0, ~0U)) xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg); info->min = from; info->max = to; *flags |= F_LENGTH; return true; } return false; }
static void ipvs_mt_parse(struct xt_option_call *cb) { struct xt_ipvs_mtinfo *data = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_VPROTO: data->l4proto = cb->val.protocol; break; case O_VADDR: memcpy(&data->vaddr, &cb->val.haddr, sizeof(cb->val.haddr)); memcpy(&data->vmask, &cb->val.hmask, sizeof(cb->val.hmask)); break; case O_VDIR: if (strcasecmp(cb->arg, "ORIGINAL") == 0) { data->bitmask |= XT_IPVS_DIR; data->invert &= ~XT_IPVS_DIR; } else if (strcasecmp(cb->arg, "REPLY") == 0) { data->bitmask |= XT_IPVS_DIR; data->invert |= XT_IPVS_DIR; } else { xtables_param_act(XTF_BAD_VALUE, "ipvs", "--vdir", cb->arg); } break; case O_VMETHOD: if (strcasecmp(cb->arg, "GATE") == 0) data->fwd_method = IP_VS_CONN_F_DROUTE; else if (strcasecmp(cb->arg, "IPIP") == 0) data->fwd_method = IP_VS_CONN_F_TUNNEL; else if (strcasecmp(cb->arg, "MASQ") == 0) data->fwd_method = IP_VS_CONN_F_MASQ; else xtables_param_act(XTF_BAD_VALUE, "ipvs", "--vmethod", cb->arg); break; } data->bitmask |= 1 << cb->entry->id; if (cb->invert) data->invert |= 1 << cb->entry->id; }
static int quota_mt2_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_quota_mtinfo2 *info = (void *)(*match)->data; char *end; switch (c) { case 'g': xtables_param_act(XTF_ONLY_ONCE, "quota", "--grow", *flags & FL_GROW); xtables_param_act(XTF_NO_INVERT, "quota", "--grow", invert); info->flags |= XT_QUOTA_GROW; *flags |= FL_GROW; return true; case 'c': /* no-change */ xtables_param_act(XTF_ONLY_ONCE, "quota", "--no-change", *flags & FL_NO_CHANGE); xtables_param_act(XTF_NO_INVERT, "quota", "--no-change", invert); info->flags |= XT_QUOTA_NO_CHANGE; *flags |= FL_NO_CHANGE; return true; case 'n': /* zero termination done on behalf of the kernel module */ xtables_param_act(XTF_ONLY_ONCE, "quota", "--name", *flags & FL_NAME); xtables_param_act(XTF_NO_INVERT, "quota", "--name", invert); strncpy(info->name, optarg, sizeof(info->name)); *flags |= FL_NAME; return true; case 'p': xtables_param_act(XTF_ONLY_ONCE, "quota", "--packets", *flags & FL_PACKET); xtables_param_act(XTF_NO_INVERT, "quota", "--packets", invert); info->flags |= XT_QUOTA_PACKET; *flags |= FL_PACKET; return true; case 'q': xtables_param_act(XTF_ONLY_ONCE, "quota", "--quota", *flags & FL_QUOTA); if (invert) info->flags |= XT_QUOTA_INVERT; info->quota = strtoull(optarg, &end, 0); if (*end != '\0') xtables_error(PARAMETER_PROBLEM, "quota match: " "invalid value for --quota"); *flags |= FL_QUOTA; return true; } return false; }
static int tproxy_tg_parse1(int c, char **argv, int invert, unsigned int *flags, struct xt_tproxy_target_info_v1 *info, unsigned int nfproto) { switch (c) { case '1': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert); parse_tproxy_lport(optarg, &info->lport); *flags |= PARAM_ONPORT; return true; case '2': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert); parse_tproxy_laddr(optarg, (void *)&info->laddr, nfproto); *flags |= PARAM_ONIP; return true; case '3': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert); parse_tproxy_mark(optarg, &info->mark_value, &info->mark_mask); *flags |= PARAM_MARK; return true; } return false; }
static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_tproxy_target_info *tproxyinfo = (void *)(*target)->data; switch (c) { case '1': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert); parse_tproxy_lport(optarg, tproxyinfo); *flags |= PARAM_ONPORT; return 1; case '2': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert); parse_tproxy_laddr(optarg, tproxyinfo); *flags |= PARAM_ONIP; return 1; case '3': xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK); xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert); parse_tproxy_mark(optarg, tproxyinfo); *flags |= PARAM_MARK; return 1; } return 0; }
static void ratelimit_parse(struct xt_option_call *cb) { struct xt_ratelimit_mtinfo *info = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_MODE: if (parse_mode(&info->mode, cb->arg) < 0) xtables_param_act(XTF_BAD_VALUE, "ratelimit", "--ratelimit-mode", cb->arg); break; } }
static int LED_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_led_info *led = (void *)(*target)->data; switch (c) { case 'i': xtables_param_act(XTF_NO_INVERT, "LED", "--led-trigger-id", invert); if (strlen("netfilter-") + strlen(optarg) > sizeof(led->id)) xtables_error(PARAMETER_PROBLEM, "--led-trigger-id must be 16 chars or less"); if (optarg[0] == '\0') xtables_error(PARAMETER_PROBLEM, "--led-trigger-id cannot be blank"); /* "netfilter-" + 16 char id == 26 == sizeof(led->id) */ strcpy(led->id, "netfilter-"); strcat(led->id, optarg); *flags = 1; return true; case 'd': xtables_param_act(XTF_NO_INVERT, "LED", "--led-delay", invert); if (strncasecmp(optarg, "inf", 3) == 0) led->delay = -1; else led->delay = strtoul(optarg, NULL, 0); return true; case 'a': if (!invert) led->always_blink = 1; return true; } return false; }
static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_tos_target_info *info = (void *)(*target)->data; struct tos_value_mask tvm; switch (c) { case '=': xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); if (tvm.mask != 0xFF) xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel " "is too old to support anything besides " "/0xFF as a mask."); info->tos = tvm.value; *flags |= FLAG_TOS; return true; } return false; }
static void conntrack_ps_expires(struct xt_conntrack_mtinfo2 *info, const char *s) { unsigned int min, max; char *end; if (!xtables_strtoui(s, &end, &min, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); max = min; if (*end == ':') if (!xtables_strtoui(s, &end, &max, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); if (min > max) xtables_error(PARAMETER_PROBLEM, "expire min. range value \"%u\" greater than max. " "range value \"%u\"", min, max); info->expires_min = min; info->expires_max = max; }
static int ct_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data; unsigned int zone; switch (c) { case CT_OPT_NOTRACK: xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK); info->flags |= XT_CT_NOTRACK; break; case CT_OPT_HELPER: xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER); strncpy(info->helper, optarg, sizeof(info->helper)); info->helper[sizeof(info->helper) - 1] = '\0'; break; case CT_OPT_CTEVENTS: xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS); info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg); break; case CT_OPT_EXPEVENTS: xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS); info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg); break; case CT_OPT_ZONE: xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE); if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX)) xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg); info->zone = zone; break; default: return 0; } *flags |= c; return 1; }
static int CHECKSUM_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_CHECKSUM_info *einfo = (struct xt_CHECKSUM_info *)(*target)->data; switch (c) { case 'F': xtables_param_act(XTF_ONLY_ONCE, "CHECKSUM", "--checksum-fill", *flags & XT_CHECKSUM_OP_FILL); einfo->operation = XT_CHECKSUM_OP_FILL; *flags |= XT_CHECKSUM_OP_FILL; break; } return 1; }
static int iprange_mt6_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_iprange_mtinfo *info = (void *)(*match)->data; const struct in6_addr *ia; char *end; switch (c) { case '1': /* --src-range */ end = strchr(optarg, '-'); if (end == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--src-range", optarg); *end = '\0'; ia = xtables_numeric_to_ip6addr(optarg); if (ia == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--src-range", optarg); memcpy(&info->src_min.in, ia, sizeof(*ia)); ia = xtables_numeric_to_ip6addr(end+1); if (ia == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--src-range", end + 1); memcpy(&info->src_max.in, ia, sizeof(*ia)); info->flags |= IPRANGE_SRC; if (invert) info->flags |= IPRANGE_SRC_INV; *flags |= F_SRCIP; return true; case '2': /* --dst-range */ end = strchr(optarg, '-'); if (end == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--dst-range", optarg); *end = '\0'; ia = xtables_numeric_to_ip6addr(optarg); if (ia == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--dst-range", optarg); memcpy(&info->dst_min.in, ia, sizeof(*ia)); ia = xtables_numeric_to_ip6addr(end + 1); if (ia == NULL) xtables_param_act(XTF_BAD_VALUE, "iprange", "--dst-range", end + 1); memcpy(&info->dst_max.in, ia, sizeof(*ia)); info->flags |= IPRANGE_DST; if (invert) info->flags |= IPRANGE_DST_INV; *flags |= F_DSTIP; return true; } return false; }
static void parse_tproxy_laddr(const char *s, union nf_inet_addr *addrp, unsigned int nfproto) { struct in6_addr *laddr6 = NULL; struct in_addr *laddr4 = NULL; if (nfproto == NFPROTO_IPV6) { laddr6 = xtables_numeric_to_ip6addr(s); if (laddr6 == NULL) goto out; addrp->in6 = *laddr6; } else if (nfproto == NFPROTO_IPV4) { laddr4 = xtables_numeric_to_ipaddr(s); if (laddr4 == NULL) goto out; addrp->in = *laddr4; } return; out: xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s); }
static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct xt_mark_tginfo2 *info = (void *)(*target)->data; unsigned int value, mask = UINT32_MAX; char *end; switch (c) { case 'X': /* --set-xmark */ case '=': /* --set-mark */ xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); xtables_param_act(XTF_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert); if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); if (*end == '/') if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); if (*end != '\0') xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); info->mark = value; info->mask = mask; if (c == '=') info->mask = value | mask; break; case '&': /* --and-mark */ xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); xtables_param_act(XTF_NO_INVERT, "MARK", "--and-mark", invert); if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "MARK", "--and-mark", optarg); info->mark = 0; info->mask = ~mask; break; case '|': /* --or-mark */ xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); xtables_param_act(XTF_NO_INVERT, "MARK", "--or-mark", invert); if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "MARK", "--or-mark", optarg); info->mark = value; info->mask = value; break; case '^': /* --xor-mark */ xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); xtables_param_act(XTF_NO_INVERT, "MARK", "--xor-mark", invert); if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) xtables_param_act(XTF_BAD_VALUE, "MARK", "--xor-mark", optarg); info->mark = value; info->mask = 0; break; default: return false; } *flags |= F_MARK; return true; }
static int owner_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ipt_owner_info *info = (void *)(*match)->data; struct passwd *pwd; struct group *grp; unsigned int id; switch (c) { case 'u': xtables_param_act(XTF_ONLY_ONCE, "owner", "--uid-owner", *flags & FLAG_UID_OWNER); if ((pwd = getpwnam(optarg)) != NULL) id = pwd->pw_uid; else if (!xtables_strtoui(optarg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", optarg); if (invert) info->invert |= IPT_OWNER_UID; info->match |= IPT_OWNER_UID; info->uid = id; *flags |= FLAG_UID_OWNER; return true; case 'g': xtables_param_act(XTF_ONLY_ONCE, "owner", "--gid-owner", *flags & FLAG_GID_OWNER); if ((grp = getgrnam(optarg)) != NULL) id = grp->gr_gid; else if (!xtables_strtoui(optarg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", optarg); if (invert) info->invert |= IPT_OWNER_GID; info->match |= IPT_OWNER_GID; info->gid = id; *flags |= FLAG_GID_OWNER; return true; case 'p': xtables_param_act(XTF_ONLY_ONCE, "owner", "--pid-owner", *flags & FLAG_PID_OWNER); if (!xtables_strtoui(optarg, NULL, &id, 0, INT_MAX)) xtables_param_act(XTF_BAD_VALUE, "owner", "--pid-owner", optarg); if (invert) info->invert |= IPT_OWNER_PID; info->match |= IPT_OWNER_PID; info->pid = id; *flags |= FLAG_PID_OWNER; return true; case 's': xtables_param_act(XTF_ONLY_ONCE, "owner", "--sid-owner", *flags & FLAG_SID_OWNER); if (!xtables_strtoui(optarg, NULL, &id, 0, INT_MAX)) xtables_param_act(XTF_BAD_VALUE, "owner", "--sid-value", optarg); if (invert) info->invert |= IPT_OWNER_SID; info->match |= IPT_OWNER_SID; info->sid = id; *flags |= FLAG_SID_OWNER; return true; #ifdef IPT_OWNER_COMM case 'c': xtables_param_act(XTF_ONLY_ONCE, "owner", "--cmd-owner", *flags & FLAG_COMM); if (strlen(optarg) > sizeof(info->comm)) xtables_error(PARAMETER_PROBLEM, "owner match: command " "\"%s\" too long, max. %zu characters", optarg, sizeof(info->comm)); info->comm[sizeof(info->comm)-1] = '\0'; strncpy(info->comm, optarg, sizeof(info->comm)); if (invert) info->invert |= IPT_OWNER_COMM; info->match |= IPT_OWNER_COMM; *flags |= FLAG_COMM; return true; #endif } return false; }
static int owner_mt6_parse_v0(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ip6t_owner_info *info = (void *)(*match)->data; struct passwd *pwd; struct group *grp; unsigned int id; switch (c) { case 'u': xtables_param_act(XTF_ONLY_ONCE, "owner", "--uid-owner", *flags & FLAG_UID_OWNER); if ((pwd = getpwnam(optarg)) != NULL) id = pwd->pw_uid; else if (!xtables_strtoui(optarg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", optarg); if (invert) info->invert |= IP6T_OWNER_UID; info->match |= IP6T_OWNER_UID; info->uid = id; *flags |= FLAG_UID_OWNER; return true; case 'g': xtables_param_act(XTF_ONLY_ONCE, "owner", "--gid-owner", *flags & FLAG_GID_OWNER); if ((grp = getgrnam(optarg)) != NULL) id = grp->gr_gid; else if (!xtables_strtoui(optarg, NULL, &id, 0, UINT32_MAX - 1)) xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", optarg); if (invert) info->invert |= IP6T_OWNER_GID; info->match |= IP6T_OWNER_GID; info->gid = id; *flags |= FLAG_GID_OWNER; return true; case 'p': xtables_param_act(XTF_ONLY_ONCE, "owner", "--pid-owner", *flags & FLAG_PID_OWNER); if (!xtables_strtoui(optarg, NULL, &id, 0, INT_MAX)) xtables_param_act(XTF_BAD_VALUE, "owner", "--pid-owner", optarg); if (invert) info->invert |= IP6T_OWNER_PID; info->match |= IP6T_OWNER_PID; info->pid = id; *flags |= FLAG_PID_OWNER; return true; case 's': xtables_param_act(XTF_ONLY_ONCE, "owner", "--sid-owner", *flags & FLAG_SID_OWNER); if (!xtables_strtoui(optarg, NULL, &id, 0, INT_MAX)) xtables_param_act(XTF_BAD_VALUE, "owner", "--sid-owner", optarg); if (invert) info->invert |= IP6T_OWNER_SID; info->match |= IP6T_OWNER_SID; info->sid = id; *flags |= FLAG_SID_OWNER; return true; } return false; }