blob: e33658733bf5b8a223a5667ce9223bacd6b06462 [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[] = {
21 {"icmp-net-unreachable", "net-unreach",
22 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"},
29 {"tcp-reset", "rst",
30 IPT_TCP_RESET, "for TCP only: faked TCP RST"},
31 {"echo-reply", "echoreply",
32 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
33};
34
35static void
36print_reject_types()
37{
38 unsigned int i;
39
40 printf("Valid reject types:\n");
41
42 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
43 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
44 printf(" %-25s\talias\n", reject_table[i].alias);
45 }
46 printf("\n");
47}
48
49/* Saves the union ipt_targinfo in parsable form to stdout. */
50
51/* Function which prints out usage message. */
52static void
53help(void)
54{
55 printf(
56"REJECT options:\n"
57"--reject-with type drop input packet and send back\n"
58" a reply packet according to type:\n");
59
60 print_reject_types();
61}
62
63static struct option opts[] = {
64 { "reject-with", 1, 0, '1' },
65 { 0 }
66};
67
68/* Allocate and initialize the target. */
69static void
70init(struct ipt_entry_target *t, unsigned int *nfcache)
71{
72 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data;
73
74 /* default */
75 reject->with = IPT_ICMP_PORT_UNREACHABLE;
76
77 /* Can't cache this */
78 *nfcache |= NFC_UNKNOWN;
79}
80
81/* Function which parses command options; returns true if it
82 ate an option */
83static int
84parse(int c, char **argv, int invert, unsigned int *flags,
85 const struct ipt_entry *entry,
86 struct ipt_entry_target **target)
87{
88 struct ipt_reject_info *reject = (struct ipt_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':
94 if (check_inverse(optarg, &invert))
95 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 */
107 }
108 return 0;
109}
110
111/* Final check; nothing. */
112static void final_check(unsigned int flags)
113{
114}
115
116/* Prints out ipt_reject_info. */
117static void
118print(const struct ipt_ip *ip,
119 const struct ipt_entry_target *target,
120 int numeric)
121{
122 const struct ipt_reject_info *reject
123 = (const struct ipt_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
133/* Saves ipt_reject in parsable form to stdout. */
134static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
135{
136 const struct ipt_reject_info *reject
137 = (const struct ipt_reject_info *)target->data;
138
139 printf("--reject-with %s ", reject_table[reject->with].name);
140}
141
142struct iptables_target reject
143= { NULL,
144 "REJECT",
145 NETFILTER_VERSION,
146 sizeof(struct ipt_reject_info),
147 &help,
148 &init,
149 &parse,
150 &final_check,
151 &print,
152 &save,
153 opts
154};
155
156void _init(void)
157{
158 register_target(&reject);
159}