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-06-29 12:35:40.000000000 +0200
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-06-29 12:35:40.000000000 +0200
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-06-29 12:35:40.000000000 +0200
19 +/* Shared library add-on to iptables to add policy support. */
29 +#include <sys/socket.h>
30 +#include <netinet/in.h>
31 +#include <arpa/inet.h>
32 +#include <ip6tables.h>
34 +#include <linux/netfilter_ipv6/ip6_tables.h>
35 +#include <linux/netfilter_ipv6/ip6t_policy.h>
38 + * HACK: global pointer to current matchinfo for making
39 + * final checks and adjustments in final_check.
41 +static struct ip6t_policy_info *policy_info;
43 +static void help(void)
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"
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",
62 +static struct option opts[] =
89 + .name = "tunnel-src",
94 + .name = "tunnel-dst",
115 +/* FIXME - Duplicated code from ip6tables.c */
116 +/* Duplicated to stop too many changes in other files .... */
118 +in6addrcpy(struct in6_addr *dst, struct in6_addr *src)
120 + memcpy(dst, src, sizeof(struct in6_addr));
121 + /* dst->s6_addr = src->s6_addr; */
125 +addr_to_numeric(const struct in6_addr *addrp)
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));
134 +mask_to_numeric(const struct in6_addr *addrp)
136 + static char buf[50+2];
137 + int l = ipv6_prefix_length(addrp);
140 + strcat(buf, addr_to_numeric(addrp));
143 + sprintf(buf, "/%d", l);
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);
152 +/* End duplicated code from ip6tables.c */
154 +static void init(struct ip6t_entry_match *m, unsigned int *nfcache)
156 + *nfcache |= NFC_UNKNOWN;
159 +static int parse_direction(char *s)
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);
168 +static int parse_policy(char *s)
170 + if (strcmp(s, "none") == 0)
171 + return POLICY_MATCH_NONE;
172 + if (strcmp(s, "ipsec") == 0)
174 + exit_error(PARAMETER_PROBLEM, "policy match: invalid policy `%s'", s);
177 +static int parse_mode(char *s)
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);
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)
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;
197 + check_inverse(optarg, &invert, &optind, 0);
201 + if (info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))
202 + exit_error(PARAMETER_PROBLEM,
203 + "policy match: double --dir option");
205 + exit_error(PARAMETER_PROBLEM,
206 + "policy match: can't invert --dir option");
208 + info->flags |= parse_direction(argv[optind-1]);
212 + exit_error(PARAMETER_PROBLEM,
213 + "policy match: can't invert --policy option");
215 + info->flags |= parse_policy(argv[optind-1]);
218 + if (info->flags & POLICY_MATCH_STRICT)
219 + exit_error(PARAMETER_PROBLEM,
220 + "policy match: double --strict option");
223 + exit_error(PARAMETER_PROBLEM,
224 + "policy match: can't invert --strict option");
226 + info->flags |= POLICY_MATCH_STRICT;
229 + if (e->match.reqid)
230 + exit_error(PARAMETER_PROBLEM,
231 + "policy match: double --reqid option");
233 + e->match.reqid = 1;
234 + e->invert.reqid = invert;
235 + e->reqid = strtol(argv[optind-1], NULL, 10);
239 + exit_error(PARAMETER_PROBLEM,
240 + "policy match: double --spi option");
243 + e->invert.spi = invert;
244 + e->spi = strtol(argv[optind-1], NULL, 0x10);
247 + if (e->match.saddr)
248 + exit_error(PARAMETER_PROBLEM,
249 + "policy match: double --tunnel-src option");
251 + parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
253 + exit_error(PARAMETER_PROBLEM,
254 + "policy match: name resolves to multiple IPs");
256 + e->match.saddr = 1;
257 + e->invert.saddr = invert;
258 + in6addrcpy(&e->daddr, addr);
259 + in6addrcpy(&e->dmask, &mask);
262 + if (e->match.daddr)
263 + exit_error(PARAMETER_PROBLEM,
264 + "policy match: double --tunnel-dst option");
266 + parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
268 + exit_error(PARAMETER_PROBLEM,
269 + "policy match: name resolves to multiple IPs");
271 + e->match.daddr = 1;
272 + e->invert.daddr = invert;
273 + in6addrcpy(&e->daddr, addr);
274 + in6addrcpy(&e->dmask, &mask);
277 + if (e->match.proto)
278 + exit_error(PARAMETER_PROBLEM,
279 + "policy match: double --proto option");
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;
291 + exit_error(PARAMETER_PROBLEM,
292 + "policy match: double --mode option");
294 + mode = parse_mode(argv[optind-1]);
296 + e->invert.mode = invert;
301 + exit_error(PARAMETER_PROBLEM,
302 + "policy match: can't invert --next option");
304 + if (++info->len == POLICY_MAX_ELEM)
305 + exit_error(PARAMETER_PROBLEM,
306 + "policy match: maximum policy depth reached");
312 + policy_info = info;
316 +static void final_check(unsigned int flags)
318 + struct ip6t_policy_info *info = policy_info;
319 + struct ip6t_policy_elem *e;
323 + exit_error(PARAMETER_PROBLEM,
324 + "policy match: no parameters given");
326 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT)))
327 + exit_error(PARAMETER_PROBLEM,
328 + "policy match: neither --in nor --out specified");
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");
335 + if (info->len != 0)
336 + exit_error(PARAMETER_PROBLEM,
337 + "policy match: policy none but policy given");
339 + info->len++; /* increase len by 1, no --next after last element */
341 + if (!(info->flags & POLICY_MATCH_STRICT) && info->len > 1)
342 + exit_error(PARAMETER_PROBLEM,
343 + "policy match: multiple elements but no --strict");
345 + for (i = 0; i < info->len; 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");
356 +static void print_mode(char *prefix, u_int8_t mode, int numeric)
358 + printf("%smode ", prefix);
361 + case POLICY_MODE_TRANSPORT:
362 + printf("transport ");
364 + case POLICY_MODE_TUNNEL:
373 +static void print_proto(char *prefix, u_int8_t proto, int numeric)
375 + struct protoent *p = NULL;
377 + printf("%sproto ", prefix);
379 + p = getprotobynumber(proto);
381 + printf("%s ", p->p_name);
383 + printf("%u ", proto);
386 +#define PRINT_INVERT(x) \
392 +static void print_entry(char *prefix, const struct ip6t_policy_elem *e,
395 + if (e->match.reqid) {
396 + PRINT_INVERT(e->invert.reqid);
397 + printf("%sreqid %u ", prefix, e->reqid);
399 + if (e->match.spi) {
400 + PRINT_INVERT(e->invert.spi);
401 + printf("%sspi 0x%x ", prefix, e->spi);
403 + if (e->match.proto) {
404 + PRINT_INVERT(e->invert.proto);
405 + print_proto(prefix, e->proto, numeric);
407 + if (e->match.mode) {
408 + PRINT_INVERT(e->invert.mode);
409 + print_mode(prefix, e->mode, numeric);
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));
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));
425 +static void print_flags(char *prefix, const struct ip6t_policy_info *info)
427 + if (info->flags & POLICY_MATCH_IN)
428 + printf("%sdir in ", prefix);
430 + printf("%sdir out ", prefix);
432 + if (info->flags & POLICY_MATCH_NONE)
433 + printf("%spol none ", prefix);
435 + printf("%spol ipsec ", prefix);
437 + if (info->flags & POLICY_MATCH_STRICT)
438 + printf("%sstrict ", prefix);
441 +static void print(const struct ip6t_ip6 *ip,
442 + const struct ip6t_entry_match *match,
445 + const struct ip6t_policy_info *info = (void *)match->data;
448 + printf("policy match ");
449 + print_flags("", info);
450 + for (i = 0; i < info->len; i++) {
452 + printf("[%u] ", i);
453 + print_entry("", &info->pol[i], numeric);
459 +static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
461 + const struct ip6t_policy_info *info = (void *)match->data;
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)
472 +struct ip6tables_match policy = {
474 + .version = IPTABLES_VERSION,
475 + .size = IP6T_ALIGN(sizeof(struct ip6t_policy_info)),
476 + .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_policy_info)),
480 + .final_check = final_check,
488 + register_match6(&policy);
490 diff -Nur iptables.org/extensions/libipt_policy.c iptables/extensions/libipt_policy.c
491 --- iptables.org/extensions/libipt_policy.c 1970-01-01 01:00:00.000000000 +0100
492 +++ iptables/extensions/libipt_policy.c 2004-06-29 12:35:40.000000000 +0200
494 +/* Shared library add-on to iptables to add policy support. */
503 +#include <sys/socket.h>
504 +#include <netinet/in.h>
505 +#include <arpa/inet.h>
506 +#include <iptables.h>
508 +#include <linux/netfilter_ipv4/ip_tables.h>
509 +#include <linux/netfilter_ipv4/ipt_policy.h>
512 + * HACK: global pointer to current matchinfo for making
513 + * final checks and adjustments in final_check.
515 +static struct ipt_policy_info *policy_info;
517 +static void help(void)
520 +"policy v%s options:\n"
521 +" --dir in|out match policy applied during decapsulation/\n"
522 +" policy to be applied during encapsulation\n"
523 +" --pol none|ipsec match policy\n"
524 +" --strict match entire policy instead of single element\n"
525 +" at any position\n"
526 +"[!] --reqid reqid match reqid\n"
527 +"[!] --spi spi match SPI\n"
528 +"[!] --proto proto match protocol (ah/esp/ipcomp)\n"
529 +"[!] --mode mode match mode (transport/tunnel)\n"
530 +"[!] --tunnel-src addr/mask match tunnel source\n"
531 +"[!] --tunnel-dst addr/mask match tunnel destination\n"
532 +" --next begin next element in policy\n",
536 +static struct option opts[] =
563 + .name = "tunnel-src",
568 + .name = "tunnel-dst",
589 +static void init(struct ipt_entry_match *m, unsigned int *nfcache)
591 + *nfcache |= NFC_UNKNOWN;
594 +static int parse_direction(char *s)
596 + if (strcmp(s, "in") == 0)
597 + return POLICY_MATCH_IN;
598 + if (strcmp(s, "out") == 0)
599 + return POLICY_MATCH_OUT;
600 + exit_error(PARAMETER_PROBLEM, "policy_match: invalid dir `%s'", s);
603 +static int parse_policy(char *s)
605 + if (strcmp(s, "none") == 0)
606 + return POLICY_MATCH_NONE;
607 + if (strcmp(s, "ipsec") == 0)
609 + exit_error(PARAMETER_PROBLEM, "policy match: invalid policy `%s'", s);
612 +static int parse_mode(char *s)
614 + if (strcmp(s, "transport") == 0)
615 + return POLICY_MODE_TRANSPORT;
616 + if (strcmp(s, "tunnel") == 0)
617 + return POLICY_MODE_TUNNEL;
618 + exit_error(PARAMETER_PROBLEM, "policy match: invalid mode `%s'", s);
621 +static int parse(int c, char **argv, int invert, unsigned int *flags,
622 + const struct ipt_entry *entry,
623 + unsigned int *nfcache,
624 + struct ipt_entry_match **match)
626 + struct ipt_policy_info *info = (void *)(*match)->data;
627 + struct ipt_policy_elem *e = &info->pol[info->len];
628 + struct in_addr *addr = NULL, mask;
629 + unsigned int naddr = 0;
632 + check_inverse(optarg, &invert, &optind, 0);
636 + if (info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))
637 + exit_error(PARAMETER_PROBLEM,
638 + "policy match: double --dir option");
640 + exit_error(PARAMETER_PROBLEM,
641 + "policy match: can't invert --dir option");
643 + info->flags |= parse_direction(argv[optind-1]);
647 + exit_error(PARAMETER_PROBLEM,
648 + "policy match: can't invert --policy option");
650 + info->flags |= parse_policy(argv[optind-1]);
653 + if (info->flags & POLICY_MATCH_STRICT)
654 + exit_error(PARAMETER_PROBLEM,
655 + "policy match: double --strict option");
658 + exit_error(PARAMETER_PROBLEM,
659 + "policy match: can't invert --strict option");
661 + info->flags |= POLICY_MATCH_STRICT;
664 + if (e->match.reqid)
665 + exit_error(PARAMETER_PROBLEM,
666 + "policy match: double --reqid option");
668 + e->match.reqid = 1;
669 + e->invert.reqid = invert;
670 + e->reqid = strtol(argv[optind-1], NULL, 10);
674 + exit_error(PARAMETER_PROBLEM,
675 + "policy match: double --spi option");
678 + e->invert.spi = invert;
679 + e->spi = strtol(argv[optind-1], NULL, 0x10);
682 + if (e->match.saddr)
683 + exit_error(PARAMETER_PROBLEM,
684 + "policy match: double --tunnel-src option");
686 + parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
688 + exit_error(PARAMETER_PROBLEM,
689 + "policy match: name resolves to multiple IPs");
691 + e->match.saddr = 1;
692 + e->invert.saddr = invert;
693 + e->saddr = addr[0].s_addr;
694 + e->smask = mask.s_addr;
697 + if (e->match.daddr)
698 + exit_error(PARAMETER_PROBLEM,
699 + "policy match: double --tunnel-dst option");
701 + parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
703 + exit_error(PARAMETER_PROBLEM,
704 + "policy match: name resolves to multiple IPs");
706 + e->match.daddr = 1;
707 + e->invert.daddr = invert;
708 + e->daddr = addr[0].s_addr;
709 + e->dmask = mask.s_addr;
712 + if (e->match.proto)
713 + exit_error(PARAMETER_PROBLEM,
714 + "policy match: double --proto option");
716 + e->proto = parse_protocol(argv[optind-1]);
717 + if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
718 + e->proto != IPPROTO_COMP)
719 + exit_error(PARAMETER_PROBLEM,
720 + "policy match: protocol must ah/esp/ipcomp");
721 + e->match.proto = 1;
722 + e->invert.proto = invert;
726 + exit_error(PARAMETER_PROBLEM,
727 + "policy match: double --mode option");
729 + mode = parse_mode(argv[optind-1]);
731 + e->invert.mode = invert;
736 + exit_error(PARAMETER_PROBLEM,
737 + "policy match: can't invert --next option");
739 + if (++info->len == POLICY_MAX_ELEM)
740 + exit_error(PARAMETER_PROBLEM,
741 + "policy match: maximum policy depth reached");
747 + policy_info = info;
751 +static void final_check(unsigned int flags)
753 + struct ipt_policy_info *info = policy_info;
754 + struct ipt_policy_elem *e;
758 + exit_error(PARAMETER_PROBLEM,
759 + "policy match: no parameters given");
761 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT)))
762 + exit_error(PARAMETER_PROBLEM,
763 + "policy match: neither --in nor --out specified");
765 + if (info->flags & POLICY_MATCH_NONE) {
766 + if (info->flags & POLICY_MATCH_STRICT)
767 + exit_error(PARAMETER_PROBLEM,
768 + "policy match: policy none but --strict given");
770 + if (info->len != 0)
771 + exit_error(PARAMETER_PROBLEM,
772 + "policy match: policy none but policy given");
774 + info->len++; /* increase len by 1, no --next after last element */
776 + if (!(info->flags & POLICY_MATCH_STRICT) && info->len > 1)
777 + exit_error(PARAMETER_PROBLEM,
778 + "policy match: multiple elements but no --strict");
780 + for (i = 0; i < info->len; i++) {
782 + if ((e->match.saddr || e->match.daddr)
783 + && ((e->mode == POLICY_MODE_TUNNEL && e->invert.mode) ||
784 + (e->mode == POLICY_MODE_TRANSPORT && !e->invert.mode)))
785 + exit_error(PARAMETER_PROBLEM,
786 + "policy match: --tunnel-src/--tunnel-dst "
787 + "is only valid in tunnel mode");
791 +static void print_mode(char *prefix, u_int8_t mode, int numeric)
793 + printf("%smode ", prefix);
796 + case POLICY_MODE_TRANSPORT:
797 + printf("transport ");
799 + case POLICY_MODE_TUNNEL:
808 +static void print_proto(char *prefix, u_int8_t proto, int numeric)
810 + struct protoent *p = NULL;
812 + printf("%sproto ", prefix);
814 + p = getprotobynumber(proto);
816 + printf("%s ", p->p_name);
818 + printf("%u ", proto);
821 +#define PRINT_INVERT(x) \
827 +static void print_entry(char *prefix, const struct ipt_policy_elem *e,
830 + if (e->match.reqid) {
831 + PRINT_INVERT(e->invert.reqid);
832 + printf("%sreqid %u ", prefix, e->reqid);
834 + if (e->match.spi) {
835 + PRINT_INVERT(e->invert.spi);
836 + printf("%sspi 0x%x ", prefix, e->spi);
838 + if (e->match.proto) {
839 + PRINT_INVERT(e->invert.proto);
840 + print_proto(prefix, e->proto, numeric);
842 + if (e->match.mode) {
843 + PRINT_INVERT(e->invert.mode);
844 + print_mode(prefix, e->mode, numeric);
846 + if (e->match.daddr) {
847 + PRINT_INVERT(e->invert.daddr);
848 + printf("%stunnel-dst %s%s ", prefix,
849 + addr_to_dotted((struct in_addr *)&e->daddr),
850 + mask_to_dotted((struct in_addr *)&e->dmask));
852 + if (e->match.saddr) {
853 + PRINT_INVERT(e->invert.saddr);
854 + printf("%stunnel-src %s%s ", prefix,
855 + addr_to_dotted((struct in_addr *)&e->saddr),
856 + mask_to_dotted((struct in_addr *)&e->smask));
860 +static void print_flags(char *prefix, const struct ipt_policy_info *info)
862 + if (info->flags & POLICY_MATCH_IN)
863 + printf("%sdir in ", prefix);
865 + printf("%sdir out ", prefix);
867 + if (info->flags & POLICY_MATCH_NONE)
868 + printf("%spol none ", prefix);
870 + printf("%spol ipsec ", prefix);
872 + if (info->flags & POLICY_MATCH_STRICT)
873 + printf("%sstrict ", prefix);
876 +static void print(const struct ipt_ip *ip,
877 + const struct ipt_entry_match *match,
880 + const struct ipt_policy_info *info = (void *)match->data;
883 + printf("policy match ");
884 + print_flags("", info);
885 + for (i = 0; i < info->len; i++) {
887 + printf("[%u] ", i);
888 + print_entry("", &info->pol[i], numeric);
892 +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
894 + const struct ipt_policy_info *info = (void *)match->data;
897 + print_flags("--", info);
898 + for (i = 0; i < info->len; i++) {
899 + print_entry("--", &info->pol[i], 0);
900 + if (i + 1 < info->len)
907 +struct iptables_match policy = {
909 + .version = IPTABLES_VERSION,
910 + .size = IPT_ALIGN(sizeof(struct ipt_policy_info)),
911 + .userspacesize = IPT_ALIGN(sizeof(struct ipt_policy_info)),
915 + .final_check = final_check,
923 + register_match(&policy);
925 diff -Nur iptables.org/extensions/libipt_policy.man iptables/extensions/libipt_policy.man
926 --- iptables.org/extensions/libipt_policy.man 1970-01-01 01:00:00.000000000 +0100
927 +++ iptables/extensions/libipt_policy.man 2004-06-29 12:35:40.000000000 +0200
929 +This modules matches the policy used by IPsec for handling a packet.
931 +.BI "--dir " "in|out"
932 +Used to select whether to match the policy used for decapsulation or the
933 +policy that will be used for encapsulation.
936 +.B PREROUTING, INPUT and FORWARD
940 +.B POSTROUTING, OUTPUT and FORWARD
943 +.BI "--pol " "none|ipsec"
944 +Matches if the packet is subject to IPsec processing.
947 +Selects whether to match the exact policy or match if any rule of
948 +the policy matches the given policy.
951 +Matches the reqid of the policy rule. The reqid can be specified with
958 +Matches the SPI of the SA.
960 +.BI "--proto " "ah|esp|ipcomp"
961 +Matches the encapsulation protocol.
963 +.BI "--mode " "tunnel|transport"
964 +Matches the encapsulation mode.
966 +.BI "--tunnel-src " "addr[/mask]"
967 +Matches the source address of a tunnel. Only valid with --mode tunnel.
969 +.BI "--tunnel-dst " "addr[/mask]"
970 +Matches the destination address of a tunnel. Only valid with --mode tunnel.
973 +Start the next element in the policy specification. Can only be used with
975 diff -Nur iptables.org/include/libipq/libipq.h iptables/include/libipq/libipq.h
976 --- iptables.org/include/libipq/libipq.h 2003-09-07 12:09:22.000000000 +0200
977 +++ iptables/include/libipq/libipq.h 2004-06-29 12:35:08.000000000 +0200
982 +int ipq_set_vwmark(const struct ipq_handle *h,
984 + unsigned int verdict,
985 + unsigned long nfmark,
987 + unsigned char *buf);
989 int ipq_ctl(const struct ipq_handle *h, int request, ...);
991 char *ipq_errstr(void);
992 diff -Nur iptables.org/libipq/libipq.c iptables/libipq/libipq.c
993 --- iptables.org/libipq/libipq.c 2003-11-14 20:17:45.000000000 +0100
994 +++ iptables/libipq/libipq.c 2004-06-29 12:35:08.000000000 +0200
996 return ipq_netlink_sendmsg(h, &msg, 0);
999 +int ipq_set_vwmark(const struct ipq_handle *h,
1001 + unsigned int verdict,
1002 + unsigned long nfmark,
1004 + unsigned char *buf)
1006 + unsigned char nvecs;
1008 + struct nlmsghdr nlh;
1009 + ipq_peer_msg_t pm;
1010 + struct iovec iov[3];
1011 + struct msghdr msg;
1013 + memset(&nlh, 0, sizeof(nlh));
1014 + nlh.nlmsg_flags = NLM_F_REQUEST;
1015 + nlh.nlmsg_type = IPQM_VWMARK;
1016 + nlh.nlmsg_pid = h->local.nl_pid;
1017 + memset(&pm, 0, sizeof(pm));
1018 + pm.msg.vwmark.value = verdict;
1019 + pm.msg.vwmark.id = id;
1020 + pm.msg.vwmark.data_len = data_len;
1021 + pm.msg.vwmark.nfmark = nfmark;
1022 + iov[0].iov_base = &nlh;
1023 + iov[0].iov_len = sizeof(nlh);
1024 + iov[1].iov_base = ±
1025 + iov[1].iov_len = sizeof(pm);
1026 + tlen = sizeof(nlh) + sizeof(pm);
1028 + if (data_len && buf) {
1029 + iov[2].iov_base = buf;
1030 + iov[2].iov_len = data_len;
1034 + msg.msg_name = (void *)&h->peer;
1035 + msg.msg_namelen = sizeof(h->peer);
1036 + msg.msg_iov = iov;
1037 + msg.msg_iovlen = nvecs;
1038 + msg.msg_control = NULL;
1039 + msg.msg_controllen = 0;
1040 + msg.msg_flags = 0;
1041 + nlh.nlmsg_len = tlen;
1042 + return ipq_netlink_sendmsg(h, &msg, 0);
1047 /* Not implemented yet */
1048 int ipq_ctl(const struct ipq_handle *h, int request, ...)
1050 diff -Nur iptables.org/libipq/libipq.c.orig iptables/libipq/libipq.c.orig
1051 --- iptables.org/libipq/libipq.c.orig 1970-01-01 01:00:00.000000000 +0100
1052 +++ iptables/libipq/libipq.c.orig 2003-11-14 20:17:45.000000000 +0100
1057 + * IPQ userspace library.
1059 + * Please note that this library is still developmental, and there may
1060 + * be some API changes.
1062 + * Author: James Morris <jmorris@intercode.com.au>
1064 + * 07-11-2001 Modified by Fernando Anton to add support for IPv6.
1066 + * Copyright (c) 2000-2001 Netfilter Core Team
1068 + * This program is free software; you can redistribute it and/or modify
1069 + * it under the terms of the GNU General Public License as published by
1070 + * the Free Software Foundation; either version 2 of the License, or
1071 + * (at your option) any later version.
1073 + * This program is distributed in the hope that it will be useful,
1074 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1075 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1076 + * GNU General Public License for more details.
1080 +#include <stdlib.h>
1082 +#include <string.h>
1083 +#include <unistd.h>
1084 +#include <sys/time.h>
1085 +#include <sys/types.h>
1087 +#include <libipq/libipq.h>
1089 +/****************************************************************************
1091 + * Private interface
1093 + ****************************************************************************/
1114 +#define IPQ_MAXERR IPQ_ERR_PROTOCOL
1116 +struct ipq_errmap_t {
1120 + { IPQ_ERR_NONE, "Unknown error" },
1121 + { IPQ_ERR_IMPL, "Implementation error" },
1122 + { IPQ_ERR_HANDLE, "Unable to create netlink handle" },
1123 + { IPQ_ERR_SOCKET, "Unable to create netlink socket" },
1124 + { IPQ_ERR_BIND, "Unable to bind netlink socket" },
1125 + { IPQ_ERR_BUFFER, "Unable to allocate buffer" },
1126 + { IPQ_ERR_RECV, "Failed to receive netlink message" },
1127 + { IPQ_ERR_NLEOF, "Received EOF on netlink socket" },
1128 + { IPQ_ERR_ADDRLEN, "Invalid peer address length" },
1129 + { IPQ_ERR_STRUNC, "Sent message truncated" },
1130 + { IPQ_ERR_RTRUNC, "Received message truncated" },
1131 + { IPQ_ERR_NLRECV, "Received error from netlink" },
1132 + { IPQ_ERR_SEND, "Failed to send netlink message" },
1133 + { IPQ_ERR_SUPP, "Operation not supported" },
1134 + { IPQ_ERR_RECVBUF, "Receive buffer size invalid" },
1135 + { IPQ_ERR_TIMEOUT, "Timeout"},
1136 + { IPQ_ERR_PROTOCOL, "Invalid protocol specified" }
1139 +static int ipq_errno = IPQ_ERR_NONE;
1141 +static ssize_t ipq_netlink_sendto(const struct ipq_handle *h,
1142 + const void *msg, size_t len);
1144 +static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
1145 + unsigned char *buf, size_t len,
1148 +static ssize_t ipq_netlink_sendmsg(const struct ipq_handle *h,
1149 + const struct msghdr *msg,
1150 + unsigned int flags);
1152 +static char *ipq_strerror(int errcode);
1154 +static ssize_t ipq_netlink_sendto(const struct ipq_handle *h,
1155 + const void *msg, size_t len)
1157 + int status = sendto(h->fd, msg, len, 0,
1158 + (struct sockaddr *)&h->peer, sizeof(h->peer));
1160 + ipq_errno = IPQ_ERR_SEND;
1164 +static ssize_t ipq_netlink_sendmsg(const struct ipq_handle *h,
1165 + const struct msghdr *msg,
1166 + unsigned int flags)
1168 + int status = sendmsg(h->fd, msg, flags);
1170 + ipq_errno = IPQ_ERR_SEND;
1174 +static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
1175 + unsigned char *buf, size_t len,
1178 + int addrlen, status;
1179 + struct nlmsghdr *nlh;
1181 + if (len < sizeof(struct nlmsgerr)) {
1182 + ipq_errno = IPQ_ERR_RECVBUF;
1185 + addrlen = sizeof(h->peer);
1187 + if (timeout != 0) {
1189 + struct timeval tv;
1192 + if (timeout < 0) {
1193 + /* non-block non-timeout */
1197 + tv.tv_sec = timeout / 1000000;
1198 + tv.tv_usec = timeout % 1000000;
1201 + FD_ZERO(&read_fds);
1202 + FD_SET(h->fd, &read_fds);
1203 + ret = select(h->fd+1, &read_fds, NULL, NULL, &tv);
1205 + if (errno == EINTR) {
1208 + ipq_errno = IPQ_ERR_RECV;
1212 + if (!FD_ISSET(h->fd, &read_fds)) {
1213 + ipq_errno = IPQ_ERR_TIMEOUT;
1217 + status = recvfrom(h->fd, buf, len, 0,
1218 + (struct sockaddr *)&h->peer, &addrlen);
1220 + ipq_errno = IPQ_ERR_RECV;
1223 + if (addrlen != sizeof(h->peer)) {
1224 + ipq_errno = IPQ_ERR_RECV;
1227 + if (h->peer.nl_pid != 0) {
1228 + ipq_errno = IPQ_ERR_RECV;
1231 + if (status == 0) {
1232 + ipq_errno = IPQ_ERR_NLEOF;
1235 + nlh = (struct nlmsghdr *)buf;
1236 + if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
1237 + ipq_errno = IPQ_ERR_RTRUNC;
1243 +static char *ipq_strerror(int errcode)
1245 + if (errcode < 0 || errcode > IPQ_MAXERR)
1246 + errcode = IPQ_ERR_IMPL;
1247 + return ipq_errmap[errcode].message;
1250 +/****************************************************************************
1252 + * Public interface
1254 + ****************************************************************************/
1257 + * Create and initialise an ipq handle.
1259 +struct ipq_handle *ipq_create_handle(u_int32_t flags, u_int32_t protocol)
1262 + struct ipq_handle *h;
1264 + h = (struct ipq_handle *)malloc(sizeof(struct ipq_handle));
1266 + ipq_errno = IPQ_ERR_HANDLE;
1270 + memset(h, 0, sizeof(struct ipq_handle));
1272 + if (protocol == PF_INET)
1273 + h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);
1274 + else if (protocol == PF_INET6)
1275 + h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_IP6_FW);
1277 + ipq_errno = IPQ_ERR_PROTOCOL;
1282 + if (h->fd == -1) {
1283 + ipq_errno = IPQ_ERR_SOCKET;
1288 + memset(&h->local, 0, sizeof(struct sockaddr_nl));
1289 + h->local.nl_family = AF_NETLINK;
1290 + h->local.nl_pid = getpid();
1291 + h->local.nl_groups = 0;
1292 + status = bind(h->fd, (struct sockaddr *)&h->local, sizeof(h->local));
1293 + if (status == -1) {
1294 + ipq_errno = IPQ_ERR_BIND;
1299 + memset(&h->peer, 0, sizeof(struct sockaddr_nl));
1300 + h->peer.nl_family = AF_NETLINK;
1301 + h->peer.nl_pid = 0;
1302 + h->peer.nl_groups = 0;
1307 + * No error condition is checked here at this stage, but it may happen
1308 + * if/when reliable messaging is implemented.
1310 +int ipq_destroy_handle(struct ipq_handle *h)
1319 +int ipq_set_mode(const struct ipq_handle *h,
1320 + u_int8_t mode, size_t range)
1323 + struct nlmsghdr nlh;
1324 + ipq_peer_msg_t pm;
1327 + memset(&req, 0, sizeof(req));
1328 + req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
1329 + req.nlh.nlmsg_flags = NLM_F_REQUEST;
1330 + req.nlh.nlmsg_type = IPQM_MODE;
1331 + req.nlh.nlmsg_pid = h->local.nl_pid;
1332 + req.pm.msg.mode.value = mode;
1333 + req.pm.msg.mode.range = range;
1334 + return ipq_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
1338 + * timeout is in microseconds (1 second is 1000000 (1 million) microseconds)
1341 +ssize_t ipq_read(const struct ipq_handle *h,
1342 + unsigned char *buf, size_t len, int timeout)
1344 + return ipq_netlink_recvfrom(h, buf, len, timeout);
1347 +int ipq_message_type(const unsigned char *buf)
1349 + return ((struct nlmsghdr*)buf)->nlmsg_type;
1352 +int ipq_get_msgerr(const unsigned char *buf)
1354 + struct nlmsghdr *h = (struct nlmsghdr *)buf;
1355 + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
1356 + return -err->error;
1359 +ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf)
1361 + return NLMSG_DATA((struct nlmsghdr *)(buf));
1364 +int ipq_set_verdict(const struct ipq_handle *h,
1366 + unsigned int verdict,
1368 + unsigned char *buf)
1370 + unsigned char nvecs;
1372 + struct nlmsghdr nlh;
1373 + ipq_peer_msg_t pm;
1374 + struct iovec iov[3];
1375 + struct msghdr msg;
1377 + memset(&nlh, 0, sizeof(nlh));
1378 + nlh.nlmsg_flags = NLM_F_REQUEST;
1379 + nlh.nlmsg_type = IPQM_VERDICT;
1380 + nlh.nlmsg_pid = h->local.nl_pid;
1381 + memset(&pm, 0, sizeof(pm));
1382 + pm.msg.verdict.value = verdict;
1383 + pm.msg.verdict.id = id;
1384 + pm.msg.verdict.data_len = data_len;
1385 + iov[0].iov_base = &nlh;
1386 + iov[0].iov_len = sizeof(nlh);
1387 + iov[1].iov_base = ±
1388 + iov[1].iov_len = sizeof(pm);
1389 + tlen = sizeof(nlh) + sizeof(pm);
1391 + if (data_len && buf) {
1392 + iov[2].iov_base = buf;
1393 + iov[2].iov_len = data_len;
1397 + msg.msg_name = (void *)&h->peer;
1398 + msg.msg_namelen = sizeof(h->peer);
1399 + msg.msg_iov = iov;
1400 + msg.msg_iovlen = nvecs;
1401 + msg.msg_control = NULL;
1402 + msg.msg_controllen = 0;
1403 + msg.msg_flags = 0;
1404 + nlh.nlmsg_len = tlen;
1405 + return ipq_netlink_sendmsg(h, &msg, 0);
1408 +/* Not implemented yet */
1409 +int ipq_ctl(const struct ipq_handle *h, int request, ...)
1414 +char *ipq_errstr(void)
1416 + return ipq_strerror(ipq_errno);
1419 +void ipq_perror(const char *s)
1424 + fputs("ERROR", stderr);
1426 + fprintf(stderr, ": %s", ipq_errstr());
1428 + fprintf(stderr, ": %s", strerror(errno));
1429 + fputc('\n', stderr);