158
156
struct ip6t_policy_info *info = (void *)(*match)->data;
159
157
struct ip6t_policy_elem *e = &info->pol[info->len];
160
158
struct in6_addr *addr = NULL, mask;
161
unsigned int naddr = 0;
159
unsigned int naddr = 0, num;
164
check_inverse(optarg, &invert, &optind, 0);
162
xtables_check_inverse(optarg, &invert, &optind, 0);
168
166
if (info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT))
169
exit_error(PARAMETER_PROBLEM,
167
xtables_error(PARAMETER_PROBLEM,
170
168
"policy match: double --dir option");
172
exit_error(PARAMETER_PROBLEM,
170
xtables_error(PARAMETER_PROBLEM,
173
171
"policy match: can't invert --dir option");
175
173
info->flags |= parse_direction(argv[optind-1]);
179
exit_error(PARAMETER_PROBLEM,
177
xtables_error(PARAMETER_PROBLEM,
180
178
"policy match: can't invert --policy option");
182
180
info->flags |= parse_policy(argv[optind-1]);
185
183
if (info->flags & IP6T_POLICY_MATCH_STRICT)
186
exit_error(PARAMETER_PROBLEM,
184
xtables_error(PARAMETER_PROBLEM,
187
185
"policy match: double --strict option");
190
exit_error(PARAMETER_PROBLEM,
188
xtables_error(PARAMETER_PROBLEM,
191
189
"policy match: can't invert --strict option");
193
191
info->flags |= IP6T_POLICY_MATCH_STRICT;
196
194
if (e->match.reqid)
197
exit_error(PARAMETER_PROBLEM,
195
xtables_error(PARAMETER_PROBLEM,
198
196
"policy match: double --reqid option");
200
198
e->match.reqid = 1;
201
199
e->invert.reqid = invert;
202
e->reqid = strtol(argv[optind-1], NULL, 10);
200
if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
201
xtables_param_act(XTF_BAD_VALUE, "policy", "--reqid", optarg);
205
205
if (e->match.spi)
206
exit_error(PARAMETER_PROBLEM,
206
xtables_error(PARAMETER_PROBLEM,
207
207
"policy match: double --spi option");
209
209
e->match.spi = 1;
210
210
e->invert.spi = invert;
211
e->spi = strtol(argv[optind-1], NULL, 0x10);
211
if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
212
xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg);
214
216
if (e->match.saddr)
215
exit_error(PARAMETER_PROBLEM,
217
xtables_error(PARAMETER_PROBLEM,
216
218
"policy match: double --tunnel-src option");
218
ip6parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
220
xtables_ip6parse_any(argv[optind-1], &addr, &mask, &naddr);
220
exit_error(PARAMETER_PROBLEM,
222
xtables_error(PARAMETER_PROBLEM,
221
223
"policy match: name resolves to multiple IPs");
223
225
e->match.saddr = 1;
229
231
if (e->match.daddr)
230
exit_error(PARAMETER_PROBLEM,
232
xtables_error(PARAMETER_PROBLEM,
231
233
"policy match: double --tunnel-dst option");
233
ip6parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
235
xtables_ip6parse_any(argv[optind-1], &addr, &mask, &naddr);
235
exit_error(PARAMETER_PROBLEM,
237
xtables_error(PARAMETER_PROBLEM,
236
238
"policy match: name resolves to multiple IPs");
238
240
e->match.daddr = 1;
244
246
if (e->match.proto)
245
exit_error(PARAMETER_PROBLEM,
247
xtables_error(PARAMETER_PROBLEM,
246
248
"policy match: double --proto option");
248
e->proto = parse_protocol(argv[optind-1]);
250
e->proto = xtables_parse_protocol(argv[optind-1]);
249
251
if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
250
252
e->proto != IPPROTO_COMP)
251
exit_error(PARAMETER_PROBLEM,
253
xtables_error(PARAMETER_PROBLEM,
252
254
"policy match: protocol must ah/esp/ipcomp");
253
255
e->match.proto = 1;
254
256
e->invert.proto = invert;
257
259
if (e->match.mode)
258
exit_error(PARAMETER_PROBLEM,
260
xtables_error(PARAMETER_PROBLEM,
259
261
"policy match: double --mode option");
261
263
mode = parse_mode(argv[optind-1]);
289
291
if (info == NULL)
290
exit_error(PARAMETER_PROBLEM,
292
xtables_error(PARAMETER_PROBLEM,
291
293
"policy match: no parameters given");
293
295
if (!(info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT)))
294
exit_error(PARAMETER_PROBLEM,
296
xtables_error(PARAMETER_PROBLEM,
295
297
"policy match: neither --in nor --out specified");
297
299
if (info->flags & IP6T_POLICY_MATCH_NONE) {
298
300
if (info->flags & IP6T_POLICY_MATCH_STRICT)
299
exit_error(PARAMETER_PROBLEM,
301
xtables_error(PARAMETER_PROBLEM,
300
302
"policy match: policy none but --strict given");
302
304
if (info->len != 0)
303
exit_error(PARAMETER_PROBLEM,
305
xtables_error(PARAMETER_PROBLEM,
304
306
"policy match: policy none but policy given");
306
308
info->len++; /* increase len by 1, no --next after last element */
308
310
if (!(info->flags & IP6T_POLICY_MATCH_STRICT) && info->len > 1)
309
exit_error(PARAMETER_PROBLEM,
311
xtables_error(PARAMETER_PROBLEM,
310
312
"policy match: multiple elements but no --strict");
312
314
for (i = 0; i < info->len; i++) {
315
317
if (info->flags & IP6T_POLICY_MATCH_STRICT &&
316
318
!(e->match.reqid || e->match.spi || e->match.saddr ||
317
319
e->match.daddr || e->match.proto || e->match.mode))
318
exit_error(PARAMETER_PROBLEM,
320
xtables_error(PARAMETER_PROBLEM,
319
321
"policy match: empty policy element");
321
323
if ((e->match.saddr || e->match.daddr)
322
324
&& ((e->mode == IP6T_POLICY_MODE_TUNNEL && e->invert.mode) ||
323
325
(e->mode == IP6T_POLICY_MODE_TRANSPORT && !e->invert.mode)))
324
exit_error(PARAMETER_PROBLEM,
326
xtables_error(PARAMETER_PROBLEM,
325
327
"policy match: --tunnel-src/--tunnel-dst "
326
328
"is only valid in tunnel mode");