blob: 000096ec4a0b5a6654c18ab91af72c304aef4e21 [file] [log] [blame]
Harald Weltec8af1fd2001-07-23 02:15:09 +00001/* Shared library add-on to iptables to add customized REJECT support.
2 *
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>
12#include <ip6tables.h>
13#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
54/* Saves the union ipt_targinfo in parsable form to stdout. */
55
56/* Function which prints out usage message. */
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000057static void REJECT_help(void)
Harald Weltec8af1fd2001-07-23 02:15:09 +000058{
59 printf(
60"REJECT options:\n"
61"--reject-with type drop input packet and send back\n"
62" a reply packet according to type:\n");
63
64 print_reject_types();
65}
66
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000067static const struct option REJECT_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000068 { "reject-with", 1, NULL, '1' },
Max Kellermann9ee386a2008-01-29 13:48:05 +000069 { .name = NULL }
Harald Weltec8af1fd2001-07-23 02:15:09 +000070};
71
72/* Allocate and initialize the target. */
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000073static void REJECT_init(struct xt_entry_target *t)
Harald Weltec8af1fd2001-07-23 02:15:09 +000074{
75 struct ip6t_reject_info *reject = (struct ip6t_reject_info *)t->data;
76
77 /* default */
78 reject->with = IP6T_ICMP6_PORT_UNREACH;
79
Harald Weltec8af1fd2001-07-23 02:15:09 +000080}
81
82/* Function which parses command options; returns true if it
83 ate an option */
Jan Engelhardt4d150eb2007-10-04 16:29:39 +000084static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags,
85 const void *entry, struct xt_entry_target **target)
Harald Weltec8af1fd2001-07-23 02:15:09 +000086{
87 struct ip6t_reject_info *reject =
88 (struct ip6t_reject_info *)(*target)->data;
89 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names);
90 unsigned int i;
91
92 switch(c) {
93 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000094 if (check_inverse(optarg, &invert, NULL, 0))
Harald Weltec8af1fd2001-07-23 02:15:09 +000095 exit_error(PARAMETER_PROBLEM,
96 "Unexpected `!' after --reject-with");
97 for (i = 0; i < limit; i++) {
98 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0)
99 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) {
100 reject->with = reject_table[i].with;
101 return 1;
102 }
103 }
104 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg);
105 default:
106 /* Fall through */
Fabrice MARIEae31bb62002-06-14 07:38:16 +0000107 break;
Harald Weltec8af1fd2001-07-23 02:15:09 +0000108 }
109 return 0;
110}
111
Harald Weltec8af1fd2001-07-23 02:15:09 +0000112/* Prints out ipt_reject_info. */
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000113static void REJECT_print(const void *ip, const struct xt_entry_target *target,
114 int numeric)
Harald Weltec8af1fd2001-07-23 02:15:09 +0000115{
116 const struct ip6t_reject_info *reject
117 = (const struct ip6t_reject_info *)target->data;
118 unsigned int i;
119
120 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
121 if (reject_table[i].with == reject->with)
122 break;
123 }
124 printf("reject-with %s ", reject_table[i].name);
125}
126
127/* Saves ipt_reject in parsable form to stdout. */
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000128static void REJECT_save(const void *ip, const struct xt_entry_target *target)
Harald Weltec8af1fd2001-07-23 02:15:09 +0000129{
130 const struct ip6t_reject_info *reject
131 = (const struct ip6t_reject_info *)target->data;
132 unsigned int i;
133
134 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++)
135 if (reject_table[i].with == reject->with)
136 break;
137
138 printf("--reject-with %s ", reject_table[i].name);
139}
140
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000141static struct ip6tables_target reject_target6 = {
Harald Welte02aa7332005-02-01 15:38:20 +0000142 .name = "REJECT",
143 .version = IPTABLES_VERSION,
144 .size = IP6T_ALIGN(sizeof(struct ip6t_reject_info)),
145 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_reject_info)),
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000146 .help = REJECT_help,
147 .init = REJECT_init,
148 .parse = REJECT_parse,
149 .print = REJECT_print,
150 .save = REJECT_save,
151 .extra_opts = REJECT_opts,
Harald Weltec8af1fd2001-07-23 02:15:09 +0000152};
153
154void _init(void)
155{
Jan Engelhardt4d150eb2007-10-04 16:29:39 +0000156 register_target6(&reject_target6);
Harald Weltec8af1fd2001-07-23 02:15:09 +0000157}