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