blob: 0e2120210f389540b89bba5d18b9bf21e810e89a [file] [log] [blame]
Jan Engelhardtddac6c52008-09-01 14:22:19 +02001/* Shared library add-on to ip6tables to add customized REJECT support.
Harald Weltec8af1fd2001-07-23 02:15:09 +00002 *
3 * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4 *
5 * ported to IPv6 by Harald Welte <laforge@gnumonks.org>
6 *
7 */
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <getopt.h>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +010012#include <xtables.h>
Harald Weltec8af1fd2001-07-23 02:15:09 +000013#include <linux/netfilter_ipv6/ip6_tables.h>
14#include <linux/netfilter_ipv6/ip6t_REJECT.h>
15
16struct reject_names {
17 const char *name;
18 const char *alias;
19 enum ip6t_reject_with with;
20 const char *desc;
21};
22
23static const struct reject_names reject_table[] = {
24 {"icmp6-no-route", "no-route",
25 IP6T_ICMP6_NO_ROUTE, "ICMPv6 no route"},
26 {"icmp6-adm-prohibited", "adm-prohibited",
27 IP6T_ICMP6_ADM_PROHIBITED, "ICMPv6 administratively prohibited"},
28#if 0
29 {"icmp6-not-neighbor", "not-neighbor"},
30 IP6T_ICMP6_NOT_NEIGHBOR, "ICMPv6 not a neighbor"},
31#endif
32 {"icmp6-addr-unreachable", "addr-unreach",
33 IP6T_ICMP6_ADDR_UNREACH, "ICMPv6 address unreachable"},
34 {"icmp6-port-unreachable", "port-unreach",
35 IP6T_ICMP6_PORT_UNREACH, "ICMPv6 port unreachable"},
36 {"tcp-reset", "tcp-reset",
37 IP6T_TCP_RESET, "TCP RST packet"}
38};
39
40static void
Patrick McHardy500f4832007-09-08 15:59:04 +000041print_reject_types(void)
Harald Weltec8af1fd2001-07-23 02:15:09 +000042{
43 unsigned int i;
44
45 printf("Valid reject types:\n");
46
47 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
48 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
49 printf(" %-25s\talias\n", reject_table[i].alias);
50 }
51 printf("\n");
52}
53
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000054static void REJECT_help(void)
Harald Weltec8af1fd2001-07-23 02:15:09 +000055{
56 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020057"REJECT target options:\n"
Harald Weltec8af1fd2001-07-23 02:15:09 +000058"--reject-with type drop input packet and send back\n"
59" a reply packet according to type:\n");
60
61 print_reject_types();
62}
63
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000064static const struct option REJECT_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000065 { "reject-with", 1, NULL, '1' },
Max Kellermann9ee386a2008-01-29 13:48:05 +000066 { .name = NULL }
Harald Weltec8af1fd2001-07-23 02:15:09 +000067};
68
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000069static void REJECT_init(struct xt_entry_target *t)
Harald Weltec8af1fd2001-07-23 02:15:09 +000070{
71 struct ip6t_reject_info *reject = (struct ip6t_reject_info *)t->data;
72
73 /* default */
74 reject->with = IP6T_ICMP6_PORT_UNREACH;
75
Harald Weltec8af1fd2001-07-23 02:15:09 +000076}
77
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000078static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags,
79 const void *entry, struct xt_entry_target **target)
Harald Weltec8af1fd2001-07-23 02:15:09 +000080{
81 struct ip6t_reject_info *reject =
82 (struct ip6t_reject_info *)(*target)->data;
83 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names);
84 unsigned int i;
85
86 switch(c) {
87 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000088 if (check_inverse(optarg, &invert, NULL, 0))
Harald Weltec8af1fd2001-07-23 02:15:09 +000089 exit_error(PARAMETER_PROBLEM,
90 "Unexpected `!' after --reject-with");
91 for (i = 0; i < limit; i++) {
92 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0)
93 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) {
94 reject->with = reject_table[i].with;
95 return 1;
96 }
97 }
98 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg);
99 default:
100 /* Fall through */
Fabrice MARIEae31bb62002-06-14 07:38:16 +0000101 break;
Harald Weltec8af1fd2001-07-23 02:15:09 +0000102 }
103 return 0;
104}
105
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000106static void REJECT_print(const void *ip, const struct xt_entry_target *target,
107 int numeric)
Harald Weltec8af1fd2001-07-23 02:15:09 +0000108{
109 const struct ip6t_reject_info *reject
110 = (const struct ip6t_reject_info *)target->data;
111 unsigned int i;
112
113 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
114 if (reject_table[i].with == reject->with)
115 break;
116 }
117 printf("reject-with %s ", reject_table[i].name);
118}
119
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000120static void REJECT_save(const void *ip, const struct xt_entry_target *target)
Harald Weltec8af1fd2001-07-23 02:15:09 +0000121{
122 const struct ip6t_reject_info *reject
123 = (const struct ip6t_reject_info *)target->data;
124 unsigned int i;
125
126 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++)
127 if (reject_table[i].with == reject->with)
128 break;
129
130 printf("--reject-with %s ", reject_table[i].name);
131}
132
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200133static struct xtables_target reject_tg6_reg = {
Harald Welte02aa7332005-02-01 15:38:20 +0000134 .name = "REJECT",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200135 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100136 .family = NFPROTO_IPV6,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200137 .size = XT_ALIGN(sizeof(struct ip6t_reject_info)),
138 .userspacesize = XT_ALIGN(sizeof(struct ip6t_reject_info)),
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000139 .help = REJECT_help,
140 .init = REJECT_init,
141 .parse = REJECT_parse,
142 .print = REJECT_print,
143 .save = REJECT_save,
144 .extra_opts = REJECT_opts,
Harald Weltec8af1fd2001-07-23 02:15:09 +0000145};
146
147void _init(void)
148{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200149 xtables_register_target(&reject_tg6_reg);
Harald Weltec8af1fd2001-07-23 02:15:09 +0000150}