Clean and tiddy-up files.
[tomato.git] / release / src / router / iptables / extensions / libipt_ipv4options.c
blob7003a505e06076ec1635f2ecf55ba3f29b96d670
1 /* Shared library add-on to iptables to add ipv4 options matching support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <getopt.h>
8 #include <iptables.h>
9 #include <linux/netfilter_ipv4/ipt_ipv4options.h>
11 #ifndef XTABLES_VERSION
12 #define XTABLES_VERSION IPTABLES_VERSION
13 #endif
15 #ifdef IPT_LIB_DIR
16 #define xtables_target iptables_target
17 #define xtables_register_target register_target
18 #endif
20 /* Function which prints out usage message. */
21 static void
22 help(void)
24 printf(
25 "ipv4options v%s options:\n"
26 " --ssrr (match strict source routing flag)\n"
27 " --lsrr (match loose source routing flag)\n"
28 " --no-srr (match packets with no source routing)\n\n"
29 " [!] --rr (match record route flag)\n\n"
30 " [!] --ts (match timestamp flag)\n\n"
31 " [!] --ra (match router-alert option)\n\n"
32 " [!] --any-opt (match any option or no option at all if used with '!')\n",
33 XTABLES_VERSION);
36 static struct option opts[] = {
37 { "ssrr", 0, 0, '1' },
38 { "lsrr", 0, 0, '2' },
39 { "no-srr", 0, 0, '3'},
40 { "rr", 0, 0, '4'},
41 { "ts", 0, 0, '5'},
42 { "ra", 0, 0, '6'},
43 { "any-opt", 0, 0, '7'},
44 {0}
47 /* Function which parses command options; returns true if it
48 ate an option */
49 static int
50 parse(int c, char **argv, int invert, unsigned int *flags,
51 #ifdef _XTABLES_H
52 const void *entry, struct xt_entry_match **match)
53 #else
54 const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match)
55 #endif
57 struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
59 switch (c)
61 /* strict-source-routing */
62 case '1':
63 if (invert)
64 exit_error(PARAMETER_PROBLEM,
65 "ipv4options: unexpected `!' with --ssrr");
66 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
67 exit_error(PARAMETER_PROBLEM,
68 "Can't specify --ssrr twice");
69 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
70 exit_error(PARAMETER_PROBLEM,
71 "Can't specify --ssrr with --lsrr");
72 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
73 exit_error(PARAMETER_PROBLEM,
74 "Can't specify --ssrr with --no-srr");
76 info->options |= IPT_IPV4OPTION_MATCH_SSRR;
77 *flags |= IPT_IPV4OPTION_MATCH_SSRR;
78 break;
80 /* loose-source-routing */
81 case '2':
82 if (invert)
83 exit_error(PARAMETER_PROBLEM,
84 "ipv4options: unexpected `!' with --lsrr");
85 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
86 exit_error(PARAMETER_PROBLEM,
87 "Can't specify --lsrr twice");
88 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
89 exit_error(PARAMETER_PROBLEM,
90 "Can't specify --lsrr with --ssrr");
91 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
92 exit_error(PARAMETER_PROBLEM,
93 "Can't specify --lsrr with --no-srr");
94 info->options |= IPT_IPV4OPTION_MATCH_LSRR;
95 *flags |= IPT_IPV4OPTION_MATCH_LSRR;
96 break;
98 /* no-source-routing */
99 case '3':
100 if (invert)
101 exit_error(PARAMETER_PROBLEM,
102 "ipv4options: unexpected `!' with --no-srr");
103 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
104 exit_error(PARAMETER_PROBLEM,
105 "Can't specify --no-srr twice");
106 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
107 exit_error(PARAMETER_PROBLEM,
108 "Can't specify --no-srr with --ssrr");
109 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
110 exit_error(PARAMETER_PROBLEM,
111 "Can't specify --no-srr with --lsrr");
112 info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
113 *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
114 break;
116 /* record-route */
117 case '4':
118 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
119 exit_error(PARAMETER_PROBLEM,
120 "Can't specify --rr twice");
121 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
122 exit_error(PARAMETER_PROBLEM,
123 "Can't specify ! --rr twice");
124 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
125 exit_error(PARAMETER_PROBLEM,
126 "Can't specify --rr with ! --rr");
127 if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
128 exit_error(PARAMETER_PROBLEM,
129 "Can't specify ! --rr with --rr");
130 if (invert) {
131 info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
132 *flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
134 else {
135 info->options |= IPT_IPV4OPTION_MATCH_RR;
136 *flags |= IPT_IPV4OPTION_MATCH_RR;
138 break;
140 /* timestamp */
141 case '5':
142 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
143 exit_error(PARAMETER_PROBLEM,
144 "Can't specify --ts twice");
145 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
146 exit_error(PARAMETER_PROBLEM,
147 "Can't specify ! --ts twice");
148 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
149 exit_error(PARAMETER_PROBLEM,
150 "Can't specify --ts with ! --ts");
151 if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
152 exit_error(PARAMETER_PROBLEM,
153 "Can't specify ! --ts with --ts");
154 if (invert) {
155 info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
156 *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
158 else {
159 info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
160 *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
162 break;
164 /* router-alert */
165 case '6':
166 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
167 exit_error(PARAMETER_PROBLEM,
168 "Can't specify --ra twice");
169 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
170 exit_error(PARAMETER_PROBLEM,
171 "Can't specify ! --rr twice");
172 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
173 exit_error(PARAMETER_PROBLEM,
174 "Can't specify --ra with ! --ra");
175 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
176 exit_error(PARAMETER_PROBLEM,
177 "Can't specify ! --ra with --ra");
178 if (invert) {
179 info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
180 *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
182 else {
183 info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
184 *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
186 break;
188 /* any option */
189 case '7' :
190 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
191 exit_error(PARAMETER_PROBLEM,
192 "Can't specify --any-opt twice");
193 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
194 exit_error(PARAMETER_PROBLEM,
195 "Can't specify ! --any-opt with --any-opt");
196 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
197 exit_error(PARAMETER_PROBLEM,
198 "Can't specify ! --any-opt twice");
199 if ((!invert) &&
200 ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) ||
201 (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) ||
202 (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
203 (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)))
204 exit_error(PARAMETER_PROBLEM,
205 "Can't specify --any-opt with any other negative ipv4options match");
206 if (invert &&
207 ((*flags & IPT_IPV4OPTION_MATCH_LSRR) ||
208 (*flags & IPT_IPV4OPTION_MATCH_SSRR) ||
209 (*flags & IPT_IPV4OPTION_MATCH_RR) ||
210 (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
211 (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)))
212 exit_error(PARAMETER_PROBLEM,
213 "Can't specify ! --any-opt with any other positive ipv4options match");
214 if (invert) {
215 info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
216 *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
218 else {
219 info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT;
220 *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT;
222 break;
224 default:
225 return 0;
227 return 1;
230 static void
231 final_check(unsigned int flags)
233 if (flags == 0)
234 exit_error(PARAMETER_PROBLEM,
235 "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
238 /* Prints out the matchinfo. */
239 static void
240 #ifdef _XTABLES_H
241 print(const void *ip,
242 const struct xt_entry_match *match,
243 #else
244 print(const struct ipt_ip *ip,
245 const struct ipt_entry_match *match,
246 #endif
247 int numeric)
249 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
251 printf(" IPV4OPTS");
252 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
253 printf(" SSRR");
254 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
255 printf(" LSRR");
256 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
257 printf(" !SRR");
258 if (info->options & IPT_IPV4OPTION_MATCH_RR)
259 printf(" RR");
260 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
261 printf(" !RR");
262 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
263 printf(" TS");
264 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
265 printf(" !TS");
266 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
267 printf(" RA");
268 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
269 printf(" !RA");
270 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
271 printf(" ANYOPT ");
272 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
273 printf(" NOOPT");
275 printf(" ");
278 /* Saves the data in parsable form to stdout. */
279 static void
280 #ifdef _XTABLES_H
281 save(const void *ip,
282 const struct xt_entry_match *match)
283 #else
284 save(const struct ipt_ip *ip,
285 const struct ipt_entry_match *match)
286 #endif
288 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
290 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
291 printf(" --ssrr");
292 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
293 printf(" --lsrr");
294 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
295 printf(" --no-srr");
296 if (info->options & IPT_IPV4OPTION_MATCH_RR)
297 printf(" --rr");
298 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
299 printf(" ! --rr");
300 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
301 printf(" --ts");
302 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
303 printf(" ! --ts");
304 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
305 printf(" --ra");
306 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
307 printf(" ! --ra");
308 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
309 printf(" --any-opt");
310 if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
311 printf(" ! --any-opt");
313 printf(" ");
316 static struct xtables_match ipv4options_struct = {
317 .next = NULL,
318 .name = "ipv4options",
319 .version = XTABLES_VERSION,
320 .size = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
321 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
322 .help = &help,
323 .parse = &parse,
324 .final_check = &final_check,
325 .print = &print,
326 .save = &save,
327 .extra_opts = opts
330 void _init(void)
332 xtables_register_match(&ipv4options_struct);