libipt_REJECT.c revision f7e72d5730420194d6d3e441e881f8d7f217d888
1/* 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	{"echo-reply", "echoreply",
30	 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
31	{"icmp-net-prohibited", "net-prohib",
32	 IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
33	{"icmp-host-prohibited", "host-prohib",
34	 IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
35	{"icmp-packet-filtered", "packet-filtered",
36	 IPT_ICMP_PACKET_FILTERED, "ICMP packet filtered"}
37};
38
39static void
40print_reject_types()
41{
42	unsigned int i;
43
44	printf("Valid reject types:\n");
45
46	for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
47		printf("    %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
48		printf("    %-25s\talias\n", reject_table[i].alias);
49	}
50	printf("\n");
51}
52
53/* Saves the union ipt_targinfo in parsable form to stdout. */
54
55/* Function which prints out usage message. */
56static void
57help(void)
58{
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
67static struct option opts[] = {
68	{ "reject-with", 1, 0, '1' },
69	{ 0 }
70};
71
72/* Allocate and initialize the target. */
73static void
74init(struct ipt_entry_target *t, unsigned int *nfcache)
75{
76	struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data;
77
78	/* default */
79	reject->with = IPT_ICMP_PORT_UNREACHABLE;
80
81	/* Can't cache this */
82	*nfcache |= NFC_UNKNOWN;
83}
84
85/* Function which parses command options; returns true if it
86   ate an option */
87static int
88parse(int c, char **argv, int invert, unsigned int *flags,
89      const struct ipt_entry *entry,
90      struct ipt_entry_target **target)
91{
92	struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data;
93	unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names);
94	unsigned int i;
95
96	switch(c) {
97	case '1':
98		if (check_inverse(optarg, &invert))
99			exit_error(PARAMETER_PROBLEM,
100				   "Unexpected `!' after --reject-with");
101		for (i = 0; i < limit; i++) {
102			if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0)
103			    || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) {
104				reject->with = reject_table[i].with;
105				return 1;
106			}
107		}
108		exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg);
109	default:
110		/* Fall through */
111	}
112	return 0;
113}
114
115/* Final check; nothing. */
116static void final_check(unsigned int flags)
117{
118}
119
120/* Prints out ipt_reject_info. */
121static void
122print(const struct ipt_ip *ip,
123      const struct ipt_entry_target *target,
124      int numeric)
125{
126	const struct ipt_reject_info *reject
127		= (const struct ipt_reject_info *)target->data;
128	unsigned int i;
129
130	for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) {
131		if (reject_table[i].with == reject->with)
132			break;
133	}
134	printf("reject-with %s ", reject_table[i].name);
135}
136
137/* Saves ipt_reject in parsable form to stdout. */
138static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
139{
140	const struct ipt_reject_info *reject
141		= (const struct ipt_reject_info *)target->data;
142
143	printf("--reject-with %s ", reject_table[reject->with].name);
144}
145
146struct iptables_target reject
147= { NULL,
148    "REJECT",
149    NETFILTER_VERSION,
150    sizeof(struct ipt_reject_info),
151    sizeof(struct ipt_reject_info),
152    &help,
153    &init,
154    &parse,
155    &final_check,
156    &print,
157    &save,
158    opts
159};
160
161void _init(void)
162{
163	register_target(&reject);
164}
165