blob: 431695820d6c28311e2dabe8dc9dec2e2863fc14 [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add customized REJECT support.
2 *
3 * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4 */
5#include <stdio.h>
6#include <string.h>
7#include <stdlib.h>
8#include <getopt.h>
9#include <iptables.h>
10#include <linux/netfilter_ipv4/ip_tables.h>
11#include <linux/netfilter_ipv4/ipt_REJECT.h>
12
13struct reject_names {
14 const char *name;
15 const char *alias;
16 enum ipt_reject_with with;
17 const char *desc;
18};
19
20static const struct reject_names reject_table[] = {
Rusty Russell7e53bf92000-03-20 07:03:28 +000021 {"icmp-net-unreachable", "net-unreach",
Marc Bouchere6869a82000-03-20 06:03:29 +000022 IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"},
23 {"icmp-host-unreachable", "host-unreach",
24 IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"},
Marc Bouchere6869a82000-03-20 06:03:29 +000025 {"icmp-proto-unreachable", "proto-unreach",
26 IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"},
Harald Welte30d920a2001-06-16 19:02:25 +000027 {"icmp-port-unreachable", "port-unreach",
28 IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"},
Rusty Russellbd8382b2000-12-18 05:09:52 +000029#if 0
Marc Bouchere6869a82000-03-20 06:03:29 +000030 {"echo-reply", "echoreply",
Rusty Russellf7e72d52000-06-20 19:07:29 +000031 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
Rusty Russellbd8382b2000-12-18 05:09:52 +000032#endif
Rusty Russellf7e72d52000-06-20 19:07:29 +000033 {"icmp-net-prohibited", "net-prohib",
34 IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
35 {"icmp-host-prohibited", "host-prohib",
36 IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
Rusty Russell52e440e2000-07-12 07:30:55 +000037 {"tcp-reset", "tcp-reset",
38 IPT_TCP_RESET, "TCP RST packet"}
Marc Bouchere6869a82000-03-20 06:03:29 +000039};
40
Rusty Russell7e53bf92000-03-20 07:03:28 +000041static void
Marc Bouchere6869a82000-03-20 06:03:29 +000042print_reject_types()
43{
44 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000045
Marc Bouchere6869a82000-03-20 06:03:29 +000046 printf("Valid reject types:\n");
47
48 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
49 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
50 printf(" %-25s\talias\n", reject_table[i].alias);
51 }
52 printf("\n");
53}
54
55/* Saves the union ipt_targinfo in parsable form to stdout. */
56
57/* Function which prints out usage message. */
Rusty Russell7e53bf92000-03-20 07:03:28 +000058static void
Marc Bouchere6869a82000-03-20 06:03:29 +000059help(void)
60{
61 printf(
62"REJECT options:\n"
63"--reject-with type drop input packet and send back\n"
64" a reply packet according to type:\n");
65
66 print_reject_types();
67}
68
69static struct option opts[] = {
70 { "reject-with", 1, 0, '1' },
71 { 0 }
72};
73
74/* Allocate and initialize the target. */
75static void
76init(struct ipt_entry_target *t, unsigned int *nfcache)
77{
78 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data;
Rusty Russell7e53bf92000-03-20 07:03:28 +000079
Marc Bouchere6869a82000-03-20 06:03:29 +000080 /* default */
81 reject->with = IPT_ICMP_PORT_UNREACHABLE;
Rusty Russell7e53bf92000-03-20 07:03:28 +000082
Marc Bouchere6869a82000-03-20 06:03:29 +000083 /* Can't cache this */
84 *nfcache |= NFC_UNKNOWN;
85}
86
87/* Function which parses command options; returns true if it
88 ate an option */
89static int
90parse(int c, char **argv, int invert, unsigned int *flags,
91 const struct ipt_entry *entry,
92 struct ipt_entry_target **target)
Rusty Russell7e53bf92000-03-20 07:03:28 +000093{
Marc Bouchere6869a82000-03-20 06:03:29 +000094 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data;
95 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names);
96 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000097
Marc Bouchere6869a82000-03-20 06:03:29 +000098 switch(c) {
99 case '1':
100 if (check_inverse(optarg, &invert))
Rusty Russell7e53bf92000-03-20 07:03:28 +0000101 exit_error(PARAMETER_PROBLEM,
Marc Bouchere6869a82000-03-20 06:03:29 +0000102 "Unexpected `!' after --reject-with");
103 for (i = 0; i < limit; i++) {
104 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0)
105 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) {
106 reject->with = reject_table[i].with;
107 return 1;
108 }
109 }
Rusty Russellbd8382b2000-12-18 05:09:52 +0000110 /* This due to be dropped late in 2.4 pre-release cycle --RR */
111 if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0
112 || strncasecmp("echoreply", optarg, strlen(optarg)) == 0)
113 fprintf(stderr, "--reject-with echo-reply no longer"
114 " supported\n");
Marc Bouchere6869a82000-03-20 06:03:29 +0000115 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg);
116 default:
117 /* Fall through */
Marc Boucher6e9bfc72002-01-19 12:48:05 +0000118 break;
Marc Bouchere6869a82000-03-20 06:03:29 +0000119 }
120 return 0;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000121}
Marc Bouchere6869a82000-03-20 06:03:29 +0000122
123/* Final check; nothing. */
124static void final_check(unsigned int flags)
125{
126}
127
128/* Prints out ipt_reject_info. */
Rusty Russell7e53bf92000-03-20 07:03:28 +0000129static void
Marc Bouchere6869a82000-03-20 06:03:29 +0000130print(const struct ipt_ip *ip,
Rusty Russell7e53bf92000-03-20 07:03:28 +0000131 const struct ipt_entry_target *target,
Marc Bouchere6869a82000-03-20 06:03:29 +0000132 int numeric)
133{
Rusty Russell7e53bf92000-03-20 07:03:28 +0000134 const struct ipt_reject_info *reject
Marc Bouchere6869a82000-03-20 06:03:29 +0000135 = (const struct ipt_reject_info *)target->data;
136 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000137
Marc Bouchere6869a82000-03-20 06:03:29 +0000138 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
139 if (reject_table[i].with == reject->with)
140 break;
141 }
142 printf("reject-with %s ", reject_table[i].name);
143}
144
145/* Saves ipt_reject in parsable form to stdout. */
146static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
147{
Rusty Russell7e53bf92000-03-20 07:03:28 +0000148 const struct ipt_reject_info *reject
Marc Bouchere6869a82000-03-20 06:03:29 +0000149 = (const struct ipt_reject_info *)target->data;
Harald Welte97b3fde2001-05-12 05:22:18 +0000150 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000151
Harald Welte97b3fde2001-05-12 05:22:18 +0000152 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++)
153 if (reject_table[i].with == reject->with)
154 break;
155
156 printf("--reject-with %s ", reject_table[i].name);
Marc Bouchere6869a82000-03-20 06:03:29 +0000157}
158
Harald Welte3efb6ea2001-08-06 18:50:21 +0000159static
Marc Bouchere6869a82000-03-20 06:03:29 +0000160struct iptables_target reject
161= { NULL,
162 "REJECT",
163 NETFILTER_VERSION,
Rusty Russell73f72f52000-07-03 10:17:57 +0000164 IPT_ALIGN(sizeof(struct ipt_reject_info)),
165 IPT_ALIGN(sizeof(struct ipt_reject_info)),
Marc Bouchere6869a82000-03-20 06:03:29 +0000166 &help,
167 &init,
168 &parse,
169 &final_check,
170 &print,
171 &save,
172 opts
173};
174
175void _init(void)
176{
177 register_target(&reject);
178}