• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/iptables-1.4.x/extensions/
1/* Shared library add-on to iptables to add ROUTE target support.
2 * Author : Cedric de Launois, <delaunois@info.ucl.ac.be>
3 * v 1.11 2004/11/23
4 */
5
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9#include <getopt.h>
10#include <iptables.h>
11#include <net/if.h>
12#include <sys/socket.h>
13#include <netinet/in.h>
14#include <arpa/inet.h>
15#include <linux/netfilter_ipv4/ip_tables.h>
16#include <linux/netfilter_ipv4/ipt_ROUTE.h>
17
18/* compile IPT_ROUTE_TEE support even if kernel headers are unpatched */
19#ifndef IPT_ROUTE_TEE
20#define IPT_ROUTE_TEE		0x02
21#endif
22
23/* Function which prints out usage message. */
24static void
25help(void)
26{
27	printf(
28"ROUTE target v%s options:\n"
29"    --oif   \tifname \t\tRoute packet through `ifname' network interface\n"
30"    --iif   \tifname \t\tChange packet's incoming interface to `ifname'\n"
31"    --gw    \tip     \t\tRoute packet via this gateway `ip'\n"
32"    --continue\t     \t\tRoute packet and continue traversing the\n"
33"            \t       \t\trules. Not valid with --iif or --tee.\n"
34"    --tee\t  \t\tDuplicate packet, route the duplicate,\n"
35"            \t       \t\tcontinue traversing with original packet.\n"
36"            \t       \t\tNot valid with --iif or --continue.\n"
37"\n",
38"1.11");
39}
40
41static struct option route_opts[] = {
42	{.name = "oif", .has_arg = true, .val = '1' },
43	{.name = "iif", .has_arg = true, .val = '2' },
44	{.name = "gw", .has_arg = true, .val = '3' },
45	{.name = "continue", .has_arg = false, .val = '4' },
46	{.name = "tee", .has_arg = false, .val = '5' },
47	XT_GETOPT_TABLEEND,
48};
49
50/* Initialize the target. */
51static void ROUTE_init(struct xt_entry_target *t)
52{
53	struct ipt_route_target_info *route_info = (struct ipt_route_target_info*)t->data;
54
55	route_info->oif[0] = '\0';
56	route_info->iif[0] = '\0';
57	route_info->gw = 0;
58	route_info->flags = 0;
59}
60
61
62#define IPT_ROUTE_OPT_OIF      0x01
63#define IPT_ROUTE_OPT_IIF      0x02
64#define IPT_ROUTE_OPT_GW       0x04
65#define IPT_ROUTE_OPT_CONTINUE 0x08
66#define IPT_ROUTE_OPT_TEE      0x10
67
68/* Function which parses command options; returns true if it
69   ate an option */
70static int ROUTE_parse(int c, char **argv, int invert, unsigned int *flags,
71      const void *entry, struct xt_entry_target **target)
72{
73	struct ipt_route_target_info *route_info =
74		(struct ipt_route_target_info*)(*target)->data;
75
76	switch (c) {
77	case '1':
78		if (*flags & IPT_ROUTE_OPT_OIF)
79			xtables_error(PARAMETER_PROBLEM,
80				   "Can't specify --oif twice");
81
82		if (*flags & IPT_ROUTE_OPT_IIF)
83			xtables_error(PARAMETER_PROBLEM,
84				   "Can't use --oif and --iif together");
85
86		if (strlen(optarg) > sizeof(route_info->oif) - 1)
87			xtables_error(PARAMETER_PROBLEM,
88				   "Maximum interface name length %u",
89				   sizeof(route_info->oif) - 1);
90
91		strcpy(route_info->oif, optarg);
92		*flags |= IPT_ROUTE_OPT_OIF;
93		break;
94
95	case '2':
96		if (*flags & IPT_ROUTE_OPT_IIF)
97			xtables_error(PARAMETER_PROBLEM,
98				   "Can't specify --iif twice");
99
100		if (*flags & IPT_ROUTE_OPT_OIF)
101			xtables_error(PARAMETER_PROBLEM,
102				   "Can't use --iif and --oif together");
103
104		if (strlen(optarg) > sizeof(route_info->iif) - 1)
105			xtables_error(PARAMETER_PROBLEM,
106				   "Maximum interface name length %u",
107				   sizeof(route_info->iif) - 1);
108
109		strcpy(route_info->iif, optarg);
110		*flags |= IPT_ROUTE_OPT_IIF;
111		break;
112
113	case '3':
114		if (*flags & IPT_ROUTE_OPT_GW)
115			xtables_error(PARAMETER_PROBLEM,
116				   "Can't specify --gw twice");
117
118		if (!inet_aton(optarg, (struct in_addr*)&route_info->gw)) {
119			xtables_error(PARAMETER_PROBLEM,
120				   "Invalid IP address %s",
121				   optarg);
122		}
123
124		*flags |= IPT_ROUTE_OPT_GW;
125		break;
126
127	case '4':
128		if (*flags & IPT_ROUTE_OPT_CONTINUE)
129			xtables_error(PARAMETER_PROBLEM,
130				   "Can't specify --continue twice");
131		if (*flags & IPT_ROUTE_OPT_TEE)
132			xtables_error(PARAMETER_PROBLEM,
133				   "Can't specify --continue AND --tee");
134
135		route_info->flags |= IPT_ROUTE_CONTINUE;
136		*flags |= IPT_ROUTE_OPT_CONTINUE;
137
138		break;
139
140	case '5':
141		if (*flags & IPT_ROUTE_OPT_TEE)
142			xtables_error(PARAMETER_PROBLEM,
143				   "Can't specify --tee twice");
144		if (*flags & IPT_ROUTE_OPT_CONTINUE)
145			xtables_error(PARAMETER_PROBLEM,
146				   "Can't specify --tee AND --continue");
147
148		route_info->flags |= IPT_ROUTE_TEE;
149		*flags |= IPT_ROUTE_OPT_TEE;
150
151		break;
152
153	default:
154		return 0;
155	}
156
157	return 1;
158}
159
160
161static void
162final_check(unsigned int flags)
163{
164	if (!flags)
165		xtables_error(PARAMETER_PROBLEM,
166		           "ROUTE target: oif, iif or gw option required");
167
168	if ((flags & (IPT_ROUTE_OPT_CONTINUE|IPT_ROUTE_OPT_TEE)) && (flags & IPT_ROUTE_OPT_IIF))
169		xtables_error(PARAMETER_PROBLEM,
170			   "ROUTE target: can't continue traversing the rules with iif option");
171}
172
173
174/* Prints out the targinfo. */
175static void
176ROUTE_print(const void *ip, const struct xt_entry_target *target,
177      int numeric)
178{
179	const struct ipt_route_target_info *route_info
180		= (const struct ipt_route_target_info *)target->data;
181
182	printf("ROUTE ");
183
184	if (route_info->oif[0])
185		printf("oif:%s ", route_info->oif);
186
187	if (route_info->iif[0])
188		printf("iif:%s ", route_info->iif);
189
190	if (route_info->gw) {
191		struct in_addr ip_1 = { route_info->gw };
192		printf("gw:%s ", inet_ntoa(ip_1));
193	}
194
195	if (route_info->flags & IPT_ROUTE_CONTINUE)
196		printf("continue");
197
198	if (route_info->flags & IPT_ROUTE_TEE)
199		printf("tee");
200
201}
202
203
204static void ROUTE_save(const void *ip, const struct xt_entry_target *target)
205{
206	const struct ipt_route_target_info *route_info
207		= (const struct ipt_route_target_info *)target->data;
208
209	if (route_info->oif[0])
210		printf("--oif %s ", route_info->oif);
211
212	if (route_info->iif[0])
213		printf("--iif %s ", route_info->iif);
214
215	if (route_info->gw) {
216		struct in_addr ip_1 = { route_info->gw };
217		printf("--gw %s ", inet_ntoa(ip_1));
218	}
219
220	if (route_info->flags & IPT_ROUTE_CONTINUE)
221		printf("--continue ");
222
223	if (route_info->flags & IPT_ROUTE_TEE)
224		printf("--tee ");
225}
226
227
228static struct xtables_target route_target = {
229	.family		= NFPROTO_IPV4,
230	.name		= "ROUTE",
231	.version	= XTABLES_VERSION,
232	.size		= XT_ALIGN(sizeof(struct ipt_route_target_info)),
233	.userspacesize	= XT_ALIGN(sizeof(struct ipt_route_target_info)),
234	.help		= help,
235	.init		= ROUTE_init,
236	.parse		= ROUTE_parse,
237	.final_check	= final_check,
238	.print		= ROUTE_print,
239	.save		= ROUTE_save,
240	.extra_opts	= route_opts
241};
242
243void _init(void)
244{
245	xtables_register_target(&route_target);
246}
247