blob: e13d4b1e5702d0e69e44a0b678042269852531a5 [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 Russellf7e72d52000-06-20 19:07:29 +000030 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"}
Marc Bouchere6869a82000-03-20 06:03:29 +000037};
38
Rusty Russell7e53bf92000-03-20 07:03:28 +000039static void
Marc Bouchere6869a82000-03-20 06:03:29 +000040print_reject_types()
41{
42 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000043
Marc Bouchere6869a82000-03-20 06:03:29 +000044 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. */
Rusty Russell7e53bf92000-03-20 07:03:28 +000056static void
Marc Bouchere6869a82000-03-20 06:03:29 +000057help(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;
Rusty Russell7e53bf92000-03-20 07:03:28 +000077
Marc Bouchere6869a82000-03-20 06:03:29 +000078 /* default */
79 reject->with = IPT_ICMP_PORT_UNREACHABLE;
Rusty Russell7e53bf92000-03-20 07:03:28 +000080
Marc Bouchere6869a82000-03-20 06:03:29 +000081 /* 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)
Rusty Russell7e53bf92000-03-20 07:03:28 +000091{
Marc Bouchere6869a82000-03-20 06:03:29 +000092 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;
Rusty Russell7e53bf92000-03-20 07:03:28 +000095
Marc Bouchere6869a82000-03-20 06:03:29 +000096 switch(c) {
97 case '1':
98 if (check_inverse(optarg, &invert))
Rusty Russell7e53bf92000-03-20 07:03:28 +000099 exit_error(PARAMETER_PROBLEM,
Marc Bouchere6869a82000-03-20 06:03:29 +0000100 "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;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000113}
Marc Bouchere6869a82000-03-20 06:03:29 +0000114
115/* Final check; nothing. */
116static void final_check(unsigned int flags)
117{
118}
119
120/* Prints out ipt_reject_info. */
Rusty Russell7e53bf92000-03-20 07:03:28 +0000121static void
Marc Bouchere6869a82000-03-20 06:03:29 +0000122print(const struct ipt_ip *ip,
Rusty Russell7e53bf92000-03-20 07:03:28 +0000123 const struct ipt_entry_target *target,
Marc Bouchere6869a82000-03-20 06:03:29 +0000124 int numeric)
125{
Rusty Russell7e53bf92000-03-20 07:03:28 +0000126 const struct ipt_reject_info *reject
Marc Bouchere6869a82000-03-20 06:03:29 +0000127 = (const struct ipt_reject_info *)target->data;
128 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000129
Marc Bouchere6869a82000-03-20 06:03:29 +0000130 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{
Rusty Russell7e53bf92000-03-20 07:03:28 +0000140 const struct ipt_reject_info *reject
Marc Bouchere6869a82000-03-20 06:03:29 +0000141 = (const struct ipt_reject_info *)target->data;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000142
Marc Bouchere6869a82000-03-20 06:03:29 +0000143 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),
Rusty Russelledf14cf2000-04-19 11:26:44 +0000151 sizeof(struct ipt_reject_info),
Marc Bouchere6869a82000-03-20 06:03:29 +0000152 &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}