K2.6 patches and update.
[tomato.git] / release / src / router / iptables / extensions / libip6t_ROUTE.c
blobfb3528974a9e14f55652da3e4df398d787503b79
1 /* Shared library add-on to iptables to add ROUTE v6 target support.
2 * Author : Cedric de Launois, <delaunois@info.ucl.ac.be>
3 * v 1.1 2004/11/23
4 */
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <getopt.h>
10 #include <net/if.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <arpa/inet.h>
15 #include <ip6tables.h>
16 #include <linux/netfilter_ipv6/ip6_tables.h>
17 #include <linux/netfilter_ipv6/ip6t_ROUTE.h>
19 #ifndef XTABLES_VERSION
20 #define XTABLES_VERSION IPTABLES_VERSION
21 #endif
23 /* compile IP6T_ROUTE_TEE support even if kernel headers are unpatched */
24 #ifndef IP6T_ROUTE_TEE
25 #define IP6T_ROUTE_TEE 0x02
26 #endif
28 /* Function which prints out usage message. */
29 static void
30 help(void)
32 printf(
33 "ROUTE target v%s options:\n"
34 " --oif \tifname \t\tRoute packet through `ifname' network interface\n"
35 " --iif \tifname \t\tChange packet's incoming interface to `ifname'\n"
36 " --gw \tip \t\tRoute packet via this gateway `ip'\n"
37 " --continue\t \t\tRoute packet and continue traversing the\n"
38 " \t \t\trules. Not valid with --iif or --tee.\n"
39 " --tee\t \t\tDuplicate packet, route the duplicate,\n"
40 " \t \t\tcontinue traversing with original packet.\n"
41 " \t \t\tNot valid with --iif or --continue.\n"
42 "\n",
43 "1.11");
46 static struct option opts[] = {
47 { "oif", 1, 0, '1' },
48 { "iif", 1, 0, '2' },
49 { "gw", 1, 0, '3' },
50 { "continue", 0, 0, '4' },
51 { "tee", 0, 0, '5' },
52 { 0 }
55 /* Initialize the target. */
56 static void
57 #ifdef _XTABLES_H
58 init(struct xt_entry_target *t)
59 #else
60 init(struct ip6t_entry_target *t, unsigned int *nfcache)
61 #endif
63 struct ip6t_route_target_info *route_info =
64 (struct ip6t_route_target_info*)t->data;
66 route_info->oif[0] = '\0';
67 route_info->iif[0] = '\0';
68 route_info->gw[0] = 0;
69 route_info->gw[1] = 0;
70 route_info->gw[2] = 0;
71 route_info->gw[3] = 0;
72 route_info->flags = 0;
76 #define IP6T_ROUTE_OPT_OIF 0x01
77 #define IP6T_ROUTE_OPT_IIF 0x02
78 #define IP6T_ROUTE_OPT_GW 0x04
79 #define IP6T_ROUTE_OPT_CONTINUE 0x08
80 #define IP6T_ROUTE_OPT_TEE 0x10
82 /* Function which parses command options; returns true if it
83 ate an option */
84 static int
85 parse(int c, char **argv, int invert, unsigned int *flags,
86 #ifdef _XTABLES_H
87 const void *entry, struct xt_entry_target **target)
88 #else
89 const struct ip6t_entry *entry, struct ip6t_entry_target **target)
90 #endif
92 struct ip6t_route_target_info *route_info =
93 (struct ip6t_route_target_info*)(*target)->data;
95 switch (c) {
96 case '1':
97 if (*flags & IP6T_ROUTE_OPT_OIF)
98 exit_error(PARAMETER_PROBLEM,
99 "Can't specify --oif twice");
101 if (check_inverse(optarg, &invert, NULL, 0))
102 exit_error(PARAMETER_PROBLEM,
103 "Unexpected `!' after --oif");
105 if (strlen(optarg) > sizeof(route_info->oif) - 1)
106 exit_error(PARAMETER_PROBLEM,
107 "Maximum interface name length %u",
108 sizeof(route_info->oif) - 1);
110 strcpy(route_info->oif, optarg);
111 *flags |= IP6T_ROUTE_OPT_OIF;
112 break;
114 case '2':
115 exit_error(PARAMETER_PROBLEM,
116 "--iif option not implemented");
117 break;
119 case '3':
120 if (*flags & IP6T_ROUTE_OPT_GW)
121 exit_error(PARAMETER_PROBLEM,
122 "Can't specify --gw twice");
124 if (check_inverse(optarg, &invert, NULL, 0))
125 exit_error(PARAMETER_PROBLEM,
126 "Unexpected `!' after --gw");
128 if (!inet_pton(AF_INET6, optarg, (struct in6_addr*)&route_info->gw)) {
129 exit_error(PARAMETER_PROBLEM,
130 "Invalid IPv6 address %s",
131 optarg);
134 *flags |= IP6T_ROUTE_OPT_GW;
135 break;
137 case '4':
138 if (*flags & IP6T_ROUTE_OPT_CONTINUE)
139 exit_error(PARAMETER_PROBLEM,
140 "Can't specify --continue twice");
141 if (*flags & IP6T_ROUTE_OPT_TEE)
142 exit_error(PARAMETER_PROBLEM,
143 "Can't specify --continue AND --tee");
145 route_info->flags |= IP6T_ROUTE_CONTINUE;
146 *flags |= IP6T_ROUTE_OPT_CONTINUE;
148 break;
150 case '5':
151 if (*flags & IP6T_ROUTE_OPT_TEE)
152 exit_error(PARAMETER_PROBLEM,
153 "Can't specify --tee twice");
154 if (*flags & IP6T_ROUTE_OPT_CONTINUE)
155 exit_error(PARAMETER_PROBLEM,
156 "Can't specify --tee AND --continue");
158 route_info->flags |= IP6T_ROUTE_TEE;
159 *flags |= IP6T_ROUTE_OPT_TEE;
161 break;
163 default:
164 return 0;
167 return 1;
171 static void
172 final_check(unsigned int flags)
174 if (!flags)
175 exit_error(PARAMETER_PROBLEM,
176 "ROUTE target: oif or gw option required");
180 /* Prints out the targinfo. */
181 static void
182 #ifdef _XTABLES_H
183 print(const void *ip,
184 const struct xt_entry_target *target,
185 #else
186 print(const struct ip6t_ip6 *ip,
187 const struct ip6t_entry_target *target,
188 #endif
189 int numeric)
191 const struct ip6t_route_target_info *route_info
192 = (const struct ip6t_route_target_info *)target->data;
194 printf("ROUTE ");
196 if (route_info->oif[0])
197 printf("oif:%s ", route_info->oif);
199 if (route_info->gw[0]
200 || route_info->gw[1]
201 || route_info->gw[2]
202 || route_info->gw[3]) {
203 char address[INET6_ADDRSTRLEN];
204 printf("gw:%s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN));
207 if (route_info->flags & IP6T_ROUTE_CONTINUE)
208 printf("continue");
210 if (route_info->flags & IP6T_ROUTE_TEE)
211 printf("tee");
216 static void
217 #ifdef _XTABLES_H
218 save(const void *ip,
219 const struct xt_entry_target *target)
220 #else
221 save(const struct ip6t_ip6 *ip,
222 const struct ip6t_entry_target *target)
223 #endif
225 const struct ip6t_route_target_info *route_info
226 = (const struct ip6t_route_target_info *)target->data;
228 if (route_info->oif[0])
229 printf("--oif %s ", route_info->oif);
231 if (route_info->gw[0]
232 || route_info->gw[1]
233 || route_info->gw[2]
234 || route_info->gw[3]) {
235 char address[INET6_ADDRSTRLEN];
236 printf("--gw %s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN));
239 if (route_info->flags & IP6T_ROUTE_CONTINUE)
240 printf("--continue ");
242 if (route_info->flags & IP6T_ROUTE_TEE)
243 printf("--tee ");
247 static struct ip6tables_target route = {
248 .name = "ROUTE",
249 .version = XTABLES_VERSION,
250 .size = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)),
251 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)),
252 .help = &help,
253 .init = &init,
254 .parse = &parse,
255 .final_check = &final_check,
256 .print = &print,
257 .save = &save,
258 .extra_opts = opts,
261 void _init(void)
263 register_target6(&route);