1 /* Shared library add-on to iptables to add ipv4 options matching support. */
9 #include <linux/netfilter_ipv4/ipt_ipv4options.h>
11 /* Function which prints out usage message. */
16 "ipv4options v%s options:\n"
17 " --ssrr (match strict source routing flag)\n"
18 " --lsrr (match loose source routing flag)\n"
19 " --no-srr (match packets with no source routing)\n\n"
20 " [!] --rr (match record route flag)\n\n"
21 " [!] --ts (match timestamp flag)\n\n"
22 " [!] --ra (match router-alert option)\n\n"
23 " [!] --any-opt (match any option or no option at all if used with '!')\n",
27 static struct option opts[] = {
28 { "ssrr", 0, 0, '1' },
29 { "lsrr", 0, 0, '2' },
30 { "no-srr", 0, 0, '3'},
34 { "any-opt", 0, 0, '7'},
38 /* Initialize the match. */
40 init(struct ipt_entry_match *m, unsigned int *nfcache)
42 /* caching not yet implemented */
43 *nfcache |= NFC_UNKNOWN;
46 /* Function which parses command options; returns true if it
49 parse(int c, char **argv, int invert, unsigned int *flags,
50 const struct ipt_entry *entry,
51 unsigned int *nfcache,
52 struct ipt_entry_match **match)
54 struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
58 /* strict-source-routing */
61 exit_error(PARAMETER_PROBLEM,
62 "ipv4options: unexpected `!' with --ssrr");
63 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
64 exit_error(PARAMETER_PROBLEM,
65 "Can't specify --ssrr twice");
66 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
67 exit_error(PARAMETER_PROBLEM,
68 "Can't specify --ssrr with --lsrr");
69 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
70 exit_error(PARAMETER_PROBLEM,
71 "Can't specify --ssrr with --no-srr");
73 info->options |= IPT_IPV4OPTION_MATCH_SSRR;
74 *flags |= IPT_IPV4OPTION_MATCH_SSRR;
77 /* loose-source-routing */
80 exit_error(PARAMETER_PROBLEM,
81 "ipv4options: unexpected `!' with --lsrr");
82 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
83 exit_error(PARAMETER_PROBLEM,
84 "Can't specify --lsrr twice");
85 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
86 exit_error(PARAMETER_PROBLEM,
87 "Can't specify --lsrr with --ssrr");
88 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
89 exit_error(PARAMETER_PROBLEM,
90 "Can't specify --lsrr with --no-srr");
91 info->options |= IPT_IPV4OPTION_MATCH_LSRR;
92 *flags |= IPT_IPV4OPTION_MATCH_LSRR;
95 /* no-source-routing */
98 exit_error(PARAMETER_PROBLEM,
99 "ipv4options: unexpected `!' with --no-srr");
100 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
101 exit_error(PARAMETER_PROBLEM,
102 "Can't specify --no-srr twice");
103 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
104 exit_error(PARAMETER_PROBLEM,
105 "Can't specify --no-srr with --ssrr");
106 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
107 exit_error(PARAMETER_PROBLEM,
108 "Can't specify --no-srr with --lsrr");
109 info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
110 *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
115 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
116 exit_error(PARAMETER_PROBLEM,
117 "Can't specify --rr twice");
118 if (invert && (*flags & IPT_IPV4OPTION_DONT_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 with ! --rr");
124 if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
125 exit_error(PARAMETER_PROBLEM,
126 "Can't specify ! --rr with --rr");
128 info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
129 *flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
132 info->options |= IPT_IPV4OPTION_MATCH_RR;
133 *flags |= IPT_IPV4OPTION_MATCH_RR;
139 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
140 exit_error(PARAMETER_PROBLEM,
141 "Can't specify --ts twice");
142 if (invert && (*flags & IPT_IPV4OPTION_DONT_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 with ! --ts");
148 if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
149 exit_error(PARAMETER_PROBLEM,
150 "Can't specify ! --ts with --ts");
152 info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
153 *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
156 info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
157 *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
163 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
164 exit_error(PARAMETER_PROBLEM,
165 "Can't specify --ra twice");
166 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
167 exit_error(PARAMETER_PROBLEM,
168 "Can't specify ! --rr twice");
169 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
170 exit_error(PARAMETER_PROBLEM,
171 "Can't specify --ra with ! --ra");
172 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
173 exit_error(PARAMETER_PROBLEM,
174 "Can't specify ! --ra with --ra");
176 info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
177 *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
180 info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
181 *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
187 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
188 exit_error(PARAMETER_PROBLEM,
189 "Can't specify --any-opt twice");
190 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
191 exit_error(PARAMETER_PROBLEM,
192 "Can't specify ! --any-opt with --any-opt");
193 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
194 exit_error(PARAMETER_PROBLEM,
195 "Can't specify ! --any-opt twice");
197 ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) ||
198 (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) ||
199 (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
200 (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)))
201 exit_error(PARAMETER_PROBLEM,
202 "Can't specify --any-opt with any other negative ipv4options match");
204 ((*flags & IPT_IPV4OPTION_MATCH_LSRR) ||
205 (*flags & IPT_IPV4OPTION_MATCH_SSRR) ||
206 (*flags & IPT_IPV4OPTION_MATCH_RR) ||
207 (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
208 (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)))
209 exit_error(PARAMETER_PROBLEM,
210 "Can't specify ! --any-opt with any other positive ipv4options match");
212 info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
213 *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
216 info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT;
217 *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT;
228 final_check(unsigned int flags)
231 exit_error(PARAMETER_PROBLEM,
232 "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
235 /* Prints out the matchinfo. */
237 print(const struct ipt_ip *ip,
238 const struct ipt_entry_match *match,
241 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
244 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
246 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
248 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
250 if (info->options & IPT_IPV4OPTION_MATCH_RR)
252 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
254 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
256 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
258 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
260 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
262 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
264 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
270 /* Saves the data in parsable form to stdout. */
272 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
274 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
276 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
278 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
280 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
282 if (info->options & IPT_IPV4OPTION_MATCH_RR)
284 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
286 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
288 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
290 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
292 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
294 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
295 printf(" --any-opt");
296 if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
297 printf(" ! --any-opt");
303 struct iptables_match ipv4options_struct
307 IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
308 IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
320 register_match(&ipv4options_struct);