blob: 2c0b85b75b027fc73018010fdd33c84857252947 [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"},
25 {"icmp-port-unreachable", "port-unreach",
26 IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"},
27 {"icmp-proto-unreachable", "proto-unreach",
28 IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"},
Marc Bouchere6869a82000-03-20 06:03:29 +000029 {"echo-reply", "echoreply",
Rusty Russella1ce9f92000-03-24 08:39:16 +000030 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}
Marc Bouchere6869a82000-03-20 06:03:29 +000031};
32
Rusty Russell7e53bf92000-03-20 07:03:28 +000033static void
Marc Bouchere6869a82000-03-20 06:03:29 +000034print_reject_types()
35{
36 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000037
Marc Bouchere6869a82000-03-20 06:03:29 +000038 printf("Valid reject types:\n");
39
40 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
41 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
42 printf(" %-25s\talias\n", reject_table[i].alias);
43 }
44 printf("\n");
45}
46
47/* Saves the union ipt_targinfo in parsable form to stdout. */
48
49/* Function which prints out usage message. */
Rusty Russell7e53bf92000-03-20 07:03:28 +000050static void
Marc Bouchere6869a82000-03-20 06:03:29 +000051help(void)
52{
53 printf(
54"REJECT options:\n"
55"--reject-with type drop input packet and send back\n"
56" a reply packet according to type:\n");
57
58 print_reject_types();
59}
60
61static struct option opts[] = {
62 { "reject-with", 1, 0, '1' },
63 { 0 }
64};
65
66/* Allocate and initialize the target. */
67static void
68init(struct ipt_entry_target *t, unsigned int *nfcache)
69{
70 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data;
Rusty Russell7e53bf92000-03-20 07:03:28 +000071
Marc Bouchere6869a82000-03-20 06:03:29 +000072 /* default */
73 reject->with = IPT_ICMP_PORT_UNREACHABLE;
Rusty Russell7e53bf92000-03-20 07:03:28 +000074
Marc Bouchere6869a82000-03-20 06:03:29 +000075 /* Can't cache this */
76 *nfcache |= NFC_UNKNOWN;
77}
78
79/* Function which parses command options; returns true if it
80 ate an option */
81static int
82parse(int c, char **argv, int invert, unsigned int *flags,
83 const struct ipt_entry *entry,
84 struct ipt_entry_target **target)
Rusty Russell7e53bf92000-03-20 07:03:28 +000085{
Marc Bouchere6869a82000-03-20 06:03:29 +000086 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data;
87 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names);
88 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000089
Marc Bouchere6869a82000-03-20 06:03:29 +000090 switch(c) {
91 case '1':
92 if (check_inverse(optarg, &invert))
Rusty Russell7e53bf92000-03-20 07:03:28 +000093 exit_error(PARAMETER_PROBLEM,
Marc Bouchere6869a82000-03-20 06:03:29 +000094 "Unexpected `!' after --reject-with");
95 for (i = 0; i < limit; i++) {
96 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0)
97 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) {
98 reject->with = reject_table[i].with;
99 return 1;
100 }
101 }
102 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg);
103 default:
104 /* Fall through */
105 }
106 return 0;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000107}
Marc Bouchere6869a82000-03-20 06:03:29 +0000108
109/* Final check; nothing. */
110static void final_check(unsigned int flags)
111{
112}
113
114/* Prints out ipt_reject_info. */
Rusty Russell7e53bf92000-03-20 07:03:28 +0000115static void
Marc Bouchere6869a82000-03-20 06:03:29 +0000116print(const struct ipt_ip *ip,
Rusty Russell7e53bf92000-03-20 07:03:28 +0000117 const struct ipt_entry_target *target,
Marc Bouchere6869a82000-03-20 06:03:29 +0000118 int numeric)
119{
Rusty Russell7e53bf92000-03-20 07:03:28 +0000120 const struct ipt_reject_info *reject
Marc Bouchere6869a82000-03-20 06:03:29 +0000121 = (const struct ipt_reject_info *)target->data;
122 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000123
Marc Bouchere6869a82000-03-20 06:03:29 +0000124 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
125 if (reject_table[i].with == reject->with)
126 break;
127 }
128 printf("reject-with %s ", reject_table[i].name);
129}
130
131/* Saves ipt_reject in parsable form to stdout. */
132static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
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;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000136
Marc Bouchere6869a82000-03-20 06:03:29 +0000137 printf("--reject-with %s ", reject_table[reject->with].name);
138}
139
140struct iptables_target reject
141= { NULL,
142 "REJECT",
143 NETFILTER_VERSION,
144 sizeof(struct ipt_reject_info),
Rusty Russelledf14cf2000-04-19 11:26:44 +0000145 sizeof(struct ipt_reject_info),
Marc Bouchere6869a82000-03-20 06:03:29 +0000146 &help,
147 &init,
148 &parse,
149 &final_check,
150 &print,
151 &save,
152 opts
153};
154
155void _init(void)
156{
157 register_target(&reject);
158}