1a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt/*
2a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *	libxt_conntrack
3a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *	Shared library add-on to iptables for conntrack matching support.
4a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *
5a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *	GPL (C) 2001  Marc Boucher (marc@mbsi.ca).
6a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *	Copyright © CC Computer Consultants GmbH, 2007 - 2008
7a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt *	Jan Engelhardt <jengelh@computergmbh.de>
85054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher */
9a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt#include <stdbool.h>
1073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#include <stdint.h>
11a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt#include <stdio.h>
125054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher#include <stdlib.h>
13a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt#include <string.h>
1408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#include <xtables.h>
15a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt#include <linux/netfilter/xt_conntrack.h>
1640d54756cd8a2705e22b36f7aef03bb2c472a10bPatrick McHardy#include <linux/netfilter/nf_conntrack_common.h>
174dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte
18350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct ip_conntrack_old_tuple {
19350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	struct {
20350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		__be32 ip;
21350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		union {
22350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt			__u16 all;
23350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		} u;
24350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	} src;
25350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
26350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	struct {
27350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		__be32 ip;
28350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		union {
29350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt			__u16 all;
30350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		} u;
31350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
32350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		/* The protocol. */
33350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt		__u16 protonum;
34350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	} dst;
35350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt};
36350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
37350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct xt_conntrack_info {
38350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	unsigned int statemask, statusmask;
39350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
40350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
41350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
42350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
43350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	unsigned long expires_min, expires_max;
44350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
45350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	/* Flags word */
467ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t flags;
47350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	/* Inverse flags */
487ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t invflags;
49350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt};
50350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
5173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtenum {
5273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTSTATE = 0,
5373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTPROTO,
5473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTORIGSRC,
5573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTORIGDST,
5673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTREPLSRC,
5773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTREPLDST,
5873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTORIGSRCPORT,
5973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTORIGDSTPORT,
6073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTREPLSRCPORT,
6173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTREPLDSTPORT,
6273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTSTATUS,
6373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTEXPIRE,
6473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	O_CTDIR,
6573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt};
6673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt
67a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardtstatic void conntrack_mt_help(void)
685054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
695054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	printf(
70a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"conntrack match options:\n"
71a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctstate {INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED|SNAT|DNAT}[,...]\n"
72a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"                               State(s) to match\n"
73a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctproto proto            Protocol to match; by number or name, e.g. \"tcp\"\n"
74a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctorigsrc address[/mask]\n"
75a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctorigdst address[/mask]\n"
76a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctreplsrc address[/mask]\n"
77a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctrepldst address[/mask]\n"
78a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"                               Original/Reply source/destination address\n"
79a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt"[!] --ctorigsrcport port\n"
80a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt"[!] --ctorigdstport port\n"
81a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt"[!] --ctreplsrcport port\n"
82a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt"[!] --ctrepldstport port\n"
83a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt"                               TCP/UDP/SCTP orig./reply source/destination port\n"
84a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctstatus {NONE|EXPECTED|SEEN_REPLY|ASSURED|CONFIRMED}[,...]\n"
85a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"                               Status(es) to match\n"
86a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"[!] --ctexpire time[:time]     Match remaining lifetime in seconds against\n"
87a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt"                               value or range of values (inclusive)\n"
888b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"    --ctdir {ORIGINAL|REPLY}   Flow direction of packet\n");
895054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
905054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
9173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#define s struct xt_conntrack_info /* for v0 */
9273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic const struct xt_option_entry conntrack_mt_opts_v0[] = {
9373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING,
9473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
9573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL,
9673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
9773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOST,
9873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
9973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOST,
10073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
10173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctreplsrc", .id = O_CTREPLSRC, .type = XTTYPE_HOST,
10273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
10373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctrepldst", .id = O_CTREPLDST, .type = XTTYPE_HOST,
10473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
10573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctstatus", .id = O_CTSTATUS, .type = XTTYPE_STRING,
10673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
10773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctexpire", .id = O_CTEXPIRE, .type = XTTYPE_UINT32RC,
10873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
10973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	XTOPT_TABLEEND,
1105054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher};
11173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#undef s
11273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt
11373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#define s struct xt_conntrack_mtinfo3 /* for v1-v3 */
11473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt/* We exploit the fact that v1-v3 share the same layout */
11573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic const struct xt_option_entry conntrack_mt_opts[] = {
11673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING,
11773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
11873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL,
11973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
12073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOSTMASK,
12173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
12273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOSTMASK,
12373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
12473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctreplsrc", .id = O_CTREPLSRC, .type = XTTYPE_HOSTMASK,
12573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
12673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctrepldst", .id = O_CTREPLDST, .type = XTTYPE_HOSTMASK,
12773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
12873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctstatus", .id = O_CTSTATUS, .type = XTTYPE_STRING,
12973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
13073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctexpire", .id = O_CTEXPIRE, .type = XTTYPE_UINT32RC,
13173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
13273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigsrcport", .id = O_CTORIGSRCPORT, .type = XTTYPE_PORTRC,
13373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
13473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctorigdstport", .id = O_CTORIGDSTPORT, .type = XTTYPE_PORTRC,
13573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
13673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctreplsrcport", .id = O_CTREPLSRCPORT, .type = XTTYPE_PORTRC,
13773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
13873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctrepldstport", .id = O_CTREPLDSTPORT, .type = XTTYPE_PORTRC,
13973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	 .flags = XTOPT_INVERT},
14073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	{.name = "ctdir", .id = O_CTDIR, .type = XTTYPE_STRING},
14173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	XTOPT_TABLEEND,
142a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt};
14373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#undef s
144a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
1455054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic int
146dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardtparse_state(const char *state, size_t len, struct xt_conntrack_info *sinfo)
1475054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
148dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	if (strncasecmp(state, "INVALID", len) == 0)
149a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_INVALID;
150dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "NEW", len) == 0)
151a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_NEW);
152dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "ESTABLISHED", len) == 0)
153a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED);
154dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "RELATED", len) == 0)
155a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_RELATED);
156dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "UNTRACKED", len) == 0)
157a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_UNTRACKED;
158dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "SNAT", len) == 0)
159a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_SNAT;
160dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(state, "DNAT", len) == 0)
161a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->statemask |= XT_CONNTRACK_STATE_DNAT;
1625054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	else
1635054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		return 0;
1645054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	return 1;
1655054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
1665054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
1675054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
168a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardtparse_states(const char *arg, struct xt_conntrack_info *sinfo)
1695054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
1705054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	const char *comma;
1715054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
1725054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	while ((comma = strchr(arg, ',')) != NULL) {
1735054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		if (comma == arg || !parse_state(arg, comma-arg, sinfo))
1741829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "Bad ctstate \"%s\"", arg);
1755054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		arg = comma+1;
1765054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
1770ec8c0f00b591681076af2db34df0f230b08fa2cPablo Neira Ayuso	if (!*arg)
1781829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "\"--ctstate\" requires a list of "
1790ec8c0f00b591681076af2db34df0f230b08fa2cPablo Neira Ayuso					      "states with no spaces, e.g. "
1800ec8c0f00b591681076af2db34df0f230b08fa2cPablo Neira Ayuso					      "ESTABLISHED,RELATED");
1815054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (strlen(arg) == 0 || !parse_state(arg, strlen(arg), sinfo))
1821829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Bad ctstate \"%s\"", arg);
1835054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
1845054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
185a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic bool
186c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_ps_state(struct xt_conntrack_mtinfo3 *info, const char *state,
187a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                   size_t z)
188a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
189a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (strncasecmp(state, "INVALID", z) == 0)
190a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_INVALID;
191a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "NEW", z) == 0)
192a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_NEW);
193a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "ESTABLISHED", z) == 0)
194a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED);
195a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "RELATED", z) == 0)
196a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_RELATED);
197a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "UNTRACKED", z) == 0)
198a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_UNTRACKED;
199a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "SNAT", z) == 0)
200a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_SNAT;
201a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(state, "DNAT", z) == 0)
202a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->state_mask |= XT_CONNTRACK_STATE_DNAT;
203a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else
204a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		return false;
205a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	return true;
206a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
207a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
208a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
209c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_ps_states(struct xt_conntrack_mtinfo3 *info, const char *arg)
210a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
211a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	const char *comma;
212a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
213a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	while ((comma = strchr(arg, ',')) != NULL) {
214a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (comma == arg || !conntrack_ps_state(info, arg, comma - arg))
2151829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
216a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			           "Bad ctstate \"%s\"", arg);
217a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		arg = comma + 1;
218a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
219a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
220a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (strlen(arg) == 0 || !conntrack_ps_state(info, arg, strlen(arg)))
2211829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Bad ctstate \"%s\"", arg);
222a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
223a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
2245054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic int
225dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardtparse_status(const char *status, size_t len, struct xt_conntrack_info *sinfo)
2265054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
227dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	if (strncasecmp(status, "NONE", len) == 0)
2285054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sinfo->statusmask |= 0;
229dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(status, "EXPECTED", len) == 0)
2305054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sinfo->statusmask |= IPS_EXPECTED;
231dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(status, "SEEN_REPLY", len) == 0)
2325054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sinfo->statusmask |= IPS_SEEN_REPLY;
233dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(status, "ASSURED", len) == 0)
2345054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sinfo->statusmask |= IPS_ASSURED;
235a643c3eccb6a985e720c807f5a4c86347fc9b899Harald Welte#ifdef IPS_CONFIRMED
236dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt	else if (strncasecmp(status, "CONFIRMED", len) == 0)
237a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		sinfo->statusmask |= IPS_CONFIRMED;
238a643c3eccb6a985e720c807f5a4c86347fc9b899Harald Welte#endif
2395054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	else
2405054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		return 0;
2415054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	return 1;
2425054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
2435054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
2445054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
245a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardtparse_statuses(const char *arg, struct xt_conntrack_info *sinfo)
2465054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
2475054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	const char *comma;
2485054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
2495054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	while ((comma = strchr(arg, ',')) != NULL) {
2505054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		if (comma == arg || !parse_status(arg, comma-arg, sinfo))
2511829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg);
2525054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		arg = comma+1;
2535054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
2545054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
2555054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (strlen(arg) == 0 || !parse_status(arg, strlen(arg), sinfo))
2561829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg);
2575054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
2585054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
259a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic bool
260c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_ps_status(struct xt_conntrack_mtinfo3 *info, const char *status,
261a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                    size_t z)
262a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
263a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (strncasecmp(status, "NONE", z) == 0)
264a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->status_mask |= 0;
265a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(status, "EXPECTED", z) == 0)
266a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->status_mask |= IPS_EXPECTED;
267a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(status, "SEEN_REPLY", z) == 0)
268a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->status_mask |= IPS_SEEN_REPLY;
269a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(status, "ASSURED", z) == 0)
270a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->status_mask |= IPS_ASSURED;
271a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else if (strncasecmp(status, "CONFIRMED", z) == 0)
272a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->status_mask |= IPS_CONFIRMED;
273a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	else
274a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		return false;
275a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	return true;
276a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
277a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
278a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
279c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_ps_statuses(struct xt_conntrack_mtinfo3 *info, const char *arg)
280a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
281a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	const char *comma;
282a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
283a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	while ((comma = strchr(arg, ',')) != NULL) {
284a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (comma == arg || !conntrack_ps_status(info, arg, comma - arg))
2851829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
286a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			           "Bad ctstatus \"%s\"", arg);
287a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		arg = comma + 1;
288a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
289a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
290a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (strlen(arg) == 0 || !conntrack_ps_status(info, arg, strlen(arg)))
2911829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg);
292a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
293a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
29473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack_parse(struct xt_option_call *cb)
2955054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
29673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	struct xt_conntrack_info *sinfo = cb->data;
2975054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
29873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	xtables_option_parse(cb);
29973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	switch (cb->entry->id) {
30073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTSTATE:
30173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		parse_states(cb->arg, sinfo);
30273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
303a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_STATE;
3045054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
30573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTPROTO:
30673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
307a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_PROTO;
30873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = cb->val.protocol;
3095054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
3105054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0
311a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		    && (sinfo->invflags & XT_INV_PROTO))
3121829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
3135054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher				   "rule would never match protocol");
3145054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
315a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_PROTO;
3165054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
31773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGSRC:
31873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
319a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_ORIGSRC;
32073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip = cb->val.haddr.ip;
321a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_ORIGSRC;
3225054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
32373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGDST:
32473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
325a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_ORIGDST;
32673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip = cb->val.haddr.ip;
327a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_ORIGDST;
3285054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
32973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLSRC:
33073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
331a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_REPLSRC;
33273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		sinfo->tuple[IP_CT_DIR_REPLY].src.ip = cb->val.haddr.ip;
333a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_REPLSRC;
3345054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
33573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLDST:
33673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
337a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_REPLDST;
33873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		sinfo->tuple[IP_CT_DIR_REPLY].dst.ip = cb->val.haddr.ip;
339a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_REPLDST;
3405054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
34173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTSTATUS:
34273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		parse_statuses(cb->arg, sinfo);
34373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
344a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_STATUS;
345a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_STATUS;
3465054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
34773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTEXPIRE:
3486944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		sinfo->expires_min = cb->val.u32_range[0];
3496944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		sinfo->expires_max = cb->val.u32_range[0];
3506944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		if (cb->nvals >= 2)
3516944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt			sinfo->expires_max = cb->val.u32_range[1];
35273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
353a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt			sinfo->invflags |= XT_CONNTRACK_EXPIRES;
354a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		sinfo->flags |= XT_CONNTRACK_EXPIRES;
3555054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		break;
3565054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
3575054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
3585054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
35973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack_mt_parse(struct xt_option_call *cb, uint8_t rev)
360c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
36173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	struct xt_conntrack_mtinfo3 *info = cb->data;
362c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
36373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	xtables_option_parse(cb);
36473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	switch (cb->entry->id) {
36573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTSTATE:
36673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		conntrack_ps_states(info, cb->arg);
367a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_STATE;
36873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
369a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_STATE;
370a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
37173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTPROTO:
37273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->l4proto = cb->val.protocol;
373a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO))
3741829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "conntrack: rule would "
375a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			           "never match protocol");
376a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
377a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_PROTO;
37873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
379a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_PROTO;
380a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
38173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGSRC:
38273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origsrc_addr = cb->val.haddr;
38373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origsrc_mask = cb->val.hmask;
38473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->match_flags |= XT_CONNTRACK_ORIGSRC;
38573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
38673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt			info->invert_flags |= XT_CONNTRACK_ORIGSRC;
38773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		break;
38873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGDST:
38973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origdst_addr = cb->val.haddr;
39073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origdst_mask = cb->val.hmask;
39173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->match_flags |= XT_CONNTRACK_ORIGDST;
39273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
39373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt			info->invert_flags |= XT_CONNTRACK_ORIGDST;
39473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		break;
39573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLSRC:
39673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->replsrc_addr = cb->val.haddr;
39773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->replsrc_mask = cb->val.hmask;
39873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->match_flags |= XT_CONNTRACK_REPLSRC;
39973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
40073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt			info->invert_flags |= XT_CONNTRACK_REPLSRC;
40173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		break;
40273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLDST:
40373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->repldst_addr = cb->val.haddr;
40473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->repldst_mask = cb->val.hmask;
40573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->match_flags |= XT_CONNTRACK_REPLDST;
40673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
40773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt			info->invert_flags |= XT_CONNTRACK_REPLDST;
40873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		break;
40973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTSTATUS:
41073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		conntrack_ps_statuses(info, cb->arg);
411a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_STATUS;
41273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
413a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_STATUS;
414a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
41573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTEXPIRE:
4166944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		info->expires_min = cb->val.u32_range[0];
4176944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		info->expires_max = cb->val.u32_range[0];
4186944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		if (cb->nvals >= 2)
4196944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt			info->expires_max = cb->val.u32_range[1];
420a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_EXPIRES;
42173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
422a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_EXPIRES;
423a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
42473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGSRCPORT:
42573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origsrc_port = cb->val.port_range[0];
426fe9922cb4f1fb75072970dd09605fdc056b96195Jan Engelhardt		info->origsrc_port_high = cb->val.port_range[cb->nvals >= 2];
427a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT;
42873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
429a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT;
430a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
43173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTORIGDSTPORT:
43273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->origdst_port = cb->val.port_range[0];
433fe9922cb4f1fb75072970dd09605fdc056b96195Jan Engelhardt		info->origdst_port_high = cb->val.port_range[cb->nvals >= 2];
434a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_ORIGDST_PORT;
43573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
436a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT;
437a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
43873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLSRCPORT:
43973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->replsrc_port = cb->val.port_range[0];
440fe9922cb4f1fb75072970dd09605fdc056b96195Jan Engelhardt		info->replsrc_port_high = cb->val.port_range[cb->nvals >= 2];
441a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_REPLSRC_PORT;
44273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
443a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT;
444a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
44573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTREPLDSTPORT:
44673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		info->repldst_port = cb->val.port_range[0];
447fe9922cb4f1fb75072970dd09605fdc056b96195Jan Engelhardt		info->repldst_port_high = cb->val.port_range[cb->nvals >= 2];
448a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		info->match_flags |= XT_CONNTRACK_REPLDST_PORT;
44973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (cb->invert)
450a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_REPLDST_PORT;
451a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
45273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	case O_CTDIR:
45373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		if (strcasecmp(cb->arg, "ORIGINAL") == 0) {
454a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->match_flags  |= XT_CONNTRACK_DIRECTION;
455a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags &= ~XT_CONNTRACK_DIRECTION;
45673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		} else if (strcasecmp(cb->arg, "REPLY") == 0) {
457a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->match_flags  |= XT_CONNTRACK_DIRECTION;
458a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			info->invert_flags |= XT_CONNTRACK_DIRECTION;
459a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		} else {
46073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt			xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctdir", cb->arg);
461a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		}
462a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		break;
463a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
464a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
465a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
466b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt#define cinfo_transform(r, l) \
467b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	do { \
468b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt		memcpy((r), (l), offsetof(typeof(*(l)), state_mask)); \
469b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt		(r)->state_mask  = (l)->state_mask; \
470b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt		(r)->status_mask = (l)->status_mask; \
471b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	} while (false);
472b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
47373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack1_mt_parse(struct xt_option_call *cb)
474b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
47573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	struct xt_conntrack_mtinfo1 *info = cb->data;
476c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	struct xt_conntrack_mtinfo3 up;
477b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
47873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	memset(&up, 0, sizeof(up));
479b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(&up, info);
4809bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.origsrc_port_high = up.origsrc_port;
4819bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.origdst_port_high = up.origdst_port;
4829bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.replsrc_port_high = up.replsrc_port;
4839bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.repldst_port_high = up.repldst_port;
48473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	cb->data = &up;
48573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	conntrack_mt_parse(cb, 3);
48673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	if (up.origsrc_port != up.origsrc_port_high ||
48773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.origdst_port != up.origdst_port_high ||
48873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.replsrc_port != up.replsrc_port_high ||
48973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.repldst_port != up.repldst_port_high)
49073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
49110dbcd0bfb5a62a71a706d11134f83b0539f4dd3Jan Engelhardt			"conntrack rev 1 does not support port ranges");
492b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(info, &up);
49373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	cb->data = info;
494b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
495b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
49673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack2_mt_parse(struct xt_option_call *cb)
497b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
49873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#define cinfo2_transform(r, l) \
49973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		memcpy((r), (l), offsetof(typeof(*(l)), sizeof(*info));
500b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
50173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	struct xt_conntrack_mtinfo2 *info = cb->data;
50273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	struct xt_conntrack_mtinfo3 up;
503c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
50473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	memset(&up, 0, sizeof(up));
50573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	memcpy(&up, info, sizeof(*info));
5069bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.origsrc_port_high = up.origsrc_port;
5079bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.origdst_port_high = up.origdst_port;
5089bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.replsrc_port_high = up.replsrc_port;
5099bfedca6347c2e079e569954197777813f4ef2fbJan Engelhardt	up.repldst_port_high = up.repldst_port;
51073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	cb->data = &up;
51173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	conntrack_mt_parse(cb, 3);
51273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	if (up.origsrc_port != up.origsrc_port_high ||
51373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.origdst_port != up.origdst_port_high ||
51473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.replsrc_port != up.replsrc_port_high ||
51573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	    up.repldst_port != up.repldst_port_high)
51673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
51710dbcd0bfb5a62a71a706d11134f83b0539f4dd3Jan Engelhardt			"conntrack rev 2 does not support port ranges");
51873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	memcpy(info, &up, sizeof(*info));
51973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	cb->data = info;
52073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt#undef cinfo2_transform
521c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
522c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
52373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack3_mt_parse(struct xt_option_call *cb)
524c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
52573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	conntrack_mt_parse(cb, 3);
526b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
527b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
52873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardtstatic void conntrack_mt_check(struct xt_fcheck_call *cb)
5295054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
53073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt	if (cb->xflags == 0)
5311829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "conntrack: At least one option "
532a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		           "is required");
5335054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
5345054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
5355054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
5365054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherprint_state(unsigned int statemask)
5375054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
53873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	const char *sep = " ";
5395054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
540a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_INVALID) {
5415054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sINVALID", sep);
5425054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5435054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
544a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_NEW)) {
5455054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sNEW", sep);
5465054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5475054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
548a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_RELATED)) {
5495054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sRELATED", sep);
5505054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5515054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
552a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED)) {
5535054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sESTABLISHED", sep);
5545054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5555054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
556a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_UNTRACKED) {
5574dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte		printf("%sUNTRACKED", sep);
5584dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte		sep = ",";
5594dc734c73cc4a0ff87c0ce3673544628b58c7e24Harald Welte	}
560a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_SNAT) {
5615054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sSNAT", sep);
5625054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5635054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
564a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (statemask & XT_CONNTRACK_STATE_DNAT) {
5655054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sDNAT", sep);
5665054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5675054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
5685054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
5695054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
5705054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
5715054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherprint_status(unsigned int statusmask)
5725054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
57373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	const char *sep = " ";
5745054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
5755054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (statusmask & IPS_EXPECTED) {
5765054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sEXPECTED", sep);
5775054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5785054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
5795054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (statusmask & IPS_SEEN_REPLY) {
5805054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sSEEN_REPLY", sep);
5815054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5825054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
5835054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (statusmask & IPS_ASSURED) {
5845054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		printf("%sASSURED", sep);
5855054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5865054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
587a643c3eccb6a985e720c807f5a4c86347fc9b899Harald Welte	if (statusmask & IPS_CONFIRMED) {
588a643c3eccb6a985e720c807f5a4c86347fc9b899Harald Welte		printf("%sCONFIRMED", sep);
5895054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		sep = ",";
5905054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
591a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (statusmask == 0)
592a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		printf("%sNONE", sep);
5935054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
5945054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
5955054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
596a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtconntrack_dump_addr(const union nf_inet_addr *addr,
597a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                    const union nf_inet_addr *mask,
598a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                    unsigned int family, bool numeric)
599a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
60003d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	if (family == NFPROTO_IPV4) {
601a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (!numeric && addr->ip == 0) {
60273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" anywhere");
603a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			return;
604a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		}
6056b6c096ca56975125edf2aadfd195f23d34df38fJan Engelhardt		if (numeric)
60673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %s%s",
60776f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ipaddr_to_numeric(&addr->in),
60876f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ipmask_to_numeric(&mask->in));
6096b6c096ca56975125edf2aadfd195f23d34df38fJan Engelhardt		else
61073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %s%s",
61176f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ipaddr_to_anyname(&addr->in),
61276f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ipmask_to_numeric(&mask->in));
61303d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	} else if (family == NFPROTO_IPV6) {
614a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 &&
615a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		    addr->ip6[2] == 0 && addr->ip6[3] == 0) {
61673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" anywhere");
617a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			return;
618a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		}
6196b6c096ca56975125edf2aadfd195f23d34df38fJan Engelhardt		if (numeric)
62073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %s%s",
62176f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ip6addr_to_numeric(&addr->in6),
62276f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ip6mask_to_numeric(&mask->in6));
6236b6c096ca56975125edf2aadfd195f23d34df38fJan Engelhardt		else
62473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %s%s",
62576f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ip6addr_to_anyname(&addr->in6),
62676f7a230e4182ab2b64a68c9d84437035d925f3bJan Engelhardt			       xtables_ip6mask_to_numeric(&mask->in6));
627a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
628a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
629a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
630a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
63169f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardtprint_addr(const struct in_addr *addr, const struct in_addr *mask,
63269f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt           int inv, int numeric)
6335054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
6345054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	char buf[BUFSIZ];
6355054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
636a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if (inv)
63773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" !");
6385054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
6395054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	if (mask->s_addr == 0L && !numeric)
64073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %s", "anywhere");
6415054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	else {
6425054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		if (numeric)
643e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ipaddr_to_numeric(addr));
6445054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		else
645e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ipaddr_to_anyname(addr));
646e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt		strcat(buf, xtables_ipmask_to_numeric(mask));
64773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %s", buf);
6485054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
6495054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
6505054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
6515054e85be306809cf0a484469d7f7f6e16a31646Marc Boucherstatic void
652c0a9ab93f49a3d2508c95d0ca1a01c1089983731Yasuyuki KOZAKAImatchinfo_print(const void *ip, const struct xt_entry_match *match, int numeric, const char *optpfx)
6535054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
65469f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_conntrack_info *sinfo = (const void *)match->data;
6555054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
656a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_STATE) {
657a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt        	if (sinfo->invflags & XT_CONNTRACK_STATE)
65873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
65973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctstate", optpfx);
6605054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_state(sinfo->statemask);
6615054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
6625054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
663a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_PROTO) {
664a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt        	if (sinfo->invflags & XT_CONNTRACK_PROTO)
66573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
66673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctproto", optpfx);
66773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %u", sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum);
6685a4892b7566fd572a195b12b3a449d0c03125a54Phil Oester	}
6695a4892b7566fd572a195b12b3a449d0c03125a54Phil Oester
670a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_ORIGSRC) {
671a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		if (sinfo->invflags & XT_CONNTRACK_ORIGSRC)
67273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
67373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctorigsrc", optpfx);
6745054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
6755054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_addr(
6765054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
6775054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    &sinfo->sipmsk[IP_CT_DIR_ORIGINAL],
678a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		    false,
6795054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    numeric);
6805054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
6815054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
682a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_ORIGDST) {
683a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		if (sinfo->invflags & XT_CONNTRACK_ORIGDST)
68473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
68573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctorigdst", optpfx);
6865054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
6875054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_addr(
6885054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
6895054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    &sinfo->dipmsk[IP_CT_DIR_ORIGINAL],
690a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		    false,
6915054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    numeric);
6925054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
6935054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
694a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_REPLSRC) {
695a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		if (sinfo->invflags & XT_CONNTRACK_REPLSRC)
69673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
69773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctreplsrc", optpfx);
6985054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
6995054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_addr(
7005054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
7015054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    &sinfo->sipmsk[IP_CT_DIR_REPLY],
702a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		    false,
7035054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    numeric);
7045054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
7055054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
706a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_REPLDST) {
707a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		if (sinfo->invflags & XT_CONNTRACK_REPLDST)
70873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
70973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctrepldst", optpfx);
7105054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
7115054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_addr(
7125054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
7135054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    &sinfo->dipmsk[IP_CT_DIR_REPLY],
714a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt		    false,
7155054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		    numeric);
7165054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
7175054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
718a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_STATUS) {
719a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt        	if (sinfo->invflags & XT_CONNTRACK_STATUS)
72073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
72173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctstatus", optpfx);
7225054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher		print_status(sinfo->statusmask);
7235054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
7245054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
725a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt	if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
726a80b6046fa216c26dbc18d587f6255afa8444885Jan Engelhardt        	if (sinfo->invflags & XT_CONNTRACK_EXPIRES)
72773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
72873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctexpire ", optpfx);
7295054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
7305054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher        	if (sinfo->expires_max == sinfo->expires_min)
73173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%lu", sinfo->expires_min);
7325054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher        	else
73373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%lu:%lu", sinfo->expires_min, sinfo->expires_max);
7345054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	}
735c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt
736c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt	if (sinfo->flags & XT_CONNTRACK_DIRECTION) {
737c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt		if (sinfo->invflags & XT_CONNTRACK_DIRECTION)
73873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %sctdir REPLY", optpfx);
739c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt		else
74073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %sctdir ORIGINAL", optpfx);
741c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt	}
742c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt
7435054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
7445054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
745a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
746c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_dump_ports(const char *prefix, const char *opt,
747c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		     u_int16_t port_low, u_int16_t port_high)
748c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
749c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	if (port_high == 0 || port_low == port_high)
75073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %s%s %u", prefix, opt, port_low);
751c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	else
75273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %s%s %u:%u", prefix, opt, port_low, port_high);
753c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
754c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
755c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void
756c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack_dump(const struct xt_conntrack_mtinfo3 *info, const char *prefix,
757c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy               unsigned int family, bool numeric, bool v3)
758a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
759a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_STATE) {
760a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_STATE)
76173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
76273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctstate", prefix);
763a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		print_state(info->state_mask);
764a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
765a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
766a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_PROTO) {
767a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_PROTO)
76873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
76973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctproto %u", prefix, info->l4proto);
770a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
771a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
772a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_ORIGSRC) {
773093d5fc9d1826b8f0ccfbb3160c98a3c844d0273Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_ORIGSRC)
77473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
77573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctorigsrc", prefix);
776a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		conntrack_dump_addr(&info->origsrc_addr, &info->origsrc_mask,
777a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		                    family, numeric);
778a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
779a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
780a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_ORIGDST) {
781093d5fc9d1826b8f0ccfbb3160c98a3c844d0273Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_ORIGDST)
78273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
78373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctorigdst", prefix);
784a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		conntrack_dump_addr(&info->origdst_addr, &info->origdst_mask,
785a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		                    family, numeric);
786a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
787a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
788a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_REPLSRC) {
789093d5fc9d1826b8f0ccfbb3160c98a3c844d0273Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_REPLSRC)
79073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
79173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctreplsrc", prefix);
792a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		conntrack_dump_addr(&info->replsrc_addr, &info->replsrc_mask,
793a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		                    family, numeric);
794a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
795a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
796a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_REPLDST) {
797093d5fc9d1826b8f0ccfbb3160c98a3c844d0273Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_REPLDST)
79873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
79973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctrepldst", prefix);
800a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		conntrack_dump_addr(&info->repldst_addr, &info->repldst_mask,
801a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		                    family, numeric);
802a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
803a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
804a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) {
805a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)
80673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
807c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		conntrack_dump_ports(prefix, "ctorigsrcport",
808c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->origsrc_port : ntohs(info->origsrc_port),
809c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->origsrc_port_high : 0);
810a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
811a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
812a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_ORIGDST_PORT) {
813a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)
81473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
815c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		conntrack_dump_ports(prefix, "ctorigdstport",
816c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->origdst_port : ntohs(info->origdst_port),
817c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->origdst_port_high : 0);
818a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
819a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
820a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_REPLSRC_PORT) {
821a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)
82273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
823c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		conntrack_dump_ports(prefix, "ctreplsrcport",
824c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->replsrc_port : ntohs(info->replsrc_port),
825c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->replsrc_port_high : 0);
826a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
827a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
828a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_REPLDST_PORT) {
829a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_REPLDST_PORT)
83073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
831c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		conntrack_dump_ports(prefix, "ctrepldstport",
832c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->repldst_port : ntohs(info->repldst_port),
833c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy				     v3 ? info->repldst_port_high : 0);
834a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
835a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
836a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_STATUS) {
837a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_STATUS)
83873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
83973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctstatus", prefix);
840a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		print_status(info->status_mask);
841a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
842a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
843a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_EXPIRES) {
844a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_EXPIRES)
84573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" !");
84673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" %sctexpire ", prefix);
847a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
848a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		if (info->expires_max == info->expires_min)
84973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u", (unsigned int)info->expires_min);
850a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt		else
85173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u:%u", (unsigned int)info->expires_min,
852a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt			       (unsigned int)info->expires_max);
853a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt	}
854c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt
855c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt	if (info->match_flags & XT_CONNTRACK_DIRECTION) {
856c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt		if (info->invert_flags & XT_CONNTRACK_DIRECTION)
85773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %sctdir REPLY", prefix);
858c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt		else
85973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %sctdir ORIGINAL", prefix);
860c7fc1dae1e8f8a5fe2ad4eac4bdd1f3c59d8c975Jan Engelhardt	}
861a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
862a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
86359d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void conntrack_print(const void *ip, const struct xt_entry_match *match,
86459d164019340d110d302634e429320577f0db7beJan Engelhardt                            int numeric)
8655054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
8665054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher	matchinfo_print(ip, match, numeric, "");
8675054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
8685054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
869a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
870b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtconntrack1_mt4_print(const void *ip, const struct xt_entry_match *match,
871b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt                     int numeric)
872b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
873b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	const struct xt_conntrack_mtinfo1 *info = (void *)match->data;
874c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	struct xt_conntrack_mtinfo3 up;
875b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
876b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(&up, info);
877c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump(&up, "", NFPROTO_IPV4, numeric, false);
878b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
879b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
880b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtstatic void
881b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtconntrack1_mt6_print(const void *ip, const struct xt_entry_match *match,
882b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt                     int numeric)
883b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
884b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	const struct xt_conntrack_mtinfo1 *info = (void *)match->data;
885c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	struct xt_conntrack_mtinfo3 up;
886b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
887b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(&up, info);
888c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump(&up, "", NFPROTO_IPV6, numeric, false);
889b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
890b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
891b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtstatic void
892c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack2_mt_print(const void *ip, const struct xt_entry_match *match,
893c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                    int numeric)
894a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
895c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "", NFPROTO_IPV4, numeric, false);
896a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
897a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
898a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardtstatic void
899c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack2_mt6_print(const void *ip, const struct xt_entry_match *match,
900c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                     int numeric)
901c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
902c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "", NFPROTO_IPV6, numeric, false);
903c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
904c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
905c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void
906c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack3_mt_print(const void *ip, const struct xt_entry_match *match,
907a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                    int numeric)
908a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
909c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "", NFPROTO_IPV4, numeric, true);
910c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
911c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
912c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void
913c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardyconntrack3_mt6_print(const void *ip, const struct xt_entry_match *match,
914c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                     int numeric)
915c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
916c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "", NFPROTO_IPV6, numeric, true);
917a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
918a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
91959d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void conntrack_save(const void *ip, const struct xt_entry_match *match)
9205054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
921db503f9a45f2a765ef63834a2c9416ccf59385afJoszef Kadlecsik	matchinfo_print(ip, match, 1, "--");
9225054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
9235054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
924c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void conntrack3_mt_save(const void *ip,
925c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                               const struct xt_entry_match *match)
926c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
927c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "--", NFPROTO_IPV4, true, true);
928c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
929c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
930c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void conntrack3_mt6_save(const void *ip,
931c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                                const struct xt_entry_match *match)
932a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
933c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "--", NFPROTO_IPV6, true, true);
934a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
935a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
936c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void conntrack2_mt_save(const void *ip,
937a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt                               const struct xt_entry_match *match)
938a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt{
939c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "--", NFPROTO_IPV4, true, false);
940c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy}
941c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy
942c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardystatic void conntrack2_mt6_save(const void *ip,
943c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy                                const struct xt_entry_match *match)
944c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy{
945c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump((const void *)match->data, "--", NFPROTO_IPV6, true, false);
946a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt}
947a8ad34cf11540d147b8aded6826a1452841d2aa7Jan Engelhardt
948b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtstatic void
949b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtconntrack1_mt4_save(const void *ip, const struct xt_entry_match *match)
950b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
951b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	const struct xt_conntrack_mtinfo1 *info = (void *)match->data;
952c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	struct xt_conntrack_mtinfo3 up;
953b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
954b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(&up, info);
955c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump(&up, "--", NFPROTO_IPV4, true, false);
956b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
957b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
958b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtstatic void
959b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardtconntrack1_mt6_save(const void *ip, const struct xt_entry_match *match)
960b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt{
961b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	const struct xt_conntrack_mtinfo1 *info = (void *)match->data;
962c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	struct xt_conntrack_mtinfo3 up;
963b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
964b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt	cinfo_transform(&up, info);
965c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	conntrack_dump(&up, "--", NFPROTO_IPV6, true, false);
966b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt}
967b97b42147ea65d7d24d70a2ffe925dbf091f26bcJan Engelhardt
968f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardtstatic struct xtables_match conntrack_mt_reg[] = {
969f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
970f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
971f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "conntrack",
972f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 0,
973f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_IPV4,
974f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_conntrack_info)),
975f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_info)),
976f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = conntrack_mt_help,
97773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack_parse,
97873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
979f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = conntrack_print,
980f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = conntrack_save,
98173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts_v0,
982f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
983f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
984f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
985f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "conntrack",
986f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 1,
987f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_IPV4,
988f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
989f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
990f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = conntrack_mt_help,
99173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack1_mt_parse,
99273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
9938e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.print         = conntrack1_mt4_print,
9948e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.save          = conntrack1_mt4_save,
99573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
996f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
997f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
998f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
999f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "conntrack",
1000f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 1,
1001f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_IPV6,
1002f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
1003f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)),
1004f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = conntrack_mt_help,
100573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack1_mt_parse,
100673425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
10078e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.print         = conntrack1_mt6_print,
10088e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.save          = conntrack1_mt6_save,
100973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
10108e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt	},
10118e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt	{
10128e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.version       = XTABLES_VERSION,
10138e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.name          = "conntrack",
10148e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.revision      = 2,
10158e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.family        = NFPROTO_IPV4,
10168e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)),
10178e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)),
10188e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.help          = conntrack_mt_help,
101973425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack2_mt_parse,
102073425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
1021c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.print         = conntrack2_mt_print,
1022c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.save          = conntrack2_mt_save,
102373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
10248e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt	},
10258e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt	{
10268e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.version       = XTABLES_VERSION,
10278e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.name          = "conntrack",
10288e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.revision      = 2,
10298e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.family        = NFPROTO_IPV6,
10308e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)),
10318e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)),
10328e4dacaed17701cb1891b962bb856e0e8cfbb5c8Jan Engelhardt		.help          = conntrack_mt_help,
103373425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack2_mt_parse,
103473425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
1035c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.print         = conntrack2_mt6_print,
1036c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.save          = conntrack2_mt6_save,
103773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
1038c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	},
1039c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	{
1040c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.version       = XTABLES_VERSION,
1041c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.name          = "conntrack",
1042c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.revision      = 3,
1043c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.family        = NFPROTO_IPV4,
1044c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)),
1045c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)),
1046c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.help          = conntrack_mt_help,
104773425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack3_mt_parse,
104873425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
1049c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.print         = conntrack3_mt_print,
1050c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.save          = conntrack3_mt_save,
105173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
1052c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	},
1053c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy	{
1054c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.version       = XTABLES_VERSION,
1055c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.name          = "conntrack",
1056c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.revision      = 3,
1057c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.family        = NFPROTO_IPV6,
1058c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.size          = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)),
1059c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)),
1060c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.help          = conntrack_mt_help,
106173425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_parse      = conntrack3_mt_parse,
106273425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_fcheck     = conntrack_mt_check,
1063c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.print         = conntrack3_mt6_print,
1064c8f28cc8b84133f20421470e9a61a5a0c78b9c4aPatrick McHardy		.save          = conntrack3_mt6_save,
106573425492d4c57d34a616d948666ac75ecc612eedJan Engelhardt		.x6_options    = conntrack_mt_opts,
1066f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
10675054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher};
10685054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher
10695054e85be306809cf0a484469d7f7f6e16a31646Marc Bouchervoid _init(void)
10705054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher{
1071f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	xtables_register_matches(conntrack_mt_reg, ARRAY_SIZE(conntrack_mt_reg));
10725054e85be306809cf0a484469d7f7f6e16a31646Marc Boucher}
1073