static int conntrack_mt_parse(int c, bool invert, unsigned int *flags, struct xt_conntrack_mtinfo2 *info) { unsigned int port; char *p; switch (c) { case '1': /* --ctstate */ conntrack_ps_states(info, optarg); info->match_flags |= XT_CONNTRACK_STATE; if (invert) info->invert_flags |= XT_CONNTRACK_STATE; break; case '2': /* --ctproto */ /* Canonicalize into lower case */ for (p = optarg; *p != '\0'; ++p) *p = tolower(*p); info->l4proto = xtables_parse_protocol(optarg); if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO)) xtables_error(PARAMETER_PROBLEM, "conntrack: rule would " "never match protocol"); info->match_flags |= XT_CONNTRACK_PROTO; if (invert) info->invert_flags |= XT_CONNTRACK_PROTO; break; case '7': /* --ctstatus */ conntrack_ps_statuses(info, optarg); info->match_flags |= XT_CONNTRACK_STATUS; if (invert) info->invert_flags |= XT_CONNTRACK_STATUS; break; case '8': /* --ctexpire */ conntrack_ps_expires(info, optarg); info->match_flags |= XT_CONNTRACK_EXPIRES; if (invert) info->invert_flags |= XT_CONNTRACK_EXPIRES; break; case 'a': /* --ctorigsrcport */ if (!xtables_strtoui(optarg, NULL, &port, 0, UINT16_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctorigsrcport", optarg); info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT; info->origsrc_port = htons(port); if (invert) info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT; break; case 'b': /* --ctorigdstport */ if (!xtables_strtoui(optarg, NULL, &port, 0, UINT16_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctorigdstport", optarg); info->match_flags |= XT_CONNTRACK_ORIGDST_PORT; info->origdst_port = htons(port); if (invert) info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT; break; case 'c': /* --ctreplsrcport */ if (!xtables_strtoui(optarg, NULL, &port, 0, UINT16_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctreplsrcport", optarg); info->match_flags |= XT_CONNTRACK_REPLSRC_PORT; info->replsrc_port = htons(port); if (invert) info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT; break; case 'd': /* --ctrepldstport */ if (!xtables_strtoui(optarg, NULL, &port, 0, UINT16_MAX)) xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctrepldstport", optarg); info->match_flags |= XT_CONNTRACK_REPLDST_PORT; info->repldst_port = htons(port); if (invert) info->invert_flags |= XT_CONNTRACK_REPLDST_PORT; break; case 'e': /* --ctdir */ xtables_param_act(XTF_NO_INVERT, "conntrack", "--ctdir", invert); if (strcasecmp(optarg, "ORIGINAL") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags &= ~XT_CONNTRACK_DIRECTION; } else if (strcasecmp(optarg, "REPLY") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags |= XT_CONNTRACK_DIRECTION; } else { xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctdir", optarg); } break; default: return false; } *flags = info->match_flags; return true; }
static void conntrack_mt_parse(struct xt_option_call *cb, uint8_t rev) { struct xt_conntrack_mtinfo3 *info = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_CTSTATE: conntrack_ps_states(info, cb->arg); info->match_flags |= XT_CONNTRACK_STATE; if (cb->invert) info->invert_flags |= XT_CONNTRACK_STATE; break; case O_CTPROTO: info->l4proto = cb->val.protocol; if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO)) xtables_error(PARAMETER_PROBLEM, "conntrack: rule would " "never match protocol"); info->match_flags |= XT_CONNTRACK_PROTO; if (cb->invert) info->invert_flags |= XT_CONNTRACK_PROTO; break; case O_CTORIGSRC: info->origsrc_addr = cb->val.haddr; info->origsrc_mask = cb->val.hmask; info->match_flags |= XT_CONNTRACK_ORIGSRC; if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGSRC; break; case O_CTORIGDST: info->origdst_addr = cb->val.haddr; info->origdst_mask = cb->val.hmask; info->match_flags |= XT_CONNTRACK_ORIGDST; if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGDST; break; case O_CTREPLSRC: info->replsrc_addr = cb->val.haddr; info->replsrc_mask = cb->val.hmask; info->match_flags |= XT_CONNTRACK_REPLSRC; if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLSRC; break; case O_CTREPLDST: info->repldst_addr = cb->val.haddr; info->repldst_mask = cb->val.hmask; info->match_flags |= XT_CONNTRACK_REPLDST; if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLDST; break; case O_CTSTATUS: conntrack_ps_statuses(info, cb->arg); info->match_flags |= XT_CONNTRACK_STATUS; if (cb->invert) info->invert_flags |= XT_CONNTRACK_STATUS; break; case O_CTEXPIRE: info->expires_min = cb->val.u32_range[0]; info->expires_max = cb->val.u32_range[0]; if (cb->nvals >= 2) info->expires_max = cb->val.u32_range[1]; info->match_flags |= XT_CONNTRACK_EXPIRES; if (cb->invert) info->invert_flags |= XT_CONNTRACK_EXPIRES; break; case O_CTORIGSRCPORT: info->origsrc_port = cb->val.port_range[0]; info->origsrc_port_high = cb->val.port_range[cb->nvals >= 2]; info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT; if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT; break; case O_CTORIGDSTPORT: info->origdst_port = cb->val.port_range[0]; info->origdst_port_high = cb->val.port_range[cb->nvals >= 2]; info->match_flags |= XT_CONNTRACK_ORIGDST_PORT; if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT; break; case O_CTREPLSRCPORT: info->replsrc_port = cb->val.port_range[0]; info->replsrc_port_high = cb->val.port_range[cb->nvals >= 2]; info->match_flags |= XT_CONNTRACK_REPLSRC_PORT; if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT; break; case O_CTREPLDSTPORT: info->repldst_port = cb->val.port_range[0]; info->repldst_port_high = cb->val.port_range[cb->nvals >= 2]; info->match_flags |= XT_CONNTRACK_REPLDST_PORT; if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLDST_PORT; break; case O_CTDIR: if (strcasecmp(cb->arg, "ORIGINAL") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags &= ~XT_CONNTRACK_DIRECTION; } else if (strcasecmp(cb->arg, "REPLY") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags |= XT_CONNTRACK_DIRECTION; } else { xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctdir", cb->arg); } break; } }