]> git.pld-linux.org Git - packages/iptables.git/blob - iptables-pom-ng.patch
- allow build with -O0
[packages/iptables.git] / iptables-pom-ng.patch
1 diff -Nur iptables.org/extensions/.policy-test iptables/extensions/.policy-test
2 --- iptables.org/extensions/.policy-test        1970-01-01 01:00:00.000000000 +0100
3 +++ iptables/extensions/.policy-test    2004-05-18 12:39:55.000000000 +0200
4 @@ -0,0 +1,3 @@
5 +#!/bin/sh
6 +#
7 +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_policy.h ] && echo policy
8 diff -Nur iptables.org/extensions/.policy-test6 iptables/extensions/.policy-test6
9 --- iptables.org/extensions/.policy-test6       1970-01-01 01:00:00.000000000 +0100
10 +++ iptables/extensions/.policy-test6   2004-05-18 12:39:55.000000000 +0200
11 @@ -0,0 +1,3 @@
12 +#!/bin/sh
13 +#
14 +[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_policy.h ] && echo policy
15 diff -Nur iptables.org/extensions/libip6t_policy.c iptables/extensions/libip6t_policy.c
16 --- iptables.org/extensions/libip6t_policy.c    1970-01-01 01:00:00.000000000 +0100
17 +++ iptables/extensions/libip6t_policy.c        2004-05-18 12:39:55.000000000 +0200
18 @@ -0,0 +1,471 @@
19 +/* Shared library add-on to iptables to add policy support. */
20 +
21 +#include <stdio.h>
22 +#include <netdb.h>
23 +#include <string.h>
24 +#include <stdlib.h>
25 +#include <syslog.h>
26 +#include <getopt.h>
27 +#include <netdb.h>
28 +#include <errno.h>
29 +#include <sys/socket.h>
30 +#include <netinet/in.h>
31 +#include <arpa/inet.h>
32 +#include <ip6tables.h>
33 +
34 +#include <linux/netfilter_ipv6/ip6_tables.h>
35 +#include <linux/netfilter_ipv6/ip6t_policy.h>
36 +
37 +/*
38 + * HACK: global pointer to current matchinfo for making
39 + * final checks and adjustments in final_check.
40 + */
41 +static struct ip6t_policy_info *policy_info;
42 +
43 +static void help(void)
44 +{
45 +       printf(
46 +"policy v%s options:\n"
47 +"  --dir in|out                        match policy applied during decapsulation/\n"
48 +"                              policy to be applied during encapsulation\n"
49 +"  --pol none|ipsec            match policy\n"
50 +"  --strict                    match entire policy instead of single element\n"
51 +"                              at any position\n"
52 +"[!] --reqid reqid             match reqid\n"
53 +"[!] --spi spi                 match SPI\n"
54 +"[!] --proto proto             match protocol (ah/esp/ipcomp)\n"
55 +"[!] --mode mode               match mode (transport/tunnel)\n"
56 +"[!] --tunnel-src addr/masklen match tunnel source\n"
57 +"[!] --tunnel-dst addr/masklen match tunnel destination\n"
58 +"  --next                      begin next element in policy\n",
59 +       IPTABLES_VERSION);
60 +}
61 +
62 +static struct option opts[] =
63 +{
64 +       {
65 +               .name           = "dir",
66 +               .has_arg        = 1,
67 +               .val            = '1',
68 +       },
69 +       {
70 +               .name           = "pol",
71 +               .has_arg        = 1,
72 +               .val            = '2',
73 +       },
74 +       {
75 +               .name           = "strict",
76 +               .val            = '3'
77 +       },
78 +       {
79 +               .name           = "reqid",
80 +               .has_arg        = 1,
81 +               .val            = '4',
82 +       },
83 +       {
84 +               .name           = "spi",
85 +               .has_arg        = 1,
86 +               .val            = '5'
87 +       },
88 +       {
89 +               .name           = "tunnel-src",
90 +               .has_arg        = 1,
91 +               .val            = '6'
92 +       },
93 +       {
94 +               .name           = "tunnel-dst",
95 +               .has_arg        = 1,
96 +               .val            = '7'
97 +       },
98 +       {
99 +               .name           = "proto",
100 +               .has_arg        = 1,
101 +               .val            = '8'
102 +       },
103 +       {
104 +               .name           = "mode",
105 +               .has_arg        = 1,
106 +               .val            = '9'
107 +       },
108 +       {
109 +               .name           = "next",
110 +               .val            = 'a'
111 +       },
112 +       { }
113 +};
114 +
115 +/* FIXME - Duplicated code from ip6tables.c */
116 +/* Duplicated to stop too many changes in other files .... */
117 +static void
118 +in6addrcpy(struct in6_addr *dst, struct in6_addr *src)
119 +{
120 +        memcpy(dst, src, sizeof(struct in6_addr));
121 +        /* dst->s6_addr = src->s6_addr; */
122 +}
123 +
124 +static char *
125 +addr_to_numeric(const struct in6_addr *addrp)
126 +{
127 +        /* 0000:0000:0000:0000:0000:000.000.000.000
128 +        * 0000:0000:0000:0000:0000:0000:0000:0000 */
129 +        static char buf[50+1];
130 +        return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf));
131 +}
132 +
133 +static char *
134 +mask_to_numeric(const struct in6_addr *addrp)
135 +{
136 +        static char buf[50+2];
137 +        int l = ipv6_prefix_length(addrp);
138 +        if (l == -1) {
139 +               strcpy(buf, "/");
140 +               strcat(buf, addr_to_numeric(addrp));
141 +               return buf;
142 +       }
143 +       sprintf(buf, "/%d", l);
144 +       return buf;
145 +}
146 +
147 +/* These should be in include/ip6tables.h... */
148 +extern u_int16_t parse_protocol(const char *s);
149 +extern void parse_hostnetworkmask(const char *name, struct in6_addr **addrpp,
150 +               struct in6_addr *maskp, unsigned int *naddrs);
151 +
152 +/* End duplicated code from ip6tables.c */
153 +
154 +static void init(struct ip6t_entry_match *m, unsigned int *nfcache)
155 +{
156 +       *nfcache |= NFC_UNKNOWN;
157 +}
158 +
159 +static int parse_direction(char *s)
160 +{
161 +       if (strcmp(s, "in") == 0)
162 +               return POLICY_MATCH_IN;
163 +       if (strcmp(s, "out") == 0)
164 +               return POLICY_MATCH_OUT;
165 +       exit_error(PARAMETER_PROBLEM, "policy_match: invalid dir `%s'", s);
166 +}
167 +
168 +static int parse_policy(char *s)
169 +{
170 +       if (strcmp(s, "none") == 0)
171 +               return POLICY_MATCH_NONE;
172 +       if (strcmp(s, "ipsec") == 0)
173 +               return 0;
174 +       exit_error(PARAMETER_PROBLEM, "policy match: invalid policy `%s'", s);
175 +}
176 +
177 +static int parse_mode(char *s)
178 +{
179 +       if (strcmp(s, "transport") == 0)
180 +               return POLICY_MODE_TRANSPORT;
181 +       if (strcmp(s, "tunnel") == 0)
182 +               return POLICY_MODE_TUNNEL;
183 +       exit_error(PARAMETER_PROBLEM, "policy match: invalid mode `%s'", s);
184 +}
185 +
186 +static int parse(int c, char **argv, int invert, unsigned int *flags,
187 +                 const struct ip6t_entry *entry,
188 +                 unsigned int *nfcache,
189 +                 struct ip6t_entry_match **match)
190 +{
191 +       struct ip6t_policy_info *info = (void *)(*match)->data;
192 +       struct ip6t_policy_elem *e = &info->pol[info->len];
193 +       struct in6_addr *addr = NULL, mask;
194 +       unsigned int naddr = 0;
195 +       int mode;
196 +
197 +       check_inverse(optarg, &invert, &optind, 0);
198 +
199 +       switch (c) {
200 +       case '1':
201 +               if (info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))
202 +                       exit_error(PARAMETER_PROBLEM,
203 +                                  "policy match: double --dir option");
204 +               if (invert)
205 +                       exit_error(PARAMETER_PROBLEM,
206 +                                  "policy match: can't invert --dir option");
207 +
208 +               info->flags |= parse_direction(argv[optind-1]);
209 +               break;
210 +       case '2':
211 +               if (invert)
212 +                       exit_error(PARAMETER_PROBLEM,
213 +                                  "policy match: can't invert --policy option");
214 +
215 +               info->flags |= parse_policy(argv[optind-1]);
216 +               break;
217 +       case '3':
218 +               if (info->flags & POLICY_MATCH_STRICT)
219 +                       exit_error(PARAMETER_PROBLEM,
220 +                                  "policy match: double --strict option");
221 +
222 +               if (invert)
223 +                       exit_error(PARAMETER_PROBLEM,
224 +                                  "policy match: can't invert --strict option");
225 +
226 +               info->flags |= POLICY_MATCH_STRICT;
227 +               break;
228 +       case '4':
229 +               if (e->match.reqid)
230 +                       exit_error(PARAMETER_PROBLEM,
231 +                                  "policy match: double --reqid option");
232 +
233 +               e->match.reqid = 1;
234 +               e->invert.reqid = invert;
235 +               e->reqid = strtol(argv[optind-1], NULL, 10);
236 +               break;
237 +       case '5':
238 +               if (e->match.spi)
239 +                       exit_error(PARAMETER_PROBLEM,
240 +                                  "policy match: double --spi option");
241 +               
242 +               e->match.spi = 1;
243 +               e->invert.spi = invert;
244 +               e->spi = strtol(argv[optind-1], NULL, 0x10);
245 +               break;
246 +       case '6':
247 +               if (e->match.saddr)
248 +                       exit_error(PARAMETER_PROBLEM,
249 +                                  "policy match: double --tunnel-src option");
250 +
251 +               parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
252 +               if (naddr > 1)
253 +                       exit_error(PARAMETER_PROBLEM,
254 +                                  "policy match: name resolves to multiple IPs");
255 +
256 +               e->match.saddr = 1;
257 +               e->invert.saddr = invert;
258 +               in6addrcpy(&e->daddr, addr);
259 +               in6addrcpy(&e->dmask, &mask);
260 +                break;
261 +       case '7':
262 +               if (e->match.daddr)
263 +                       exit_error(PARAMETER_PROBLEM,
264 +                                  "policy match: double --tunnel-dst option");
265 +
266 +               parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
267 +               if (naddr > 1)
268 +                       exit_error(PARAMETER_PROBLEM,
269 +                                  "policy match: name resolves to multiple IPs");
270 +
271 +               e->match.daddr = 1;
272 +               e->invert.daddr = invert;
273 +               in6addrcpy(&e->daddr, addr);
274 +               in6addrcpy(&e->dmask, &mask);
275 +               break;
276 +       case '8':
277 +               if (e->match.proto)
278 +                       exit_error(PARAMETER_PROBLEM,
279 +                                  "policy match: double --proto option");
280 +
281 +               e->proto = parse_protocol(argv[optind-1]);
282 +               if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
283 +                   e->proto != IPPROTO_COMP)
284 +                       exit_error(PARAMETER_PROBLEM,
285 +                                  "policy match: protocol must ah/esp/ipcomp");
286 +               e->match.proto = 1;
287 +               e->invert.proto = invert;
288 +               break;
289 +       case '9':
290 +               if (e->match.mode)
291 +                       exit_error(PARAMETER_PROBLEM,
292 +                                  "policy match: double --mode option");
293 +               
294 +               mode = parse_mode(argv[optind-1]);
295 +               e->match.mode = 1;
296 +               e->invert.mode = invert;
297 +               e->mode = mode;
298 +               break;
299 +       case 'a':
300 +               if (invert)
301 +                       exit_error(PARAMETER_PROBLEM,
302 +                                  "policy match: can't invert --next option");
303 +
304 +               if (++info->len == POLICY_MAX_ELEM)
305 +                       exit_error(PARAMETER_PROBLEM,
306 +                                  "policy match: maximum policy depth reached");
307 +               break;
308 +       default:
309 +               return 0;
310 +       }
311 +
312 +       policy_info = info;
313 +       return 1;
314 +}
315 +
316 +static void final_check(unsigned int flags)
317 +{
318 +       struct ip6t_policy_info *info = policy_info;
319 +       struct ip6t_policy_elem *e;
320 +       int i;
321 +
322 +       if (info == NULL)
323 +               exit_error(PARAMETER_PROBLEM,
324 +                          "policy match: no parameters given");
325 +
326 +       if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT)))
327 +               exit_error(PARAMETER_PROBLEM,
328 +                          "policy match: neither --in nor --out specified");
329 +
330 +       if (info->flags & POLICY_MATCH_NONE) {
331 +               if (info->flags & POLICY_MATCH_STRICT)
332 +                       exit_error(PARAMETER_PROBLEM,
333 +                                  "policy match: policy none but --strict given");
334 +
335 +               if (info->len != 0)
336 +                       exit_error(PARAMETER_PROBLEM,
337 +                                  "policy match: policy none but policy given");
338 +       } else
339 +               info->len++;    /* increase len by 1, no --next after last element */
340 +
341 +       if (!(info->flags & POLICY_MATCH_STRICT) && info->len > 1)
342 +               exit_error(PARAMETER_PROBLEM,
343 +                          "policy match: multiple elements but no --strict");
344 +
345 +       for (i = 0; i < info->len; i++) {
346 +               e = &info->pol[i];
347 +               if ((e->match.saddr || e->match.daddr)
348 +                   && ((e->mode == POLICY_MODE_TUNNEL && e->invert.mode) ||
349 +                       (e->mode == POLICY_MODE_TRANSPORT && !e->invert.mode)))
350 +                       exit_error(PARAMETER_PROBLEM,
351 +                                  "policy match: --tunnel-src/--tunnel-dst "
352 +                                  "is only valid in tunnel mode");
353 +       }
354 +}
355 +
356 +static void print_mode(char *prefix, u_int8_t mode, int numeric)
357 +{
358 +       printf("%smode ", prefix);
359 +
360 +       switch (mode) {
361 +       case POLICY_MODE_TRANSPORT:
362 +               printf("transport ");
363 +               break;
364 +       case POLICY_MODE_TUNNEL:
365 +               printf("tunnel ");
366 +               break;
367 +       default:
368 +               printf("??? ");
369 +               break;
370 +       }
371 +}
372 +
373 +static void print_proto(char *prefix, u_int8_t proto, int numeric)
374 +{
375 +       struct protoent *p = NULL;
376 +
377 +       printf("%sproto ", prefix);
378 +       if (!numeric)
379 +               p = getprotobynumber(proto);
380 +       if (p != NULL)
381 +               printf("%s ", p->p_name);
382 +       else
383 +               printf("%u ", proto);
384 +}
385 +
386 +#define PRINT_INVERT(x)                \
387 +do {                           \
388 +       if (x)                  \
389 +               printf("! ");   \
390 +} while(0)
391 +
392 +static void print_entry(char *prefix, const struct ip6t_policy_elem *e,
393 +                        int numeric)
394 +{
395 +       if (e->match.reqid) {
396 +               PRINT_INVERT(e->invert.reqid);
397 +               printf("%sreqid %u ", prefix, e->reqid);
398 +       }
399 +       if (e->match.spi) {
400 +               PRINT_INVERT(e->invert.spi);
401 +               printf("%sspi 0x%x ", prefix, e->spi);
402 +       }
403 +       if (e->match.proto) {
404 +               PRINT_INVERT(e->invert.proto);
405 +               print_proto(prefix, e->proto, numeric);
406 +       }
407 +       if (e->match.mode) {
408 +               PRINT_INVERT(e->invert.mode);
409 +               print_mode(prefix, e->mode, numeric);
410 +       }
411 +       if (e->match.daddr) {
412 +               PRINT_INVERT(e->invert.daddr);
413 +               printf("%stunnel-dst %s%s ", prefix,
414 +                      addr_to_numeric((struct in6_addr *)&e->daddr),
415 +                      mask_to_numeric((struct in6_addr *)&e->dmask));
416 +       }
417 +       if (e->match.saddr) {
418 +               PRINT_INVERT(e->invert.saddr);
419 +               printf("%stunnel-src %s%s ", prefix,
420 +                      addr_to_numeric((struct in6_addr *)&e->saddr),
421 +                      mask_to_numeric((struct in6_addr *)&e->smask));
422 +       }
423 +}
424 +
425 +static void print_flags(char *prefix, const struct ip6t_policy_info *info)
426 +{
427 +       if (info->flags & POLICY_MATCH_IN)
428 +               printf("%sdir in ", prefix);
429 +       else
430 +               printf("%sdir out ", prefix);
431 +
432 +       if (info->flags & POLICY_MATCH_NONE)
433 +               printf("%spol none ", prefix);
434 +       else
435 +               printf("%spol ipsec ", prefix);
436 +
437 +       if (info->flags & POLICY_MATCH_STRICT)
438 +               printf("%sstrict ", prefix);
439 +}
440 +
441 +static void print(const struct ip6t_ip6 *ip,
442 +                  const struct ip6t_entry_match *match,
443 +                 int numeric)
444 +{
445 +       const struct ip6t_policy_info *info = (void *)match->data;
446 +       unsigned int i;
447 +
448 +       printf("policy match ");
449 +       print_flags("", info);
450 +       for (i = 0; i < info->len; i++) {
451 +               if (info->len > 1)
452 +                       printf("[%u] ", i);
453 +               print_entry("", &info->pol[i], numeric);
454 +       }
455 +
456 +       printf("\n");
457 +}
458 +
459 +static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
460 +{
461 +       const struct ip6t_policy_info *info = (void *)match->data;
462 +       unsigned int i;
463 +
464 +       print_flags("--", info);
465 +       for (i = 0; i < info->len; i++) {
466 +               print_entry("--", &info->pol[i], 0);
467 +               if (i + 1 < info->len)
468 +                       printf("--next ");
469 +       }
470 +}
471 +
472 +struct ip6tables_match policy = {
473 +       .name           = "policy",
474 +       .version        = IPTABLES_VERSION,
475 +       .size           = IP6T_ALIGN(sizeof(struct ip6t_policy_info)),
476 +       .userspacesize  = IP6T_ALIGN(sizeof(struct ip6t_policy_info)),
477 +       .help           = help,
478 +       .init           = init,
479 +       .parse          = parse,
480 +       .final_check    = final_check,
481 +       .print          = print,
482 +       .save           = save,
483 +       .extra_opts     = opts
484 +};
485 +
486 +void _init(void)
487 +{
488 +       register_match6(&policy);
489 +}
490 diff -Nur iptables.org/extensions/libipt_MARK.c iptables/extensions/libipt_MARK.c
491 --- iptables.org/extensions/libipt_MARK.c       2002-08-06 20:46:18.000000000 +0200
492 +++ iptables/extensions/libipt_MARK.c   2004-05-18 12:38:18.000000000 +0200
493 @@ -20,12 +20,16 @@
494         printf(
495  "MARK target v%s options:\n"
496  "  --set-mark value                   Set nfmark value\n"
497 +"  --and-mark value                   Binary AND the nfmark with value\n"
498 +"  --or-mark  value                   Binary OR  the nfmark with value\n"
499  "\n",
500  IPTABLES_VERSION);
501  }
502  
503  static struct option opts[] = {
504         { "set-mark", 1, 0, '1' },
505 +       { "and-mark", 1, 0, '2' },
506 +       { "or-mark", 1, 0, '3' },
507         { 0 }
508  };
509  
510 @@ -45,19 +49,31 @@
511         struct ipt_mark_target_info *markinfo
512                 = (struct ipt_mark_target_info *)(*target)->data;
513  
514 -       switch (c) {
515 -       case '1':
516 +       if ((c == '1') || (c == '2') || (c == '3')) {
517 +               if (*flags)
518 +                       exit_error(PARAMETER_PROBLEM, "MARK: can only specify "
519 +                                                     "one action");
520 +               if (invert)
521 +                       exit_error(PARAMETER_PROBLEM, "MARK: unexpected `!'");
522                 if (string_to_number(optarg, 0, 0xffffffff, 
523                                      (unsigned int *)&markinfo->mark))
524 -                       exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
525 -               if (*flags)
526 -                       exit_error(PARAMETER_PROBLEM,
527 -                                  "MARK target: Can't specify --set-mark twice");
528 +                       exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'",
529 +                                  optarg);
530                 *flags = 1;
531 -               break;
532 +       }
533  
534 -       default:
535 -               return 0;
536 +       switch (c) {
537 +               case '1':
538 +                       markinfo->mode = IPT_MARK_SET;
539 +                       break;
540 +               case '2':
541 +                       markinfo->mode = IPT_MARK_AND;
542 +                       break;
543 +               case '3':
544 +                       markinfo->mode = IPT_MARK_OR;
545 +                       break;
546 +               default:
547 +                       return 0;
548         }
549  
550         return 1;
551 @@ -71,12 +87,6 @@
552                            "MARK target: Parameter --set-mark is required");
553  }
554  
555 -static void
556 -print_mark(unsigned long mark, int numeric)
557 -{
558 -       printf("0x%lx ", mark);
559 -}
560 -
561  /* Prints out the targinfo. */
562  static void
563  print(const struct ipt_ip *ip,
564 @@ -85,8 +95,19 @@
565  {
566         const struct ipt_mark_target_info *markinfo =
567                 (const struct ipt_mark_target_info *)target->data;
568 -       printf("MARK set ");
569 -       print_mark(markinfo->mark, numeric);
570 +
571 +       switch (markinfo->mode) {
572 +       case IPT_MARK_SET:
573 +               printf("MARK set ");
574 +               break;
575 +       case IPT_MARK_AND:
576 +               printf("MARK and ");
577 +               break;
578 +       case IPT_MARK_OR:
579 +               printf("MARK or ");
580 +               break;
581 +       }
582 +       printf("0x%lx ", markinfo->mark);
583  }
584  
585  /* Saves the union ipt_targinfo in parsable form to stdout. */
586 @@ -96,7 +117,18 @@
587         const struct ipt_mark_target_info *markinfo =
588                 (const struct ipt_mark_target_info *)target->data;
589  
590 -       printf("--set-mark 0x%lx ", markinfo->mark);
591 +       switch (markinfo->mode) {
592 +       case IPT_MARK_SET:
593 +               printf("--set-mark ");
594 +               break;
595 +       case IPT_MARK_AND:
596 +               printf("--and-mark ");
597 +               break;
598 +       case IPT_MARK_OR:
599 +               printf("--or-mark ");
600 +               break;
601 +       }
602 +       printf("0x%lx ", markinfo->mark);
603  }
604  
605  static
606 diff -Nur iptables.org/extensions/libipt_helper.c iptables/extensions/libipt_helper.c
607 --- iptables.org/extensions/libipt_helper.c     2004-01-31 16:33:55.000000000 +0100
608 +++ iptables/extensions/libipt_helper.c 2004-05-18 12:39:27.000000000 +0200
609 @@ -45,8 +45,9 @@
610         switch (c) {
611         case '1':
612                 check_inverse(optarg, &invert, &invert, 0);
613 -               strncpy(info->name, optarg, 29);
614 -               info->name[29] = '\0';
615 +               memset(info->name, 0, sizeof(info->name));
616 +               if (strcmp(info->name, "any"))
617 +                       strncpy(info->name, optarg, 29);
618                 if (invert)
619                         info->invert = 1;
620                 *flags = 1;
621 @@ -74,8 +75,12 @@
622        int numeric)
623  {
624         struct ipt_helper_info *info = (struct ipt_helper_info *)match->data;
625 +       char *name = "any";
626  
627 -       printf("helper match %s\"%s\" ", info->invert ? "! " : "", info->name);
628 +       if (info->name[0] != '\0')
629 +               name = info->name;
630 +
631 +       printf("helper match %s\"%s\" ", info->invert ? "! " : "", name);
632  }
633  
634  /* Saves the union ipt_info in parsable form to stdout. */
635 diff -Nur iptables.org/extensions/libipt_policy.c iptables/extensions/libipt_policy.c
636 --- iptables.org/extensions/libipt_policy.c     1970-01-01 01:00:00.000000000 +0100
637 +++ iptables/extensions/libipt_policy.c 2004-05-18 12:39:55.000000000 +0200
638 @@ -0,0 +1,431 @@
639 +/* Shared library add-on to iptables to add policy support. */
640 +#include <stdio.h>
641 +#include <netdb.h>
642 +#include <string.h>
643 +#include <stdlib.h>
644 +#include <syslog.h>
645 +#include <getopt.h>
646 +#include <netdb.h>
647 +#include <errno.h>
648 +#include <sys/socket.h>
649 +#include <netinet/in.h>
650 +#include <arpa/inet.h>
651 +#include <iptables.h>
652 +
653 +#include <linux/netfilter_ipv4/ip_tables.h>
654 +#include <linux/netfilter_ipv4/ipt_policy.h>
655 +
656 +/*
657 + * HACK: global pointer to current matchinfo for making
658 + * final checks and adjustments in final_check.
659 + */
660 +static struct ipt_policy_info *policy_info;
661 +
662 +static void help(void)
663 +{
664 +       printf(
665 +"policy v%s options:\n"
666 +"  --dir in|out                        match policy applied during decapsulation/\n"
667 +"                              policy to be applied during encapsulation\n"
668 +"  --pol none|ipsec            match policy\n"
669 +"  --strict                    match entire policy instead of single element\n"
670 +"                              at any position\n"
671 +"[!] --reqid reqid             match reqid\n"
672 +"[!] --spi spi                 match SPI\n"
673 +"[!] --proto proto             match protocol (ah/esp/ipcomp)\n"
674 +"[!] --mode mode               match mode (transport/tunnel)\n"
675 +"[!] --tunnel-src addr/mask    match tunnel source\n"
676 +"[!] --tunnel-dst addr/mask    match tunnel destination\n"
677 +"  --next                      begin next element in policy\n",
678 +       IPTABLES_VERSION);
679 +}
680 +
681 +static struct option opts[] =
682 +{
683 +       {
684 +               .name           = "dir",
685 +               .has_arg        = 1,
686 +               .val            = '1',
687 +       },
688 +       {
689 +               .name           = "pol",
690 +               .has_arg        = 1,
691 +               .val            = '2',
692 +       },
693 +       {
694 +               .name           = "strict",
695 +               .val            = '3'
696 +       },
697 +       {
698 +               .name           = "reqid",
699 +               .has_arg        = 1,
700 +               .val            = '4',
701 +       },
702 +       {
703 +               .name           = "spi",
704 +               .has_arg        = 1,
705 +               .val            = '5'
706 +       },
707 +       {
708 +               .name           = "tunnel-src",
709 +               .has_arg        = 1,
710 +               .val            = '6'
711 +       },
712 +       {
713 +               .name           = "tunnel-dst",
714 +               .has_arg        = 1,
715 +               .val            = '7'
716 +       },
717 +       {
718 +               .name           = "proto",
719 +               .has_arg        = 1,
720 +               .val            = '8'
721 +       },
722 +       {
723 +               .name           = "mode",
724 +               .has_arg        = 1,
725 +               .val            = '9'
726 +       },
727 +       {
728 +               .name           = "next",
729 +               .val            = 'a'
730 +       },
731 +       { }
732 +};
733 +
734 +static void init(struct ipt_entry_match *m, unsigned int *nfcache)
735 +{
736 +       *nfcache |= NFC_UNKNOWN;
737 +}
738 +
739 +static int parse_direction(char *s)
740 +{
741 +       if (strcmp(s, "in") == 0)
742 +               return POLICY_MATCH_IN;
743 +       if (strcmp(s, "out") == 0)
744 +               return POLICY_MATCH_OUT;
745 +       exit_error(PARAMETER_PROBLEM, "policy_match: invalid dir `%s'", s);
746 +}
747 +
748 +static int parse_policy(char *s)
749 +{
750 +       if (strcmp(s, "none") == 0)
751 +               return POLICY_MATCH_NONE;
752 +       if (strcmp(s, "ipsec") == 0)
753 +               return 0;
754 +       exit_error(PARAMETER_PROBLEM, "policy match: invalid policy `%s'", s);
755 +}
756 +
757 +static int parse_mode(char *s)
758 +{
759 +       if (strcmp(s, "transport") == 0)
760 +               return POLICY_MODE_TRANSPORT;
761 +       if (strcmp(s, "tunnel") == 0)
762 +               return POLICY_MODE_TUNNEL;
763 +       exit_error(PARAMETER_PROBLEM, "policy match: invalid mode `%s'", s);
764 +}
765 +
766 +static int parse(int c, char **argv, int invert, unsigned int *flags,
767 +                 const struct ipt_entry *entry,
768 +                 unsigned int *nfcache,
769 +                 struct ipt_entry_match **match)
770 +{
771 +       struct ipt_policy_info *info = (void *)(*match)->data;
772 +       struct ipt_policy_elem *e = &info->pol[info->len];
773 +       struct in_addr *addr = NULL, mask;
774 +       unsigned int naddr = 0;
775 +       int mode;
776 +
777 +       check_inverse(optarg, &invert, &optind, 0);
778 +
779 +       switch (c) {
780 +       case '1':
781 +               if (info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))
782 +                       exit_error(PARAMETER_PROBLEM,
783 +                                  "policy match: double --dir option");
784 +               if (invert)
785 +                       exit_error(PARAMETER_PROBLEM,
786 +                                  "policy match: can't invert --dir option");
787 +
788 +               info->flags |= parse_direction(argv[optind-1]);
789 +               break;
790 +       case '2':
791 +               if (invert)
792 +                       exit_error(PARAMETER_PROBLEM,
793 +                                  "policy match: can't invert --policy option");
794 +
795 +               info->flags |= parse_policy(argv[optind-1]);
796 +               break;
797 +       case '3':
798 +               if (info->flags & POLICY_MATCH_STRICT)
799 +                       exit_error(PARAMETER_PROBLEM,
800 +                                  "policy match: double --strict option");
801 +
802 +               if (invert)
803 +                       exit_error(PARAMETER_PROBLEM,
804 +                                  "policy match: can't invert --strict option");
805 +
806 +               info->flags |= POLICY_MATCH_STRICT;
807 +               break;
808 +       case '4':
809 +               if (e->match.reqid)
810 +                       exit_error(PARAMETER_PROBLEM,
811 +                                  "policy match: double --reqid option");
812 +
813 +               e->match.reqid = 1;
814 +               e->invert.reqid = invert;
815 +               e->reqid = strtol(argv[optind-1], NULL, 10);
816 +               break;
817 +       case '5':
818 +               if (e->match.spi)
819 +                       exit_error(PARAMETER_PROBLEM,
820 +                                  "policy match: double --spi option");
821 +               
822 +               e->match.spi = 1;
823 +               e->invert.spi = invert;
824 +               e->spi = strtol(argv[optind-1], NULL, 0x10);
825 +               break;
826 +       case '6':
827 +               if (e->match.saddr)
828 +                       exit_error(PARAMETER_PROBLEM,
829 +                                  "policy match: double --tunnel-src option");
830 +
831 +               parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
832 +               if (naddr > 1)
833 +                       exit_error(PARAMETER_PROBLEM,
834 +                                  "policy match: name resolves to multiple IPs");
835 +
836 +               e->match.saddr = 1;
837 +               e->invert.saddr = invert;
838 +               e->saddr = addr[0].s_addr;
839 +               e->smask = mask.s_addr;
840 +                break;
841 +       case '7':
842 +               if (e->match.daddr)
843 +                       exit_error(PARAMETER_PROBLEM,
844 +                                  "policy match: double --tunnel-dst option");
845 +
846 +               parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
847 +               if (naddr > 1)
848 +                       exit_error(PARAMETER_PROBLEM,
849 +                                  "policy match: name resolves to multiple IPs");
850 +
851 +               e->match.daddr = 1;
852 +               e->invert.daddr = invert;
853 +               e->daddr = addr[0].s_addr;
854 +               e->dmask = mask.s_addr;
855 +               break;
856 +       case '8':
857 +               if (e->match.proto)
858 +                       exit_error(PARAMETER_PROBLEM,
859 +                                  "policy match: double --proto option");
860 +
861 +               e->proto = parse_protocol(argv[optind-1]);
862 +               if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
863 +                   e->proto != IPPROTO_COMP)
864 +                       exit_error(PARAMETER_PROBLEM,
865 +                                  "policy match: protocol must ah/esp/ipcomp");
866 +               e->match.proto = 1;
867 +               e->invert.proto = invert;
868 +               break;
869 +       case '9':
870 +               if (e->match.mode)
871 +                       exit_error(PARAMETER_PROBLEM,
872 +                                  "policy match: double --mode option");
873 +               
874 +               mode = parse_mode(argv[optind-1]);
875 +               e->match.mode = 1;
876 +               e->invert.mode = invert;
877 +               e->mode = mode;
878 +               break;
879 +       case 'a':
880 +               if (invert)
881 +                       exit_error(PARAMETER_PROBLEM,
882 +                                  "policy match: can't invert --next option");
883 +
884 +               if (++info->len == POLICY_MAX_ELEM)
885 +                       exit_error(PARAMETER_PROBLEM,
886 +                                  "policy match: maximum policy depth reached");
887 +               break;
888 +       default:
889 +               return 0;
890 +       }
891 +
892 +       policy_info = info;
893 +       return 1;
894 +}
895 +
896 +static void final_check(unsigned int flags)
897 +{
898 +       struct ipt_policy_info *info = policy_info;
899 +       struct ipt_policy_elem *e;
900 +       int i;
901 +
902 +       if (info == NULL)
903 +               exit_error(PARAMETER_PROBLEM,
904 +                          "policy match: no parameters given");
905 +
906 +       if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT)))
907 +               exit_error(PARAMETER_PROBLEM,
908 +                          "policy match: neither --in nor --out specified");
909 +
910 +       if (info->flags & POLICY_MATCH_NONE) {
911 +               if (info->flags & POLICY_MATCH_STRICT)
912 +                       exit_error(PARAMETER_PROBLEM,
913 +                                  "policy match: policy none but --strict given");
914 +
915 +               if (info->len != 0)
916 +                       exit_error(PARAMETER_PROBLEM,
917 +                                  "policy match: policy none but policy given");
918 +       } else
919 +               info->len++;    /* increase len by 1, no --next after last element */
920 +
921 +       if (!(info->flags & POLICY_MATCH_STRICT) && info->len > 1)
922 +               exit_error(PARAMETER_PROBLEM,
923 +                          "policy match: multiple elements but no --strict");
924 +
925 +       for (i = 0; i < info->len; i++) {
926 +               e = &info->pol[i];
927 +               if ((e->match.saddr || e->match.daddr)
928 +                   && ((e->mode == POLICY_MODE_TUNNEL && e->invert.mode) ||
929 +                       (e->mode == POLICY_MODE_TRANSPORT && !e->invert.mode)))
930 +                       exit_error(PARAMETER_PROBLEM,
931 +                                  "policy match: --tunnel-src/--tunnel-dst "
932 +                                  "is only valid in tunnel mode");
933 +       }
934 +}
935 +
936 +static void print_mode(char *prefix, u_int8_t mode, int numeric)
937 +{
938 +       printf("%smode ", prefix);
939 +
940 +       switch (mode) {
941 +       case POLICY_MODE_TRANSPORT:
942 +               printf("transport ");
943 +               break;
944 +       case POLICY_MODE_TUNNEL:
945 +               printf("tunnel ");
946 +               break;
947 +       default:
948 +               printf("??? ");
949 +               break;
950 +       }
951 +}
952 +
953 +static void print_proto(char *prefix, u_int8_t proto, int numeric)
954 +{
955 +       struct protoent *p = NULL;
956 +
957 +       printf("%sproto ", prefix);
958 +       if (!numeric)
959 +               p = getprotobynumber(proto);
960 +       if (p != NULL)
961 +               printf("%s ", p->p_name);
962 +       else
963 +               printf("%u ", proto);
964 +}
965 +
966 +#define PRINT_INVERT(x)                \
967 +do {                           \
968 +       if (x)                  \
969 +               printf("! ");   \
970 +} while(0)
971 +
972 +static void print_entry(char *prefix, const struct ipt_policy_elem *e,
973 +                        int numeric)
974 +{
975 +       if (e->match.reqid) {
976 +               PRINT_INVERT(e->invert.reqid);
977 +               printf("%sreqid %u ", prefix, e->reqid);
978 +       }
979 +       if (e->match.spi) {
980 +               PRINT_INVERT(e->invert.spi);
981 +               printf("%sspi 0x%x ", prefix, e->spi);
982 +       }
983 +       if (e->match.proto) {
984 +               PRINT_INVERT(e->invert.proto);
985 +               print_proto(prefix, e->proto, numeric);
986 +       }
987 +       if (e->match.mode) {
988 +               PRINT_INVERT(e->invert.mode);
989 +               print_mode(prefix, e->mode, numeric);
990 +       }
991 +       if (e->match.daddr) {
992 +               PRINT_INVERT(e->invert.daddr);
993 +               printf("%stunnel-dst %s%s ", prefix,
994 +                      addr_to_dotted((struct in_addr *)&e->daddr),
995 +                      mask_to_dotted((struct in_addr *)&e->dmask));
996 +       }
997 +       if (e->match.saddr) {
998 +               PRINT_INVERT(e->invert.saddr);
999 +               printf("%stunnel-src %s%s ", prefix,
1000 +                      addr_to_dotted((struct in_addr *)&e->saddr),
1001 +                      mask_to_dotted((struct in_addr *)&e->smask));
1002 +       }
1003 +}
1004 +
1005 +static void print_flags(char *prefix, const struct ipt_policy_info *info)
1006 +{
1007 +       if (info->flags & POLICY_MATCH_IN)
1008 +               printf("%sdir in ", prefix);
1009 +       else
1010 +               printf("%sdir out ", prefix);
1011 +
1012 +       if (info->flags & POLICY_MATCH_NONE)
1013 +               printf("%spol none ", prefix);
1014 +       else
1015 +               printf("%spol ipsec ", prefix);
1016 +
1017 +       if (info->flags & POLICY_MATCH_STRICT)
1018 +               printf("%sstrict ", prefix);
1019 +}
1020 +
1021 +static void print(const struct ipt_ip *ip,
1022 +                  const struct ipt_entry_match *match,
1023 +                 int numeric)
1024 +{
1025 +       const struct ipt_policy_info *info = (void *)match->data;
1026 +       unsigned int i;
1027 +
1028 +       printf("policy match ");
1029 +       print_flags("", info);
1030 +       for (i = 0; i < info->len; i++) {
1031 +               if (info->len > 1)
1032 +                       printf("[%u] ", i);
1033 +               print_entry("", &info->pol[i], numeric);
1034 +       }
1035 +}
1036 +
1037 +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
1038 +{
1039 +       const struct ipt_policy_info *info = (void *)match->data;
1040 +       unsigned int i;
1041 +
1042 +       print_flags("--", info);
1043 +       for (i = 0; i < info->len; i++) {
1044 +               print_entry("--", &info->pol[i], 0);
1045 +               if (i + 1 < info->len)
1046 +                       printf("--next ");
1047 +       }
1048 +
1049 +       printf("\n");
1050 +}
1051 +
1052 +struct iptables_match policy = {
1053 +       .name           = "policy",
1054 +       .version        = IPTABLES_VERSION,
1055 +       .size           = IPT_ALIGN(sizeof(struct ipt_policy_info)),
1056 +       .userspacesize  = IPT_ALIGN(sizeof(struct ipt_policy_info)),
1057 +       .help           = help,
1058 +       .init           = init,
1059 +       .parse          = parse,
1060 +       .final_check    = final_check,
1061 +       .print          = print,
1062 +       .save           = save,
1063 +       .extra_opts     = opts
1064 +};
1065 +
1066 +void _init(void)
1067 +{
1068 +       register_match(&policy);
1069 +}
1070 diff -Nur iptables.org/extensions/libipt_policy.man iptables/extensions/libipt_policy.man
1071 --- iptables.org/extensions/libipt_policy.man   1970-01-01 01:00:00.000000000 +0100
1072 +++ iptables/extensions/libipt_policy.man       2004-05-18 12:39:55.000000000 +0200
1073 @@ -0,0 +1,46 @@
1074 +This modules matches the policy used by IPsec for handling a packet.
1075 +.TP
1076 +.BI "--dir " "in|out"
1077 +Used to select whether to match the policy used for decapsulation or the
1078 +policy that will be used for encapsulation.
1079 +.B in
1080 +is valid in the
1081 +.B PREROUTING, INPUT and FORWARD
1082 +chains,
1083 +.B out
1084 +is valid in the
1085 +.B POSTROUTING, OUTPUT and FORWARD
1086 +chains.
1087 +.TP
1088 +.BI "--pol " "none|ipsec"
1089 +Matches if the packet is subject to IPsec processing.
1090 +.TP
1091 +.BI "--strict"
1092 +Selects whether to match the exact policy or match if any rule of
1093 +the policy matches the given policy.
1094 +.TP
1095 +.BI "--reqid " "id"
1096 +Matches the reqid of the policy rule. The reqid can be specified with
1097 +.B setkey(8)
1098 +using
1099 +.B unique:id
1100 +as level.
1101 +.TP
1102 +.BI "--spi " "spi"
1103 +Matches the SPI of the SA.
1104 +.TP
1105 +.BI "--proto " "ah|esp|ipcomp"
1106 +Matches the encapsulation protocol.
1107 +.TP
1108 +.BI "--mode " "tunnel|transport"
1109 +Matches the encapsulation mode.
1110 +.TP
1111 +.BI "--tunnel-src " "addr[/mask]"
1112 +Matches the source address of a tunnel. Only valid with --mode tunnel.
1113 +.TP
1114 +.BI "--tunnel-dst " "addr[/mask]"
1115 +Matches the destination address of a tunnel. Only valid with --mode tunnel.
1116 +.TP
1117 +.BI "--next"
1118 +Start the next element in the policy specification. Can only be used with
1119 +--strict
1120 diff -Nur iptables.org/ip6tables.c iptables/ip6tables.c
1121 --- iptables.org/ip6tables.c    2004-05-18 20:09:43.000000000 +0200
1122 +++ iptables/ip6tables.c        2004-04-07 11:36:29.000000000 +0200
1123 @@ -1433,8 +1433,6 @@
1124                         ret &= ip6tc_delete_entry(chain, fw, mask, handle);
1125                 }
1126         }
1127 -       free(mask);
1128 -
1129         return ret;
1130  }
1131  
1132 @@ -1656,8 +1654,6 @@
1133  
1134         for (matchp = *matches; matchp;) {
1135                 tmp = matchp->next;
1136 -               if (matchp->match->m)
1137 -                       free(matchp->match->m);
1138                 free(matchp);
1139                 matchp = tmp;
1140         }
1141 @@ -1692,6 +1688,9 @@
1142  
1143         memset(&fw, 0, sizeof(fw));
1144  
1145 +       opts = original_opts;
1146 +       global_option_offset = 0;
1147 +
1148         /* re-set optind to 0 in case do_command gets called
1149          * a second time */
1150         optind = 0;
1151 @@ -2197,9 +2196,6 @@
1152                         printf("Warning: using chain %s, not extension\n",
1153                                jumpto);
1154  
1155 -                       if (target->t)
1156 -                               free(target->t);
1157 -
1158                         target = NULL;
1159                 }
1160  
1161 @@ -2229,7 +2225,6 @@
1162                         find_target(jumpto, LOAD_MUST_SUCCEED);
1163                 } else {
1164                         e = generate_entry(&fw, matches, target->t);
1165 -                       free(target->t);
1166                 }
1167         }
1168  
1169 @@ -2307,22 +2302,5 @@
1170  
1171         clear_rule_matches(&matches);
1172  
1173 -       if (e != NULL) {
1174 -               free(e);
1175 -               e = NULL;
1176 -       }
1177 -
1178 -       for (c = 0; c < nsaddrs; c++)
1179 -               free(&saddrs[c]);
1180 -
1181 -       for (c = 0; c < ndaddrs; c++)
1182 -               free(&daddrs[c]);
1183 -
1184 -       if (opts != original_opts) {
1185 -               free(opts);
1186 -               opts = original_opts;
1187 -               global_option_offset = 0;
1188 -       }
1189 -
1190         return ret;
1191  }
1192 diff -Nur iptables.org/iptables.8.in iptables/iptables.8.in
1193 --- iptables.org/iptables.8.in  2004-03-17 15:26:08.000000000 +0100
1194 +++ iptables/iptables.8.in      2004-05-18 12:39:16.000000000 +0200
1195 @@ -274,10 +274,18 @@
1196  the fate of the packet immediately, or an extension (see
1197  .B EXTENSIONS
1198  below).  If this
1199 -option is omitted in a rule, then matching the rule will have no
1200 +option is omitted in a rule (and
1201 +.B -g
1202 +is not used), then matching the rule will have no
1203  effect on the packet's fate, but the counters on the rule will be
1204  incremented.
1205  .TP
1206 +.BI "-g, --goto " "chain"
1207 +This specifies that the processing should continue in a user
1208 +specified chain. Unlike the --jump option return will not continue
1209 +processing in this chain but instead in the chain that called us via
1210 +--jump.
1211 +.TP
1212  .BR "-i, --in-interface " "[!] \fIname\fP"
1213  Name of an interface via which a packet was received (only for
1214  packets entering the 
1215 diff -Nur iptables.org/iptables.c iptables/iptables.c
1216 --- iptables.org/iptables.c     2004-05-18 20:09:43.000000000 +0200
1217 +++ iptables/iptables.c 2004-05-18 12:39:16.000000000 +0200
1218 @@ -138,6 +138,7 @@
1219         { "line-numbers", 0, 0, '0' },
1220         { "modprobe", 1, 0, 'M' },
1221         { "set-counters", 1, 0, 'c' },
1222 +       { "goto", 1, 0, 'g' },
1223         { 0 }
1224  };
1225  
1226 @@ -397,6 +398,10 @@
1227  "                              network interface name ([+] for wildcard)\n"
1228  "  --jump      -j target\n"
1229  "                              target for rule (may load target extension)\n"
1230 +#ifdef IPT_F_GOTO
1231 +"  --goto      -g chain\n"
1232 +"                              jump to chain with no return\n"
1233 +#endif
1234  "  --match     -m match\n"
1235  "                              extended match (may load extension)\n"
1236  "  --numeric   -n              numeric output of addresses and ports\n"
1237 @@ -1431,8 +1436,6 @@
1238                         ret &= iptc_delete_entry(chain, fw, mask, handle);
1239                 }
1240         }
1241 -       free(mask);
1242 -
1243         return ret;
1244  }
1245  
1246 @@ -1654,8 +1657,6 @@
1247  
1248         for (matchp = *matches; matchp;) {
1249                 tmp = matchp->next;
1250 -               if (matchp->match->m)
1251 -                       free(matchp->match->m);
1252                 free(matchp);
1253                 matchp = tmp;
1254         }
1255 @@ -1689,6 +1690,9 @@
1256  
1257         memset(&fw, 0, sizeof(fw));
1258  
1259 +       opts = original_opts;
1260 +       global_option_offset = 0;
1261 +
1262         /* re-set optind to 0 in case do_command gets called
1263          * a second time */
1264         optind = 0;
1265 @@ -1708,7 +1712,7 @@
1266         opterr = 0;
1267  
1268         while ((c = getopt_long(argc, argv,
1269 -          "-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:",
1270 +          "-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:",
1271                                            opts, NULL)) != -1) {
1272                 switch (c) {
1273                         /*
1274 @@ -1879,6 +1883,15 @@
1275                         fw.nfcache |= NFC_IP_DST;
1276                         break;
1277  
1278 +#ifdef IPT_F_GOTO
1279 +               case 'g':
1280 +                       set_option(&options, OPT_JUMP, &fw.ip.invflags,
1281 +                                  invert);
1282 +                       fw.ip.flags |= IPT_F_GOTO;
1283 +                       jumpto = parse_target(optarg);
1284 +                       break;
1285 +#endif
1286 +
1287                 case 'j':
1288                         set_option(&options, OPT_JUMP, &fw.ip.invflags,
1289                                    invert);
1290 @@ -2197,9 +2210,6 @@
1291                         printf("Warning: using chain %s, not extension\n",
1292                                jumpto);
1293  
1294 -                       if (target->t)
1295 -                               free(target->t);
1296 -
1297                         target = NULL;
1298                 }
1299  
1300 @@ -2226,10 +2236,14 @@
1301                          * We cannot know if the plugin is corrupt, non
1302                          * existant OR if the user just misspelled a
1303                          * chain. */
1304 +#ifdef IPT_F_GOTO
1305 +                       if (fw.ip.flags & IPT_F_GOTO)
1306 +                               exit_error(PARAMETER_PROBLEM,
1307 +                                          "goto '%s' is not a chain\n", jumpto);
1308 +#endif
1309                         find_target(jumpto, LOAD_MUST_SUCCEED);
1310                 } else {
1311                         e = generate_entry(&fw, matches, target->t);
1312 -                       free(target->t);
1313                 }
1314         }
1315  
1316 @@ -2307,22 +2321,5 @@
1317  
1318         clear_rule_matches(&matches);
1319  
1320 -       if (e != NULL) {
1321 -               free(e);
1322 -               e = NULL;
1323 -       }
1324 -
1325 -       for (c = 0; c < nsaddrs; c++)
1326 -               free(&saddrs[c]);
1327 -
1328 -       for (c = 0; c < ndaddrs; c++)
1329 -               free(&daddrs[c]);
1330 -
1331 -       if (opts != original_opts) {
1332 -               free(opts);
1333 -               opts = original_opts;
1334 -               global_option_offset = 0;
1335 -       }
1336 -
1337         return ret;
1338  }
This page took 0.185915 seconds and 3 git commands to generate.