xref: /aosp_15_r20/external/iptables/extensions/libip6t_hl.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker /*
2*a71a9546SAutomerger Merge Worker  * IPv6 Hop Limit matching module
3*a71a9546SAutomerger Merge Worker  * Maciej Soltysiak <[email protected]>
4*a71a9546SAutomerger Merge Worker  * Based on HW's ttl match
5*a71a9546SAutomerger Merge Worker  * This program is released under the terms of GNU GPL
6*a71a9546SAutomerger Merge Worker  * Cleanups by Stephane Ouellette <[email protected]>
7*a71a9546SAutomerger Merge Worker  */
8*a71a9546SAutomerger Merge Worker #include <stdio.h>
9*a71a9546SAutomerger Merge Worker #include <xtables.h>
10*a71a9546SAutomerger Merge Worker #include <linux/netfilter_ipv6/ip6t_hl.h>
11*a71a9546SAutomerger Merge Worker 
12*a71a9546SAutomerger Merge Worker enum {
13*a71a9546SAutomerger Merge Worker 	O_HL_EQ = 0,
14*a71a9546SAutomerger Merge Worker 	O_HL_LT,
15*a71a9546SAutomerger Merge Worker 	O_HL_GT,
16*a71a9546SAutomerger Merge Worker 	F_HL_EQ = 1 << O_HL_EQ,
17*a71a9546SAutomerger Merge Worker 	F_HL_LT = 1 << O_HL_LT,
18*a71a9546SAutomerger Merge Worker 	F_HL_GT = 1 << O_HL_GT,
19*a71a9546SAutomerger Merge Worker 	F_ANY  = F_HL_EQ | F_HL_LT | F_HL_GT,
20*a71a9546SAutomerger Merge Worker };
21*a71a9546SAutomerger Merge Worker 
22*a71a9546SAutomerger Merge Worker static void hl_help(void)
23*a71a9546SAutomerger Merge Worker {
24*a71a9546SAutomerger Merge Worker 	printf(
25*a71a9546SAutomerger Merge Worker "hl match options:\n"
26*a71a9546SAutomerger Merge Worker "[!] --hl-eq value	Match hop limit value\n"
27*a71a9546SAutomerger Merge Worker "  --hl-lt value	Match HL < value\n"
28*a71a9546SAutomerger Merge Worker "  --hl-gt value	Match HL > value\n");
29*a71a9546SAutomerger Merge Worker }
30*a71a9546SAutomerger Merge Worker 
31*a71a9546SAutomerger Merge Worker static void hl_parse(struct xt_option_call *cb)
32*a71a9546SAutomerger Merge Worker {
33*a71a9546SAutomerger Merge Worker 	struct ip6t_hl_info *info = cb->data;
34*a71a9546SAutomerger Merge Worker 
35*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
36*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
37*a71a9546SAutomerger Merge Worker 	case O_HL_EQ:
38*a71a9546SAutomerger Merge Worker 		info->mode = cb->invert ? IP6T_HL_NE : IP6T_HL_EQ;
39*a71a9546SAutomerger Merge Worker 		break;
40*a71a9546SAutomerger Merge Worker 	case O_HL_LT:
41*a71a9546SAutomerger Merge Worker 		info->mode = IP6T_HL_LT;
42*a71a9546SAutomerger Merge Worker 		break;
43*a71a9546SAutomerger Merge Worker 	case O_HL_GT:
44*a71a9546SAutomerger Merge Worker 		info->mode = IP6T_HL_GT;
45*a71a9546SAutomerger Merge Worker 		break;
46*a71a9546SAutomerger Merge Worker 	}
47*a71a9546SAutomerger Merge Worker }
48*a71a9546SAutomerger Merge Worker 
49*a71a9546SAutomerger Merge Worker static void hl_check(struct xt_fcheck_call *cb)
50*a71a9546SAutomerger Merge Worker {
51*a71a9546SAutomerger Merge Worker 	if (!(cb->xflags & F_ANY))
52*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
53*a71a9546SAutomerger Merge Worker 			"HL match: You must specify one of "
54*a71a9546SAutomerger Merge Worker 			"`--hl-eq', `--hl-lt', `--hl-gt'");
55*a71a9546SAutomerger Merge Worker }
56*a71a9546SAutomerger Merge Worker 
57*a71a9546SAutomerger Merge Worker static void hl_print(const void *ip, const struct xt_entry_match *match,
58*a71a9546SAutomerger Merge Worker                      int numeric)
59*a71a9546SAutomerger Merge Worker {
60*a71a9546SAutomerger Merge Worker 	static const char *const op[] = {
61*a71a9546SAutomerger Merge Worker 		[IP6T_HL_EQ] = "==",
62*a71a9546SAutomerger Merge Worker 		[IP6T_HL_NE] = "!=",
63*a71a9546SAutomerger Merge Worker 		[IP6T_HL_LT] = "<",
64*a71a9546SAutomerger Merge Worker 		[IP6T_HL_GT] = ">" };
65*a71a9546SAutomerger Merge Worker 
66*a71a9546SAutomerger Merge Worker 	const struct ip6t_hl_info *info =
67*a71a9546SAutomerger Merge Worker 		(struct ip6t_hl_info *) match->data;
68*a71a9546SAutomerger Merge Worker 
69*a71a9546SAutomerger Merge Worker 	printf(" HL match HL %s %u", op[info->mode], info->hop_limit);
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker 
72*a71a9546SAutomerger Merge Worker static void hl_save(const void *ip, const struct xt_entry_match *match)
73*a71a9546SAutomerger Merge Worker {
74*a71a9546SAutomerger Merge Worker 	static const char *const op[] = {
75*a71a9546SAutomerger Merge Worker 		[IP6T_HL_EQ] = "--hl-eq",
76*a71a9546SAutomerger Merge Worker 		[IP6T_HL_NE] = "! --hl-eq",
77*a71a9546SAutomerger Merge Worker 		[IP6T_HL_LT] = "--hl-lt",
78*a71a9546SAutomerger Merge Worker 		[IP6T_HL_GT] = "--hl-gt" };
79*a71a9546SAutomerger Merge Worker 
80*a71a9546SAutomerger Merge Worker 	const struct ip6t_hl_info *info =
81*a71a9546SAutomerger Merge Worker 		(struct ip6t_hl_info *) match->data;
82*a71a9546SAutomerger Merge Worker 
83*a71a9546SAutomerger Merge Worker 	printf(" %s %u", op[info->mode], info->hop_limit);
84*a71a9546SAutomerger Merge Worker }
85*a71a9546SAutomerger Merge Worker 
86*a71a9546SAutomerger Merge Worker static const char *const op[] = {
87*a71a9546SAutomerger Merge Worker 	[IP6T_HL_EQ] = "",
88*a71a9546SAutomerger Merge Worker 	[IP6T_HL_NE] = "!= ",
89*a71a9546SAutomerger Merge Worker 	[IP6T_HL_LT] = "lt ",
90*a71a9546SAutomerger Merge Worker 	[IP6T_HL_GT] = "gt "
91*a71a9546SAutomerger Merge Worker };
92*a71a9546SAutomerger Merge Worker 
93*a71a9546SAutomerger Merge Worker static int hl_xlate(struct xt_xlate *xl,
94*a71a9546SAutomerger Merge Worker 		    const struct xt_xlate_mt_params *params)
95*a71a9546SAutomerger Merge Worker {
96*a71a9546SAutomerger Merge Worker 	const struct ip6t_hl_info *info =
97*a71a9546SAutomerger Merge Worker 		(struct ip6t_hl_info *) params->match->data;
98*a71a9546SAutomerger Merge Worker 
99*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "ip6 hoplimit %s%u", op[info->mode], info->hop_limit);
100*a71a9546SAutomerger Merge Worker 
101*a71a9546SAutomerger Merge Worker 	return 1;
102*a71a9546SAutomerger Merge Worker }
103*a71a9546SAutomerger Merge Worker 
104*a71a9546SAutomerger Merge Worker #define s struct ip6t_hl_info
105*a71a9546SAutomerger Merge Worker static const struct xt_option_entry hl_opts[] = {
106*a71a9546SAutomerger Merge Worker 	{.name = "hl-lt", .id = O_HL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
107*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
108*a71a9546SAutomerger Merge Worker 	{.name = "hl-gt", .id = O_HL_GT, .excl = F_ANY, .type = XTTYPE_UINT8,
109*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
110*a71a9546SAutomerger Merge Worker 	{.name = "hl-eq", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
111*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
112*a71a9546SAutomerger Merge Worker 	{.name = "hl", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
113*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
114*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
115*a71a9546SAutomerger Merge Worker };
116*a71a9546SAutomerger Merge Worker #undef s
117*a71a9546SAutomerger Merge Worker 
118*a71a9546SAutomerger Merge Worker static struct xtables_match hl_mt6_reg = {
119*a71a9546SAutomerger Merge Worker 	.name          = "hl",
120*a71a9546SAutomerger Merge Worker 	.version       = XTABLES_VERSION,
121*a71a9546SAutomerger Merge Worker 	.family        = NFPROTO_IPV6,
122*a71a9546SAutomerger Merge Worker 	.size          = XT_ALIGN(sizeof(struct ip6t_hl_info)),
123*a71a9546SAutomerger Merge Worker 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)),
124*a71a9546SAutomerger Merge Worker 	.help          = hl_help,
125*a71a9546SAutomerger Merge Worker 	.print         = hl_print,
126*a71a9546SAutomerger Merge Worker 	.save          = hl_save,
127*a71a9546SAutomerger Merge Worker 	.x6_parse      = hl_parse,
128*a71a9546SAutomerger Merge Worker 	.x6_fcheck     = hl_check,
129*a71a9546SAutomerger Merge Worker 	.x6_options    = hl_opts,
130*a71a9546SAutomerger Merge Worker 	.xlate	       = hl_xlate,
131*a71a9546SAutomerger Merge Worker };
132*a71a9546SAutomerger Merge Worker 
133*a71a9546SAutomerger Merge Worker 
134*a71a9546SAutomerger Merge Worker void _init(void)
135*a71a9546SAutomerger Merge Worker {
136*a71a9546SAutomerger Merge Worker 	xtables_register_match(&hl_mt6_reg);
137*a71a9546SAutomerger Merge Worker }
138