libipt_REJECT.c revision a1ce9f9b8265a8c28facd52f4e3c0465dce2b9f0
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};
32
33static void
34print_reject_types()
35{
36	unsigned int i;
37
38	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. */
50static void
51help(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;
71
72	/* default */
73	reject->with = IPT_ICMP_PORT_UNREACHABLE;
74
75	/* 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)
85{
86	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;
89
90	switch(c) {
91	case '1':
92		if (check_inverse(optarg, &invert))
93			exit_error(PARAMETER_PROBLEM,
94				   "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;
107}
108
109/* Final check; nothing. */
110static void final_check(unsigned int flags)
111{
112}
113
114/* Prints out ipt_reject_info. */
115static void
116print(const struct ipt_ip *ip,
117      const struct ipt_entry_target *target,
118      int numeric)
119{
120	const struct ipt_reject_info *reject
121		= (const struct ipt_reject_info *)target->data;
122	unsigned int i;
123
124	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{
134	const struct ipt_reject_info *reject
135		= (const struct ipt_reject_info *)target->data;
136
137	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),
145    &help,
146    &init,
147    &parse,
148    &final_check,
149    &print,
150    &save,
151    opts
152};
153
154void _init(void)
155{
156	register_target(&reject);
157}
158