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 /* Function which parses command options; returns true if it
41 parse(int c, char **argv, int invert, unsigned int *flags,
42 const struct ipt_entry *entry,
43 struct ipt_entry_match **match)
45 struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
49 /* strict-source-routing */
52 exit_error(PARAMETER_PROBLEM,
53 "ipv4options: unexpected `!' with --ssrr");
54 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
55 exit_error(PARAMETER_PROBLEM,
56 "Can't specify --ssrr twice");
57 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
58 exit_error(PARAMETER_PROBLEM,
59 "Can't specify --ssrr with --lsrr");
60 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
61 exit_error(PARAMETER_PROBLEM,
62 "Can't specify --ssrr with --no-srr");
64 info->options |= IPT_IPV4OPTION_MATCH_SSRR;
65 *flags |= IPT_IPV4OPTION_MATCH_SSRR;
68 /* loose-source-routing */
71 exit_error(PARAMETER_PROBLEM,
72 "ipv4options: unexpected `!' with --lsrr");
73 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
74 exit_error(PARAMETER_PROBLEM,
75 "Can't specify --lsrr twice");
76 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
77 exit_error(PARAMETER_PROBLEM,
78 "Can't specify --lsrr with --ssrr");
79 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
80 exit_error(PARAMETER_PROBLEM,
81 "Can't specify --lsrr with --no-srr");
82 info->options |= IPT_IPV4OPTION_MATCH_LSRR;
83 *flags |= IPT_IPV4OPTION_MATCH_LSRR;
86 /* no-source-routing */
89 exit_error(PARAMETER_PROBLEM,
90 "ipv4options: unexpected `!' with --no-srr");
91 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
92 exit_error(PARAMETER_PROBLEM,
93 "Can't specify --no-srr twice");
94 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
95 exit_error(PARAMETER_PROBLEM,
96 "Can't specify --no-srr with --ssrr");
97 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
98 exit_error(PARAMETER_PROBLEM,
99 "Can't specify --no-srr with --lsrr");
100 info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
101 *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
106 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
107 exit_error(PARAMETER_PROBLEM,
108 "Can't specify --rr twice");
109 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
110 exit_error(PARAMETER_PROBLEM,
111 "Can't specify ! --rr twice");
112 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
113 exit_error(PARAMETER_PROBLEM,
114 "Can't specify --rr with ! --rr");
115 if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
116 exit_error(PARAMETER_PROBLEM,
117 "Can't specify ! --rr with --rr");
119 info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
120 *flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
123 info->options |= IPT_IPV4OPTION_MATCH_RR;
124 *flags |= IPT_IPV4OPTION_MATCH_RR;
130 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
131 exit_error(PARAMETER_PROBLEM,
132 "Can't specify --ts twice");
133 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
134 exit_error(PARAMETER_PROBLEM,
135 "Can't specify ! --ts twice");
136 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
137 exit_error(PARAMETER_PROBLEM,
138 "Can't specify --ts with ! --ts");
139 if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
140 exit_error(PARAMETER_PROBLEM,
141 "Can't specify ! --ts with --ts");
143 info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
144 *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
147 info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
148 *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
154 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
155 exit_error(PARAMETER_PROBLEM,
156 "Can't specify --ra twice");
157 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
158 exit_error(PARAMETER_PROBLEM,
159 "Can't specify ! --rr twice");
160 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
161 exit_error(PARAMETER_PROBLEM,
162 "Can't specify --ra with ! --ra");
163 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
164 exit_error(PARAMETER_PROBLEM,
165 "Can't specify ! --ra with --ra");
167 info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
168 *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
171 info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
172 *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
178 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
179 exit_error(PARAMETER_PROBLEM,
180 "Can't specify --any-opt twice");
181 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
182 exit_error(PARAMETER_PROBLEM,
183 "Can't specify ! --any-opt with --any-opt");
184 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
185 exit_error(PARAMETER_PROBLEM,
186 "Can't specify ! --any-opt twice");
188 ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) ||
189 (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) ||
190 (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
191 (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)))
192 exit_error(PARAMETER_PROBLEM,
193 "Can't specify --any-opt with any other negative ipv4options match");
195 ((*flags & IPT_IPV4OPTION_MATCH_LSRR) ||
196 (*flags & IPT_IPV4OPTION_MATCH_SSRR) ||
197 (*flags & IPT_IPV4OPTION_MATCH_RR) ||
198 (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
199 (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)))
200 exit_error(PARAMETER_PROBLEM,
201 "Can't specify ! --any-opt with any other positive ipv4options match");
203 info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
204 *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
207 info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT;
208 *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT;
219 final_check(unsigned int flags)
222 exit_error(PARAMETER_PROBLEM,
223 "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
226 /* Prints out the matchinfo. */
228 print(const struct ipt_ip *ip,
229 const struct ipt_entry_match *match,
232 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
235 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
237 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
239 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
241 if (info->options & IPT_IPV4OPTION_MATCH_RR)
243 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
245 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
247 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
249 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
251 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
253 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
255 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
261 /* Saves the data in parsable form to stdout. */
263 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
265 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
267 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
269 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
271 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
273 if (info->options & IPT_IPV4OPTION_MATCH_RR)
275 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
277 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
279 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
281 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
283 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
285 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
286 printf(" --any-opt");
287 if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
288 printf(" ! --any-opt");
293 static struct iptables_match ipv4options_struct = {
295 .name = "ipv4options",
296 .version = IPTABLES_VERSION,
297 .size = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
298 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
301 .final_check = &final_check,
309 register_match(&ipv4options_struct);