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 unsigned int *nfcache,
44 struct ipt_entry_match **match)
46 struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
50 /* strict-source-routing */
53 exit_error(PARAMETER_PROBLEM,
54 "ipv4options: unexpected `!' with --ssrr");
55 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
56 exit_error(PARAMETER_PROBLEM,
57 "Can't specify --ssrr twice");
58 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
59 exit_error(PARAMETER_PROBLEM,
60 "Can't specify --ssrr with --lsrr");
61 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
62 exit_error(PARAMETER_PROBLEM,
63 "Can't specify --ssrr with --no-srr");
65 info->options |= IPT_IPV4OPTION_MATCH_SSRR;
66 *flags |= IPT_IPV4OPTION_MATCH_SSRR;
69 /* loose-source-routing */
72 exit_error(PARAMETER_PROBLEM,
73 "ipv4options: unexpected `!' with --lsrr");
74 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
75 exit_error(PARAMETER_PROBLEM,
76 "Can't specify --lsrr twice");
77 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
78 exit_error(PARAMETER_PROBLEM,
79 "Can't specify --lsrr with --ssrr");
80 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
81 exit_error(PARAMETER_PROBLEM,
82 "Can't specify --lsrr with --no-srr");
83 info->options |= IPT_IPV4OPTION_MATCH_LSRR;
84 *flags |= IPT_IPV4OPTION_MATCH_LSRR;
87 /* no-source-routing */
90 exit_error(PARAMETER_PROBLEM,
91 "ipv4options: unexpected `!' with --no-srr");
92 if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
93 exit_error(PARAMETER_PROBLEM,
94 "Can't specify --no-srr twice");
95 if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
96 exit_error(PARAMETER_PROBLEM,
97 "Can't specify --no-srr with --ssrr");
98 if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
99 exit_error(PARAMETER_PROBLEM,
100 "Can't specify --no-srr with --lsrr");
101 info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
102 *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
107 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
108 exit_error(PARAMETER_PROBLEM,
109 "Can't specify --rr twice");
110 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
111 exit_error(PARAMETER_PROBLEM,
112 "Can't specify ! --rr twice");
113 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
114 exit_error(PARAMETER_PROBLEM,
115 "Can't specify --rr with ! --rr");
116 if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
117 exit_error(PARAMETER_PROBLEM,
118 "Can't specify ! --rr with --rr");
120 info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
121 *flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
124 info->options |= IPT_IPV4OPTION_MATCH_RR;
125 *flags |= IPT_IPV4OPTION_MATCH_RR;
131 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
132 exit_error(PARAMETER_PROBLEM,
133 "Can't specify --ts twice");
134 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
135 exit_error(PARAMETER_PROBLEM,
136 "Can't specify ! --ts twice");
137 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
138 exit_error(PARAMETER_PROBLEM,
139 "Can't specify --ts with ! --ts");
140 if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
141 exit_error(PARAMETER_PROBLEM,
142 "Can't specify ! --ts with --ts");
144 info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
145 *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
148 info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
149 *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
155 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
156 exit_error(PARAMETER_PROBLEM,
157 "Can't specify --ra twice");
158 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
159 exit_error(PARAMETER_PROBLEM,
160 "Can't specify ! --rr twice");
161 if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
162 exit_error(PARAMETER_PROBLEM,
163 "Can't specify --ra with ! --ra");
164 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
165 exit_error(PARAMETER_PROBLEM,
166 "Can't specify ! --ra with --ra");
168 info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
169 *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
172 info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
173 *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
179 if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
180 exit_error(PARAMETER_PROBLEM,
181 "Can't specify --any-opt twice");
182 if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
183 exit_error(PARAMETER_PROBLEM,
184 "Can't specify ! --any-opt with --any-opt");
185 if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
186 exit_error(PARAMETER_PROBLEM,
187 "Can't specify ! --any-opt twice");
189 ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) ||
190 (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) ||
191 (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
192 (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)))
193 exit_error(PARAMETER_PROBLEM,
194 "Can't specify --any-opt with any other negative ipv4options match");
196 ((*flags & IPT_IPV4OPTION_MATCH_LSRR) ||
197 (*flags & IPT_IPV4OPTION_MATCH_SSRR) ||
198 (*flags & IPT_IPV4OPTION_MATCH_RR) ||
199 (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
200 (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)))
201 exit_error(PARAMETER_PROBLEM,
202 "Can't specify ! --any-opt with any other positive ipv4options match");
204 info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
205 *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
208 info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT;
209 *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT;
220 final_check(unsigned int flags)
223 exit_error(PARAMETER_PROBLEM,
224 "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
227 /* Prints out the matchinfo. */
229 print(const struct ipt_ip *ip,
230 const struct ipt_entry_match *match,
233 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
236 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
238 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
240 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
242 if (info->options & IPT_IPV4OPTION_MATCH_RR)
244 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
246 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
248 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
250 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
252 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
254 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
256 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
262 /* Saves the data in parsable form to stdout. */
264 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
266 struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
268 if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
270 else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
272 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
274 if (info->options & IPT_IPV4OPTION_MATCH_RR)
276 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
278 if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
280 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
282 if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
284 else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
286 if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
287 printf(" --any-opt");
288 if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
289 printf(" ! --any-opt");
294 static struct iptables_match ipv4options_struct = {
296 .name = "ipv4options",
297 .version = IPTABLES_VERSION,
298 .size = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
299 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
302 .final_check = &final_check,
310 register_match(&ipv4options_struct);