static void conntrack2_mt_parse(struct xt_option_call *cb)
{
#define cinfo2_transform(r, l) \
		memcpy((r), (l), offsetof(typeof(*(l)), sizeof(*info));

	struct xt_conntrack_mtinfo2 *info = cb->data;
	struct xt_conntrack_mtinfo3 up;

	memset(&up, 0, sizeof(up));
	memcpy(&up, info, sizeof(*info));
	up.origsrc_port_high = up.origsrc_port;
	up.origdst_port_high = up.origdst_port;
	up.replsrc_port_high = up.replsrc_port;
	up.repldst_port_high = up.repldst_port;
	cb->data = &up;
	conntrack_mt_parse(cb, 3);
	if (up.origsrc_port != up.origsrc_port_high ||
	    up.origdst_port != up.origdst_port_high ||
	    up.replsrc_port != up.replsrc_port_high ||
	    up.repldst_port != up.repldst_port_high)
		xtables_error(PARAMETER_PROBLEM,
			"conntrack rev 2 does not support port ranges");
	memcpy(info, &up, sizeof(*info));
	cb->data = info;
#undef cinfo2_transform
}
static void conntrack1_mt_parse(struct xt_option_call *cb)
{
	struct xt_conntrack_mtinfo1 *info = cb->data;
	struct xt_conntrack_mtinfo3 up;

	memset(&up, 0, sizeof(up));
	cinfo_transform(&up, info);
	up.origsrc_port_high = up.origsrc_port;
	up.origdst_port_high = up.origdst_port;
	up.replsrc_port_high = up.replsrc_port;
	up.repldst_port_high = up.repldst_port;
	cb->data = &up;
	conntrack_mt_parse(cb, 3);
	if (up.origsrc_port != up.origsrc_port_high ||
	    up.origdst_port != up.origdst_port_high ||
	    up.replsrc_port != up.replsrc_port_high ||
	    up.repldst_port != up.repldst_port_high)
		xtables_error(PARAMETER_PROBLEM,
			"conntrack rev 1 does not support port ranges");
	cinfo_transform(info, &up);
	cb->data = info;
}
Esempio n. 3
0
static int
conntrack_mt6_parse(int c, bool invert, unsigned int *flags,
                    struct xt_conntrack_mtinfo2 *info)
{
	struct in6_addr *addr = NULL;
	unsigned int naddrs = 0;

	switch (c) {
	case '3': /* --ctorigsrc */
		xtables_ip6parse_any(optarg, &addr,
		                         &info->origsrc_mask.in6, &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&info->origsrc_addr.in6, addr, sizeof(*addr));
		info->match_flags |= XT_CONNTRACK_ORIGSRC;
		if (invert)
			info->invert_flags |= XT_CONNTRACK_ORIGSRC;
		break;

	case '4': /* --ctorigdst */
		xtables_ip6parse_any(optarg, &addr,
		                         &info->origdst_mask.in6, &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_ip6parse_any(optarg, &addr,
		                         &info->replsrc_mask.in6, &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_ip6parse_any(optarg, &addr,
		                         &info->repldst_mask.in6, &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_mt4_parse(int c, char **argv, int invert, unsigned int *flags,
                    const void *entry, struct xt_entry_match **match)
{
	struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data;
	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, argv, invert, flags, match);
	}

	*flags = info->match_flags;
	return true;
}
static void conntrack3_mt_parse(struct xt_option_call *cb)
{
	conntrack_mt_parse(cb, 3);
}