1ddac6c5bc636003d664d25c08ea3fe176565096cJan Engelhardt/* Shared library add-on to ip6tables to add customized REJECT support.
2c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte *
3c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte *
5c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte * ported to IPv6 by Harald Welte <laforge@gnumonks.org>
6c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte *
7c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte */
8c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte#include <stdio.h>
9c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte#include <string.h>
105d9678ad3eabc34ac40dfe055d7f6a8e44445a5aJan Engelhardt#include <xtables.h>
11c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte#include <linux/netfilter_ipv6/ip6t_REJECT.h>
12c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
13c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Weltestruct reject_names {
14c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	const char *name;
15c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	const char *alias;
16c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	enum ip6t_reject_with with;
17c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	const char *desc;
18c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte};
19c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
20b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardtenum {
21b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	O_REJECT_WITH = 0,
22b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt};
23b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt
24c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Weltestatic const struct reject_names reject_table[] = {
25c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"icmp6-no-route", "no-route",
26c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_ICMP6_NO_ROUTE, "ICMPv6 no route"},
27c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"icmp6-adm-prohibited", "adm-prohibited",
28c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_ICMP6_ADM_PROHIBITED, "ICMPv6 administratively prohibited"},
29c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte#if 0
30c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"icmp6-not-neighbor", "not-neighbor"},
31c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_ICMP6_NOT_NEIGHBOR, "ICMPv6 not a neighbor"},
32c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte#endif
33c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"icmp6-addr-unreachable", "addr-unreach",
34c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_ICMP6_ADDR_UNREACH, "ICMPv6 address unreachable"},
35c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"icmp6-port-unreachable", "port-unreach",
36c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_ICMP6_PORT_UNREACH, "ICMPv6 port unreachable"},
37c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	{"tcp-reset", "tcp-reset",
38c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		IP6T_TCP_RESET, "TCP RST packet"}
39c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte};
40c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
41c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Weltestatic void
42500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardyprint_reject_types(void)
43c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
44c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	unsigned int i;
45c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
46c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	printf("Valid reject types:\n");
47c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
482c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
49c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		printf("    %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
50c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		printf("    %-25s\talias\n", reject_table[i].alias);
51c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	}
52c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	printf("\n");
53c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
54c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
554d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardtstatic void REJECT_help(void)
56c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
57c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	printf(
588b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"REJECT target options:\n"
59c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte"--reject-with type              drop input packet and send back\n"
60c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte"                                a reply packet according to type:\n");
61c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
62c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	print_reject_types();
63c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
64c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
65b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardtstatic const struct xt_option_entry REJECT_opts[] = {
66b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	{.name = "reject-with", .id = O_REJECT_WITH, .type = XTTYPE_STRING},
67b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	XTOPT_TABLEEND,
68c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte};
69c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
704d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardtstatic void REJECT_init(struct xt_entry_target *t)
71c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
72c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	struct ip6t_reject_info *reject = (struct ip6t_reject_info *)t->data;
73c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
74c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	/* default */
75c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	reject->with = IP6T_ICMP6_PORT_UNREACH;
76c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
77c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
78c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
79b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardtstatic void REJECT_parse(struct xt_option_call *cb)
80c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
81b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	struct ip6t_reject_info *reject = cb->data;
82c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	unsigned int i;
83c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
84b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	xtables_option_parse(cb);
85b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
86b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		if (strncasecmp(reject_table[i].name,
87b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		      cb->arg, strlen(cb->arg)) == 0 ||
88b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		    strncasecmp(reject_table[i].alias,
89b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		      cb->arg, strlen(cb->arg)) == 0) {
90b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt			reject->with = reject_table[i].with;
91b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt			return;
92b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		}
93b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	xtables_error(PARAMETER_PROBLEM,
94b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt		"unknown reject type \"%s\"", cb->arg);
95c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
96c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
974d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardtstatic void REJECT_print(const void *ip, const struct xt_entry_target *target,
984d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardt                         int numeric)
99c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
100c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	const struct ip6t_reject_info *reject
101c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		= (const struct ip6t_reject_info *)target->data;
102c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	unsigned int i;
103c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
1042c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
105c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		if (reject_table[i].with == reject->with)
106c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte			break;
10773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" reject-with %s", reject_table[i].name);
108c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
109c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
1104d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardtstatic void REJECT_save(const void *ip, const struct xt_entry_target *target)
111c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
112c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	const struct ip6t_reject_info *reject
113c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		= (const struct ip6t_reject_info *)target->data;
114c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte	unsigned int i;
115c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
1162c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
117c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte		if (reject_table[i].with == reject->with)
118c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte			break;
119c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
12073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --reject-with %s", reject_table[i].name);
121c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
122c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
1238b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_target reject_tg6_reg = {
12402aa73312d6078b6de26757d5a558e0085ec20b5Harald Welte	.name = "REJECT",
1258b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
12603d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	.family		= NFPROTO_IPV6,
1278b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.size 		= XT_ALIGN(sizeof(struct ip6t_reject_info)),
1288b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.userspacesize 	= XT_ALIGN(sizeof(struct ip6t_reject_info)),
1294d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardt	.help		= REJECT_help,
1304d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardt	.init		= REJECT_init,
1314d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardt	.print		= REJECT_print,
1324d150eb5934fd4343b5fac2419c994e2bf97a96cJan Engelhardt	.save		= REJECT_save,
133b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	.x6_parse	= REJECT_parse,
134b313d8f3f78c62cce930728bc9163ecf942c22e8Jan Engelhardt	.x6_options	= REJECT_opts,
135c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte};
136c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte
137c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Weltevoid _init(void)
138c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte{
1398b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	xtables_register_target(&reject_tg6_reg);
140c8af1fd0a9b8e7e39626c7d66ade0ddc93f25fbeHarald Welte}
141