Beispiel #1
0
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;
	}
}