xref: /aosp_15_r20/external/iptables/extensions/libip6t_REJECT.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1 /* Shared library add-on to ip6tables to add customized REJECT support.
2  *
3  * (C) 2000 Jozsef Kadlecsik <[email protected]>
4  *
5  * ported to IPv6 by Harald Welte <[email protected]>
6  *
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <xtables.h>
11 #include <linux/netfilter_ipv6/ip6t_REJECT.h>
12 
13 struct reject_names {
14 	const char *name;
15 	const char *alias;
16 	const char *desc;
17 	const char *xlate;
18 };
19 
20 enum {
21 	O_REJECT_WITH = 0,
22 };
23 
24 static const struct reject_names reject_table[] = {
25 	[IP6T_ICMP6_NO_ROUTE] = {
26 		"icmp6-no-route", "no-route",
27 		"ICMPv6 no route",
28 		"no-route",
29 	},
30 	[IP6T_ICMP6_ADM_PROHIBITED] = {
31 		"icmp6-adm-prohibited", "adm-prohibited",
32 		"ICMPv6 administratively prohibited",
33 		"admin-prohibited",
34 	},
35 #if 0
36 	[IP6T_ICMP6_NOT_NEIGHBOR] = {
37 		"icmp6-not-neighbor", "not-neighbor",
38 		"ICMPv6 not a neighbor",
39 	},
40 #endif
41 	[IP6T_ICMP6_ADDR_UNREACH] = {
42 		"icmp6-addr-unreachable", "addr-unreach",
43 		"ICMPv6 address unreachable",
44 		"addr-unreachable",
45 	},
46 	[IP6T_ICMP6_PORT_UNREACH] = {
47 		"icmp6-port-unreachable", "port-unreach",
48 		"ICMPv6 port unreachable",
49 		"port-unreachable",
50 	},
51 #if 0
52 	[IP6T_ICMP6_ECHOREPLY] = {},
53 #endif
54 	[IP6T_TCP_RESET] = {
55 		"tcp-reset", "tcp-reset",
56 		"TCP RST packet",
57 		"tcp reset",
58 	},
59 	[IP6T_ICMP6_POLICY_FAIL] = {
60 		"icmp6-policy-fail", "policy-fail",
61 		"ICMPv6 policy fail",
62 		"policy-fail",
63 	},
64 	[IP6T_ICMP6_REJECT_ROUTE] = {
65 		"icmp6-reject-route", "reject-route",
66 		"ICMPv6 reject route",
67 		"reject-route",
68 	},
69 };
70 
71 static void
print_reject_types(void)72 print_reject_types(void)
73 {
74 	unsigned int i;
75 
76 	printf("Valid reject types:\n");
77 
78 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
79 		if (!reject_table[i].name)
80 			continue;
81 		printf("    %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
82 		printf("    %-25s\talias\n", reject_table[i].alias);
83 	}
84 	printf("\n");
85 }
86 
REJECT_help(void)87 static void REJECT_help(void)
88 {
89 	printf(
90 "REJECT target options:\n"
91 "--reject-with type              drop input packet and send back\n"
92 "                                a reply packet according to type:\n");
93 
94 	print_reject_types();
95 }
96 
97 static const struct xt_option_entry REJECT_opts[] = {
98 	{.name = "reject-with", .id = O_REJECT_WITH, .type = XTTYPE_STRING},
99 	XTOPT_TABLEEND,
100 };
101 
REJECT_init(struct xt_entry_target * t)102 static void REJECT_init(struct xt_entry_target *t)
103 {
104 	struct ip6t_reject_info *reject = (struct ip6t_reject_info *)t->data;
105 
106 	/* default */
107 	reject->with = IP6T_ICMP6_PORT_UNREACH;
108 
109 }
110 
REJECT_parse(struct xt_option_call * cb)111 static void REJECT_parse(struct xt_option_call *cb)
112 {
113 	struct ip6t_reject_info *reject = cb->data;
114 	unsigned int i;
115 
116 	xtables_option_parse(cb);
117 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
118 		if (!reject_table[i].name)
119 			continue;
120 		if (strncasecmp(reject_table[i].name,
121 		      cb->arg, strlen(cb->arg)) == 0 ||
122 		    strncasecmp(reject_table[i].alias,
123 		      cb->arg, strlen(cb->arg)) == 0) {
124 			reject->with = i;
125 			return;
126 		}
127 	}
128 	xtables_error(PARAMETER_PROBLEM,
129 		"unknown reject type \"%s\"", cb->arg);
130 }
131 
REJECT_print(const void * ip,const struct xt_entry_target * target,int numeric)132 static void REJECT_print(const void *ip, const struct xt_entry_target *target,
133                          int numeric)
134 {
135 	const struct ip6t_reject_info *reject
136 		= (const struct ip6t_reject_info *)target->data;
137 
138 	printf(" reject-with %s", reject_table[reject->with].name);
139 }
140 
REJECT_save(const void * ip,const struct xt_entry_target * target)141 static void REJECT_save(const void *ip, const struct xt_entry_target *target)
142 {
143 	const struct ip6t_reject_info *reject
144 		= (const struct ip6t_reject_info *)target->data;
145 
146 	printf(" --reject-with %s", reject_table[reject->with].name);
147 }
148 
REJECT_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)149 static int REJECT_xlate(struct xt_xlate *xl,
150 			const struct xt_xlate_tg_params *params)
151 {
152 	const struct ip6t_reject_info *reject =
153 		(const struct ip6t_reject_info *)params->target->data;
154 
155 	if (reject->with == IP6T_ICMP6_PORT_UNREACH)
156 		xt_xlate_add(xl, "reject");
157 	else if (reject->with == IP6T_TCP_RESET)
158 		xt_xlate_add(xl, "reject with %s",
159 			     reject_table[reject->with].xlate);
160 	else
161 		xt_xlate_add(xl, "reject with icmpv6 type %s",
162 			     reject_table[reject->with].xlate);
163 
164 	return 1;
165 }
166 
167 static struct xtables_target reject_tg6_reg = {
168 	.name = "REJECT",
169 	.version	= XTABLES_VERSION,
170 	.family		= NFPROTO_IPV6,
171 	.size 		= XT_ALIGN(sizeof(struct ip6t_reject_info)),
172 	.userspacesize 	= XT_ALIGN(sizeof(struct ip6t_reject_info)),
173 	.help		= REJECT_help,
174 	.init		= REJECT_init,
175 	.print		= REJECT_print,
176 	.save		= REJECT_save,
177 	.x6_parse	= REJECT_parse,
178 	.x6_options	= REJECT_opts,
179 	.xlate		= REJECT_xlate,
180 };
181 
_init(void)182 void _init(void)
183 {
184 	xtables_register_target(&reject_tg6_reg);
185 }
186