xref: /aosp_15_r20/external/iptables/extensions/libxt_recent.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker #include <stdbool.h>
2*a71a9546SAutomerger Merge Worker #include <stdio.h>
3*a71a9546SAutomerger Merge Worker #include <string.h>
4*a71a9546SAutomerger Merge Worker #include <xtables.h>
5*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_recent.h>
6*a71a9546SAutomerger Merge Worker 
7*a71a9546SAutomerger Merge Worker enum {
8*a71a9546SAutomerger Merge Worker 	O_SET = 0,
9*a71a9546SAutomerger Merge Worker 	O_RCHECK,
10*a71a9546SAutomerger Merge Worker 	O_UPDATE,
11*a71a9546SAutomerger Merge Worker 	O_REMOVE,
12*a71a9546SAutomerger Merge Worker 	O_SECONDS,
13*a71a9546SAutomerger Merge Worker 	O_REAP,
14*a71a9546SAutomerger Merge Worker 	O_HITCOUNT,
15*a71a9546SAutomerger Merge Worker 	O_RTTL,
16*a71a9546SAutomerger Merge Worker 	O_NAME,
17*a71a9546SAutomerger Merge Worker 	O_RSOURCE,
18*a71a9546SAutomerger Merge Worker 	O_RDEST,
19*a71a9546SAutomerger Merge Worker 	O_MASK,
20*a71a9546SAutomerger Merge Worker 	F_SET    = 1 << O_SET,
21*a71a9546SAutomerger Merge Worker 	F_RCHECK = 1 << O_RCHECK,
22*a71a9546SAutomerger Merge Worker 	F_UPDATE = 1 << O_UPDATE,
23*a71a9546SAutomerger Merge Worker 	F_REMOVE = 1 << O_REMOVE,
24*a71a9546SAutomerger Merge Worker 	F_SECONDS = 1 << O_SECONDS,
25*a71a9546SAutomerger Merge Worker 	F_ANY_OP = F_SET | F_RCHECK | F_UPDATE | F_REMOVE,
26*a71a9546SAutomerger Merge Worker };
27*a71a9546SAutomerger Merge Worker 
28*a71a9546SAutomerger Merge Worker #define s struct xt_recent_mtinfo
29*a71a9546SAutomerger Merge Worker static const struct xt_option_entry recent_opts_v0[] = {
30*a71a9546SAutomerger Merge Worker 	{.name = "set", .id = O_SET, .type = XTTYPE_NONE,
31*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
32*a71a9546SAutomerger Merge Worker 	{.name = "rcheck", .id = O_RCHECK, .type = XTTYPE_NONE,
33*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
34*a71a9546SAutomerger Merge Worker 	{.name = "update", .id = O_UPDATE, .type = XTTYPE_NONE,
35*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
36*a71a9546SAutomerger Merge Worker 	{.name = "remove", .id = O_REMOVE, .type = XTTYPE_NONE,
37*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
38*a71a9546SAutomerger Merge Worker 	{.name = "seconds", .id = O_SECONDS, .type = XTTYPE_UINT32,
39*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, seconds), .min = 1},
40*a71a9546SAutomerger Merge Worker 	{.name = "reap", .id = O_REAP, .type = XTTYPE_NONE,
41*a71a9546SAutomerger Merge Worker 	 .also = F_SECONDS },
42*a71a9546SAutomerger Merge Worker 	{.name = "hitcount", .id = O_HITCOUNT, .type = XTTYPE_UINT32,
43*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hit_count)},
44*a71a9546SAutomerger Merge Worker 	{.name = "rttl", .id = O_RTTL, .type = XTTYPE_NONE,
45*a71a9546SAutomerger Merge Worker 	 .excl = F_SET | F_REMOVE},
46*a71a9546SAutomerger Merge Worker 	{.name = "name", .id = O_NAME, .type = XTTYPE_STRING,
47*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, name)},
48*a71a9546SAutomerger Merge Worker 	{.name = "rsource", .id = O_RSOURCE, .type = XTTYPE_NONE},
49*a71a9546SAutomerger Merge Worker 	{.name = "rdest", .id = O_RDEST, .type = XTTYPE_NONE},
50*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
51*a71a9546SAutomerger Merge Worker };
52*a71a9546SAutomerger Merge Worker #undef s
53*a71a9546SAutomerger Merge Worker 
54*a71a9546SAutomerger Merge Worker #define s struct xt_recent_mtinfo_v1
55*a71a9546SAutomerger Merge Worker static const struct xt_option_entry recent_opts_v1[] = {
56*a71a9546SAutomerger Merge Worker 	{.name = "set", .id = O_SET, .type = XTTYPE_NONE,
57*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
58*a71a9546SAutomerger Merge Worker 	{.name = "rcheck", .id = O_RCHECK, .type = XTTYPE_NONE,
59*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
60*a71a9546SAutomerger Merge Worker 	{.name = "update", .id = O_UPDATE, .type = XTTYPE_NONE,
61*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
62*a71a9546SAutomerger Merge Worker 	{.name = "remove", .id = O_REMOVE, .type = XTTYPE_NONE,
63*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY_OP, .flags = XTOPT_INVERT},
64*a71a9546SAutomerger Merge Worker 	{.name = "seconds", .id = O_SECONDS, .type = XTTYPE_UINT32,
65*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, seconds), .min = 1},
66*a71a9546SAutomerger Merge Worker 	{.name = "reap", .id = O_REAP, .type = XTTYPE_NONE,
67*a71a9546SAutomerger Merge Worker 	 .also = F_SECONDS },
68*a71a9546SAutomerger Merge Worker 	{.name = "hitcount", .id = O_HITCOUNT, .type = XTTYPE_UINT32,
69*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hit_count)},
70*a71a9546SAutomerger Merge Worker 	{.name = "rttl", .id = O_RTTL, .type = XTTYPE_NONE,
71*a71a9546SAutomerger Merge Worker 	 .excl = F_SET | F_REMOVE},
72*a71a9546SAutomerger Merge Worker 	{.name = "name", .id = O_NAME, .type = XTTYPE_STRING,
73*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, name)},
74*a71a9546SAutomerger Merge Worker 	{.name = "rsource", .id = O_RSOURCE, .type = XTTYPE_NONE},
75*a71a9546SAutomerger Merge Worker 	{.name = "rdest", .id = O_RDEST, .type = XTTYPE_NONE},
76*a71a9546SAutomerger Merge Worker 	{.name = "mask", .id = O_MASK, .type = XTTYPE_HOST,
77*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, mask)},
78*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
79*a71a9546SAutomerger Merge Worker };
80*a71a9546SAutomerger Merge Worker #undef s
81*a71a9546SAutomerger Merge Worker 
recent_help(void)82*a71a9546SAutomerger Merge Worker static void recent_help(void)
83*a71a9546SAutomerger Merge Worker {
84*a71a9546SAutomerger Merge Worker 	printf(
85*a71a9546SAutomerger Merge Worker "recent match options:\n"
86*a71a9546SAutomerger Merge Worker "[!] --set                       Add source address to list, always matches.\n"
87*a71a9546SAutomerger Merge Worker "[!] --rcheck                    Match if source address in list.\n"
88*a71a9546SAutomerger Merge Worker "[!] --update                    Match if source address in list, also update last-seen time.\n"
89*a71a9546SAutomerger Merge Worker "[!] --remove                    Match if source address in list, also removes that address from list.\n"
90*a71a9546SAutomerger Merge Worker "    --seconds seconds           For check and update commands above.\n"
91*a71a9546SAutomerger Merge Worker "                                Specifies that the match will only occur if source address last seen within\n"
92*a71a9546SAutomerger Merge Worker "                                the last 'seconds' seconds.\n"
93*a71a9546SAutomerger Merge Worker "    --reap                      Purge entries older then 'seconds'.\n"
94*a71a9546SAutomerger Merge Worker "                                Can only be used in conjunction with the seconds option.\n"
95*a71a9546SAutomerger Merge Worker "    --hitcount hits             For check and update commands above.\n"
96*a71a9546SAutomerger Merge Worker "                                Specifies that the match will only occur if source address seen hits times.\n"
97*a71a9546SAutomerger Merge Worker "                                May be used in conjunction with the seconds option.\n"
98*a71a9546SAutomerger Merge Worker "    --rttl                      For check and update commands above.\n"
99*a71a9546SAutomerger Merge Worker "                                Specifies that the match will only occur if the source address and the TTL\n"
100*a71a9546SAutomerger Merge Worker "                                match between this packet and the one which was set.\n"
101*a71a9546SAutomerger Merge Worker "                                Useful if you have problems with people spoofing their source address in order\n"
102*a71a9546SAutomerger Merge Worker "                                to DoS you via this module.\n"
103*a71a9546SAutomerger Merge Worker "    --name name                 Name of the recent list to be used.  DEFAULT used if none given.\n"
104*a71a9546SAutomerger Merge Worker "    --rsource                   Match/Save the source address of each packet in the recent list table (default).\n"
105*a71a9546SAutomerger Merge Worker "    --rdest                     Match/Save the destination address of each packet in the recent list table.\n"
106*a71a9546SAutomerger Merge Worker "    --mask netmask              Netmask that will be applied to this recent list.\n"
107*a71a9546SAutomerger Merge Worker "xt_recent by: Stephen Frost <[email protected]>.\n");
108*a71a9546SAutomerger Merge Worker }
109*a71a9546SAutomerger Merge Worker 
110*a71a9546SAutomerger Merge Worker enum {
111*a71a9546SAutomerger Merge Worker 	XT_RECENT_REV_0 = 0,
112*a71a9546SAutomerger Merge Worker 	XT_RECENT_REV_1,
113*a71a9546SAutomerger Merge Worker };
114*a71a9546SAutomerger Merge Worker 
recent_init(struct xt_entry_match * match,unsigned int rev)115*a71a9546SAutomerger Merge Worker static void recent_init(struct xt_entry_match *match, unsigned int rev)
116*a71a9546SAutomerger Merge Worker {
117*a71a9546SAutomerger Merge Worker 	struct xt_recent_mtinfo *info = (struct xt_recent_mtinfo *)match->data;
118*a71a9546SAutomerger Merge Worker 	struct xt_recent_mtinfo_v1 *info_v1 =
119*a71a9546SAutomerger Merge Worker 		(struct xt_recent_mtinfo_v1 *)match->data;
120*a71a9546SAutomerger Merge Worker 
121*a71a9546SAutomerger Merge Worker 	strncpy(info->name,"DEFAULT", XT_RECENT_NAME_LEN);
122*a71a9546SAutomerger Merge Worker 	/* even though XT_RECENT_NAME_LEN is currently defined as 200,
123*a71a9546SAutomerger Merge Worker 	 * better be safe, than sorry */
124*a71a9546SAutomerger Merge Worker 	info->name[XT_RECENT_NAME_LEN-1] = '\0';
125*a71a9546SAutomerger Merge Worker 	info->side = XT_RECENT_SOURCE;
126*a71a9546SAutomerger Merge Worker 	if (rev == XT_RECENT_REV_1)
127*a71a9546SAutomerger Merge Worker 		memset(&info_v1->mask, 0xFF, sizeof(info_v1->mask));
128*a71a9546SAutomerger Merge Worker }
129*a71a9546SAutomerger Merge Worker 
recent_parse(struct xt_option_call * cb)130*a71a9546SAutomerger Merge Worker static void recent_parse(struct xt_option_call *cb)
131*a71a9546SAutomerger Merge Worker {
132*a71a9546SAutomerger Merge Worker 	struct xt_recent_mtinfo *info = cb->data;
133*a71a9546SAutomerger Merge Worker 
134*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
135*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
136*a71a9546SAutomerger Merge Worker 	case O_SET:
137*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_SET;
138*a71a9546SAutomerger Merge Worker 		if (cb->invert)
139*a71a9546SAutomerger Merge Worker 			info->invert = true;
140*a71a9546SAutomerger Merge Worker 		break;
141*a71a9546SAutomerger Merge Worker 	case O_RCHECK:
142*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_CHECK;
143*a71a9546SAutomerger Merge Worker 		if (cb->invert)
144*a71a9546SAutomerger Merge Worker 			info->invert = true;
145*a71a9546SAutomerger Merge Worker 		break;
146*a71a9546SAutomerger Merge Worker 	case O_UPDATE:
147*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_UPDATE;
148*a71a9546SAutomerger Merge Worker 		if (cb->invert)
149*a71a9546SAutomerger Merge Worker 			info->invert = true;
150*a71a9546SAutomerger Merge Worker 		break;
151*a71a9546SAutomerger Merge Worker 	case O_REMOVE:
152*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_REMOVE;
153*a71a9546SAutomerger Merge Worker 		if (cb->invert)
154*a71a9546SAutomerger Merge Worker 			info->invert = true;
155*a71a9546SAutomerger Merge Worker 		break;
156*a71a9546SAutomerger Merge Worker 	case O_RTTL:
157*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_TTL;
158*a71a9546SAutomerger Merge Worker 		break;
159*a71a9546SAutomerger Merge Worker 	case O_RSOURCE:
160*a71a9546SAutomerger Merge Worker 		info->side = XT_RECENT_SOURCE;
161*a71a9546SAutomerger Merge Worker 		break;
162*a71a9546SAutomerger Merge Worker 	case O_RDEST:
163*a71a9546SAutomerger Merge Worker 		info->side = XT_RECENT_DEST;
164*a71a9546SAutomerger Merge Worker 		break;
165*a71a9546SAutomerger Merge Worker 	case O_REAP:
166*a71a9546SAutomerger Merge Worker 		info->check_set |= XT_RECENT_REAP;
167*a71a9546SAutomerger Merge Worker 		break;
168*a71a9546SAutomerger Merge Worker 	}
169*a71a9546SAutomerger Merge Worker }
170*a71a9546SAutomerger Merge Worker 
recent_check(struct xt_fcheck_call * cb)171*a71a9546SAutomerger Merge Worker static void recent_check(struct xt_fcheck_call *cb)
172*a71a9546SAutomerger Merge Worker {
173*a71a9546SAutomerger Merge Worker 	if (!(cb->xflags & F_ANY_OP))
174*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
175*a71a9546SAutomerger Merge Worker 			"recent: you must specify one of `--set', `--rcheck' "
176*a71a9546SAutomerger Merge Worker 			"`--update' or `--remove'");
177*a71a9546SAutomerger Merge Worker }
178*a71a9546SAutomerger Merge Worker 
recent_print(const void * ip,const struct xt_entry_match * match,unsigned int family)179*a71a9546SAutomerger Merge Worker static void recent_print(const void *ip, const struct xt_entry_match *match,
180*a71a9546SAutomerger Merge Worker                          unsigned int family)
181*a71a9546SAutomerger Merge Worker {
182*a71a9546SAutomerger Merge Worker 	const struct xt_recent_mtinfo_v1 *info = (const void *)match->data;
183*a71a9546SAutomerger Merge Worker 
184*a71a9546SAutomerger Merge Worker 	if (info->invert)
185*a71a9546SAutomerger Merge Worker 		printf(" !");
186*a71a9546SAutomerger Merge Worker 
187*a71a9546SAutomerger Merge Worker 	printf(" recent:");
188*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_SET)
189*a71a9546SAutomerger Merge Worker 		printf(" SET");
190*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_CHECK)
191*a71a9546SAutomerger Merge Worker 		printf(" CHECK");
192*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_UPDATE)
193*a71a9546SAutomerger Merge Worker 		printf(" UPDATE");
194*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_REMOVE)
195*a71a9546SAutomerger Merge Worker 		printf(" REMOVE");
196*a71a9546SAutomerger Merge Worker 	if(info->seconds) printf(" seconds: %d", info->seconds);
197*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_REAP)
198*a71a9546SAutomerger Merge Worker 		printf(" reap");
199*a71a9546SAutomerger Merge Worker 	if(info->hit_count) printf(" hit_count: %d", info->hit_count);
200*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_TTL)
201*a71a9546SAutomerger Merge Worker 		printf(" TTL-Match");
202*a71a9546SAutomerger Merge Worker 	printf(" name: %s", info->name);
203*a71a9546SAutomerger Merge Worker 	if (info->side == XT_RECENT_SOURCE)
204*a71a9546SAutomerger Merge Worker 		printf(" side: source");
205*a71a9546SAutomerger Merge Worker 	if (info->side == XT_RECENT_DEST)
206*a71a9546SAutomerger Merge Worker 		printf(" side: dest");
207*a71a9546SAutomerger Merge Worker 
208*a71a9546SAutomerger Merge Worker 	switch(family) {
209*a71a9546SAutomerger Merge Worker 	case NFPROTO_IPV4:
210*a71a9546SAutomerger Merge Worker 		printf(" mask: %s",
211*a71a9546SAutomerger Merge Worker 			xtables_ipaddr_to_numeric(&info->mask.in));
212*a71a9546SAutomerger Merge Worker 		break;
213*a71a9546SAutomerger Merge Worker 	case NFPROTO_IPV6:
214*a71a9546SAutomerger Merge Worker 		printf(" mask: %s",
215*a71a9546SAutomerger Merge Worker 			xtables_ip6addr_to_numeric(&info->mask.in6));
216*a71a9546SAutomerger Merge Worker 		break;
217*a71a9546SAutomerger Merge Worker 	}
218*a71a9546SAutomerger Merge Worker }
219*a71a9546SAutomerger Merge Worker 
recent_save(const void * ip,const struct xt_entry_match * match,unsigned int family)220*a71a9546SAutomerger Merge Worker static void recent_save(const void *ip, const struct xt_entry_match *match,
221*a71a9546SAutomerger Merge Worker 			unsigned int family)
222*a71a9546SAutomerger Merge Worker {
223*a71a9546SAutomerger Merge Worker 	const struct xt_recent_mtinfo_v1 *info = (const void *)match->data;
224*a71a9546SAutomerger Merge Worker 
225*a71a9546SAutomerger Merge Worker 	if (info->invert)
226*a71a9546SAutomerger Merge Worker 		printf(" !");
227*a71a9546SAutomerger Merge Worker 
228*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_SET)
229*a71a9546SAutomerger Merge Worker 		printf(" --set");
230*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_CHECK)
231*a71a9546SAutomerger Merge Worker 		printf(" --rcheck");
232*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_UPDATE)
233*a71a9546SAutomerger Merge Worker 		printf(" --update");
234*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_REMOVE)
235*a71a9546SAutomerger Merge Worker 		printf(" --remove");
236*a71a9546SAutomerger Merge Worker 	if(info->seconds) printf(" --seconds %d", info->seconds);
237*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_REAP)
238*a71a9546SAutomerger Merge Worker 		printf(" --reap");
239*a71a9546SAutomerger Merge Worker 	if(info->hit_count) printf(" --hitcount %d", info->hit_count);
240*a71a9546SAutomerger Merge Worker 	if (info->check_set & XT_RECENT_TTL)
241*a71a9546SAutomerger Merge Worker 		printf(" --rttl");
242*a71a9546SAutomerger Merge Worker 	printf(" --name %s",info->name);
243*a71a9546SAutomerger Merge Worker 
244*a71a9546SAutomerger Merge Worker 	switch(family) {
245*a71a9546SAutomerger Merge Worker 	case NFPROTO_IPV4:
246*a71a9546SAutomerger Merge Worker 		printf(" --mask %s",
247*a71a9546SAutomerger Merge Worker 			xtables_ipaddr_to_numeric(&info->mask.in));
248*a71a9546SAutomerger Merge Worker 		break;
249*a71a9546SAutomerger Merge Worker 	case NFPROTO_IPV6:
250*a71a9546SAutomerger Merge Worker 		printf(" --mask %s",
251*a71a9546SAutomerger Merge Worker 			xtables_ip6addr_to_numeric(&info->mask.in6));
252*a71a9546SAutomerger Merge Worker 		break;
253*a71a9546SAutomerger Merge Worker 	}
254*a71a9546SAutomerger Merge Worker 
255*a71a9546SAutomerger Merge Worker 	if (info->side == XT_RECENT_SOURCE)
256*a71a9546SAutomerger Merge Worker 		printf(" --rsource");
257*a71a9546SAutomerger Merge Worker 	if (info->side == XT_RECENT_DEST)
258*a71a9546SAutomerger Merge Worker 		printf(" --rdest");
259*a71a9546SAutomerger Merge Worker }
260*a71a9546SAutomerger Merge Worker 
recent_init_v0(struct xt_entry_match * match)261*a71a9546SAutomerger Merge Worker static void recent_init_v0(struct xt_entry_match *match)
262*a71a9546SAutomerger Merge Worker {
263*a71a9546SAutomerger Merge Worker 	recent_init(match, XT_RECENT_REV_0);
264*a71a9546SAutomerger Merge Worker }
265*a71a9546SAutomerger Merge Worker 
recent_init_v1(struct xt_entry_match * match)266*a71a9546SAutomerger Merge Worker static void recent_init_v1(struct xt_entry_match *match)
267*a71a9546SAutomerger Merge Worker {
268*a71a9546SAutomerger Merge Worker 	recent_init(match, XT_RECENT_REV_1);
269*a71a9546SAutomerger Merge Worker }
270*a71a9546SAutomerger Merge Worker 
recent_save_v0(const void * ip,const struct xt_entry_match * match)271*a71a9546SAutomerger Merge Worker static void recent_save_v0(const void *ip, const struct xt_entry_match *match)
272*a71a9546SAutomerger Merge Worker {
273*a71a9546SAutomerger Merge Worker 	recent_save(ip, match, NFPROTO_UNSPEC);
274*a71a9546SAutomerger Merge Worker }
275*a71a9546SAutomerger Merge Worker 
recent_save_v4(const void * ip,const struct xt_entry_match * match)276*a71a9546SAutomerger Merge Worker static void recent_save_v4(const void *ip, const struct xt_entry_match *match)
277*a71a9546SAutomerger Merge Worker {
278*a71a9546SAutomerger Merge Worker 	recent_save(ip, match, NFPROTO_IPV4);
279*a71a9546SAutomerger Merge Worker }
280*a71a9546SAutomerger Merge Worker 
recent_save_v6(const void * ip,const struct xt_entry_match * match)281*a71a9546SAutomerger Merge Worker static void recent_save_v6(const void *ip, const struct xt_entry_match *match)
282*a71a9546SAutomerger Merge Worker {
283*a71a9546SAutomerger Merge Worker 	recent_save(ip, match, NFPROTO_IPV6);
284*a71a9546SAutomerger Merge Worker }
285*a71a9546SAutomerger Merge Worker 
recent_print_v0(const void * ip,const struct xt_entry_match * match,int numeric)286*a71a9546SAutomerger Merge Worker static void recent_print_v0(const void *ip, const struct xt_entry_match *match,
287*a71a9546SAutomerger Merge Worker 			    int numeric)
288*a71a9546SAutomerger Merge Worker {
289*a71a9546SAutomerger Merge Worker 	recent_print(ip, match, NFPROTO_UNSPEC);
290*a71a9546SAutomerger Merge Worker }
291*a71a9546SAutomerger Merge Worker 
recent_print_v4(const void * ip,const struct xt_entry_match * match,int numeric)292*a71a9546SAutomerger Merge Worker static void recent_print_v4(const void *ip, const struct xt_entry_match *match,
293*a71a9546SAutomerger Merge Worker                          int numeric)
294*a71a9546SAutomerger Merge Worker {
295*a71a9546SAutomerger Merge Worker 	recent_print(ip, match, NFPROTO_IPV4);
296*a71a9546SAutomerger Merge Worker }
297*a71a9546SAutomerger Merge Worker 
recent_print_v6(const void * ip,const struct xt_entry_match * match,int numeric)298*a71a9546SAutomerger Merge Worker static void recent_print_v6(const void *ip, const struct xt_entry_match *match,
299*a71a9546SAutomerger Merge Worker                          int numeric)
300*a71a9546SAutomerger Merge Worker {
301*a71a9546SAutomerger Merge Worker 	recent_print(ip, match, NFPROTO_IPV6);
302*a71a9546SAutomerger Merge Worker }
303*a71a9546SAutomerger Merge Worker 
304*a71a9546SAutomerger Merge Worker static struct xtables_match recent_mt_reg[] = {
305*a71a9546SAutomerger Merge Worker 	{
306*a71a9546SAutomerger Merge Worker 		.name          = "recent",
307*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
308*a71a9546SAutomerger Merge Worker 		.revision      = 0,
309*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_UNSPEC,
310*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_recent_mtinfo)),
311*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_recent_mtinfo)),
312*a71a9546SAutomerger Merge Worker 		.help          = recent_help,
313*a71a9546SAutomerger Merge Worker 		.init          = recent_init_v0,
314*a71a9546SAutomerger Merge Worker 		.x6_parse      = recent_parse,
315*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = recent_check,
316*a71a9546SAutomerger Merge Worker 		.print         = recent_print_v0,
317*a71a9546SAutomerger Merge Worker 		.save          = recent_save_v0,
318*a71a9546SAutomerger Merge Worker 		.x6_options    = recent_opts_v0,
319*a71a9546SAutomerger Merge Worker 	},
320*a71a9546SAutomerger Merge Worker 	{
321*a71a9546SAutomerger Merge Worker 		.name          = "recent",
322*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
323*a71a9546SAutomerger Merge Worker 		.revision      = 1,
324*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_IPV4,
325*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_recent_mtinfo_v1)),
326*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_recent_mtinfo_v1)),
327*a71a9546SAutomerger Merge Worker 		.help          = recent_help,
328*a71a9546SAutomerger Merge Worker 		.init          = recent_init_v1,
329*a71a9546SAutomerger Merge Worker 		.x6_parse      = recent_parse,
330*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = recent_check,
331*a71a9546SAutomerger Merge Worker 		.print         = recent_print_v4,
332*a71a9546SAutomerger Merge Worker 		.save          = recent_save_v4,
333*a71a9546SAutomerger Merge Worker 		.x6_options    = recent_opts_v1,
334*a71a9546SAutomerger Merge Worker 	},
335*a71a9546SAutomerger Merge Worker 	{
336*a71a9546SAutomerger Merge Worker 		.name          = "recent",
337*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
338*a71a9546SAutomerger Merge Worker 		.revision      = 1,
339*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_IPV6,
340*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_recent_mtinfo_v1)),
341*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_recent_mtinfo_v1)),
342*a71a9546SAutomerger Merge Worker 		.help          = recent_help,
343*a71a9546SAutomerger Merge Worker 		.init          = recent_init_v1,
344*a71a9546SAutomerger Merge Worker 		.x6_parse      = recent_parse,
345*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = recent_check,
346*a71a9546SAutomerger Merge Worker 		.print         = recent_print_v6,
347*a71a9546SAutomerger Merge Worker 		.save          = recent_save_v6,
348*a71a9546SAutomerger Merge Worker 		.x6_options    = recent_opts_v1,
349*a71a9546SAutomerger Merge Worker 	},
350*a71a9546SAutomerger Merge Worker };
351*a71a9546SAutomerger Merge Worker 
_init(void)352*a71a9546SAutomerger Merge Worker void _init(void)
353*a71a9546SAutomerger Merge Worker {
354*a71a9546SAutomerger Merge Worker 	xtables_register_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
355*a71a9546SAutomerger Merge Worker }
356