diff options
-rw-r--r-- | regress/sbin/pfctl/binat1.ok | 18 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf1.ok | 4 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf12.ok | 6 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf13.ok | 12 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf2.ok | 6 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf4.ok | 32 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf5.ok | 16 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf7.ok | 6 | ||||
-rw-r--r-- | regress/sbin/pfctl/pf8.ok | 2 | ||||
-rw-r--r-- | sbin/pfctl/parse.y | 304 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 10 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 76 | ||||
-rw-r--r-- | share/man/man5/nat.conf.5 | 20 | ||||
-rw-r--r-- | share/man/man5/pf.conf.5 | 22 | ||||
-rw-r--r-- | sys/net/pf.c | 398 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 10 | ||||
-rw-r--r-- | sys/net/pfvar.h | 183 |
17 files changed, 781 insertions, 344 deletions
diff --git a/regress/sbin/pfctl/binat1.ok b/regress/sbin/pfctl/binat1.ok index b7f5dc330e7..6ef8dfeef33 100644 --- a/regress/sbin/pfctl/binat1.ok +++ b/regress/sbin/pfctl/binat1.ok @@ -1,9 +1,9 @@ -no binat on lo0 from 192.168.1.1 to 10.1.2.3/32 -binat on lo0 from 192.168.1.1 to any -> 10.0.0.1 -binat on lo0 proto tcp from 192.168.1.2 to any -> 10.0.0.2 -binat on lo0 proto udp from 192.168.1.3 to any -> 10.0.0.3 -binat on lo0 proto icmp from 192.168.1.4 to any -> 10.0.0.4 -binat on lo0 from 192.168.1.5 to 172.16.1.1/32 -> 10.0.0.5 -binat on lo0 from 192.168.1.6 to 172.16.1.2/32 -> 10.0.0.6 -binat on lo0 from 192.168.1.7 to 172.16.2.0/24 -> 10.0.0.7 -binat on lo0 from 192.168.1.8 to ! 172.17.0.0/16 -> 10.0.0.8 +no binat on lo0 inet from 192.168.1.1 to 10.1.2.3 +binat on lo0 inet from 192.168.1.1 to any -> 10.0.0.1 +binat on lo0 inet proto tcp from 192.168.1.2 to any -> 10.0.0.2 +binat on lo0 inet proto udp from 192.168.1.3 to any -> 10.0.0.3 +binat on lo0 inet proto icmp from 192.168.1.4 to any -> 10.0.0.4 +binat on lo0 inet from 192.168.1.5 to 172.16.1.1 -> 10.0.0.5 +binat on lo0 inet from 192.168.1.6 to 172.16.1.2 -> 10.0.0.6 +binat on lo0 inet from 192.168.1.7 to 172.16.2.0/24 -> 10.0.0.7 +binat on lo0 inet from 192.168.1.8 to ! 172.17.0.0/16 -> 10.0.0.8 diff --git a/regress/sbin/pfctl/pf1.ok b/regress/sbin/pfctl/pf1.ok index c9bf8d16971..17ee5b6895f 100644 --- a/regress/sbin/pfctl/pf1.ok +++ b/regress/sbin/pfctl/pf1.ok @@ -2,5 +2,5 @@ @1 pass in all @2 pass in proto tcp from any port <= 1024 to any label foo_bar @3 pass in proto tcp from any to any port = smtp -@4 pass in inet proto tcp from 10.0.0.0/8 port > 1024 to ! 10.1.2.3/32 port != ssh -@5 pass in inet proto igmp from 10.0.0.0/8 to 10.1.1.1/32 allow-opts +@4 pass in inet proto tcp from 10.0.0.0/8 port > 1024 to ! 10.1.2.3 port != ssh +@5 pass in inet proto igmp from 10.0.0.0/8 to 10.1.1.1 allow-opts diff --git a/regress/sbin/pfctl/pf12.ok b/regress/sbin/pfctl/pf12.ok index 18d92f75316..b322e017333 100644 --- a/regress/sbin/pfctl/pf12.ok +++ b/regress/sbin/pfctl/pf12.ok @@ -1,5 +1,5 @@ -@0 pass in inet from 127.0.0.1/32 to 127.0.0.1/8 +@0 pass in inet from 127.0.0.1 to 127.0.0.1/8 @1 pass in inet from 127.0.0.1/16 to 127.0.0.1/24 @2 pass in inet from 127.0.0.1/25 to ! 127.0.0.1/26 -@3 pass in inet from ! 127.0.0.1/32 to 127.0.0.1/16 -@4 pass in inet from ! 127.0.0.1/32 to ! 127.0.0.1/8 +@3 pass in inet from ! 127.0.0.1 to 127.0.0.1/16 +@4 pass in inet from ! 127.0.0.1 to ! 127.0.0.1/8 diff --git a/regress/sbin/pfctl/pf13.ok b/regress/sbin/pfctl/pf13.ok index 00dffe49017..f6c63c34823 100644 --- a/regress/sbin/pfctl/pf13.ok +++ b/regress/sbin/pfctl/pf13.ok @@ -2,11 +2,11 @@ @1 pass in quick on enc0 fastroute inet all @2 pass in quick on enc0 fastroute inet6 all @3 pass out quick on tun0 route-to tun1 all -@4 pass out quick on tun0 route-to tun1 inet from any to 192.168.1.1/32 -@5 pass out quick on tun0 route-to tun1 inet6 from any to fec0::1/128 +@4 pass out quick on tun0 route-to tun1 inet from any to 192.168.1.1 +@5 pass out quick on tun0 route-to tun1 inet6 from any to fec0::1 @6 block in on tun0 dup-to tun1:192.168.1.1 inet proto tcp from any to any port = ftp @7 block in on tun0 dup-to tun1:fec0::1 inet6 proto tcp from any to any port = ftp -@8 pass in quick on tun0 route-to tun1 inet from 192.168.1.1/32 to 10.1.1.1/32 -@9 pass in quick on tun0 route-to tun1 inet6 from fec0::1/64 to fec1::2/128 -@10 pass in quick on tun0 dup-to tun1:192.168.1.100 inet from 192.168.1.1/32 to 10.1.1.1/32 -@11 pass in quick on tun0 dup-to tun1:fec1::2 inet6 from fec0::1/64 to fec1::2/128 +@8 pass in quick on tun0 route-to tun1 inet from 192.168.1.1 to 10.1.1.1 +@9 pass in quick on tun0 route-to tun1 inet6 from fec0::1/64 to fec1::2 +@10 pass in quick on tun0 dup-to tun1:192.168.1.100 inet from 192.168.1.1 to 10.1.1.1 +@11 pass in quick on tun0 dup-to tun1:fec1::2 inet6 from fec0::1/64 to fec1::2 diff --git a/regress/sbin/pfctl/pf2.ok b/regress/sbin/pfctl/pf2.ok index 9842fbb21a3..503ef536096 100644 --- a/regress/sbin/pfctl/pf2.ok +++ b/regress/sbin/pfctl/pf2.ok @@ -4,12 +4,12 @@ @3 block return-rst in log on tun0 proto tcp all @4 block return-icmp out log on tun0 proto udp all @5 block return-icmp in log on tun0 proto udp all -@6 block out log quick on tun0 inet from ! 157.161.48.183/32 to any -@7 block in quick on tun0 inet from any to 255.255.255.255/32 +@6 block out log quick on tun0 inet from ! 157.161.48.183 to any +@7 block in quick on tun0 inet from any to 255.255.255.255 @8 block in log quick on tun0 inet from 10.0.0.0/8 to any @9 block in log quick on tun0 inet from 172.16.0.0/12 to any @10 block in log quick on tun0 inet from 192.168.0.0/16 to any -@11 block in log quick on tun0 inet from 255.255.255.255/32 to any +@11 block in log quick on tun0 inet from 255.255.255.255 to any @12 block in log quick from no-route to any @13 pass out on tun0 inet proto icmp all icmp-type echoreq code 0 keep state @14 pass in on tun0 inet proto icmp all icmp-type echoreq code 0 keep state diff --git a/regress/sbin/pfctl/pf4.ok b/regress/sbin/pfctl/pf4.ok index d3c017c357d..8418c4e170f 100644 --- a/regress/sbin/pfctl/pf4.ok +++ b/regress/sbin/pfctl/pf4.ok @@ -12,35 +12,35 @@ @11 block in proto tcp from any port != 1234 to any @12 block in proto tcp from any port 21 >< 2048 to any @13 block in proto tcp from any port = ssh to any -@14 block in inet proto udp from 172.16.0.0/12 port = 21 to 12.34.56.78/32 port = 6668 keep state -@15 block in inet proto udp from 172.16.0.0/12 port = 21 to 12.34.56.78/32 port = 6667 keep state +@14 block in inet proto udp from 172.16.0.0/12 port = 21 to 12.34.56.78 port = 6668 keep state +@15 block in inet proto udp from 172.16.0.0/12 port = 21 to 12.34.56.78 port = 6667 keep state @16 block in inet proto udp from 172.16.0.0/12 port = 21 to 192.168.0.0/16 port = 6668 keep state @17 block in inet proto udp from 172.16.0.0/12 port = 21 to 192.168.0.0/16 port = 6667 keep state -@18 block in inet proto udp from 172.16.0.0/12 port = ssh to 12.34.56.78/32 port = 6668 keep state -@19 block in inet proto udp from 172.16.0.0/12 port = ssh to 12.34.56.78/32 port = 6667 keep state +@18 block in inet proto udp from 172.16.0.0/12 port = ssh to 12.34.56.78 port = 6668 keep state +@19 block in inet proto udp from 172.16.0.0/12 port = ssh to 12.34.56.78 port = 6667 keep state @20 block in inet proto udp from 172.16.0.0/12 port = ssh to 192.168.0.0/16 port = 6668 keep state @21 block in inet proto udp from 172.16.0.0/12 port = ssh to 192.168.0.0/16 port = 6667 keep state -@22 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78/32 port = 6668 keep state -@23 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78/32 port = 6667 keep state +@22 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78 port = 6668 keep state +@23 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78 port = 6667 keep state @24 block in inet proto udp from 10.0.0.0/8 port = 21 to 192.168.0.0/16 port = 6668 keep state @25 block in inet proto udp from 10.0.0.0/8 port = 21 to 192.168.0.0/16 port = 6667 keep state -@26 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 6668 keep state -@27 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 6667 keep state +@26 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 6668 keep state +@27 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 6667 keep state @28 block in inet proto udp from 10.0.0.0/8 port = ssh to 192.168.0.0/16 port = 6668 keep state @29 block in inet proto udp from 10.0.0.0/8 port = ssh to 192.168.0.0/16 port = 6667 keep state -@30 block in inet proto tcp from 172.16.0.0/12 port = ftp to 12.34.56.78/32 port = 6668 keep state -@31 block in inet proto tcp from 172.16.0.0/12 port = ftp to 12.34.56.78/32 port = 6667 keep state +@30 block in inet proto tcp from 172.16.0.0/12 port = ftp to 12.34.56.78 port = 6668 keep state +@31 block in inet proto tcp from 172.16.0.0/12 port = ftp to 12.34.56.78 port = 6667 keep state @32 block in inet proto tcp from 172.16.0.0/12 port = ftp to 192.168.0.0/16 port = 6668 keep state @33 block in inet proto tcp from 172.16.0.0/12 port = ftp to 192.168.0.0/16 port = 6667 keep state -@34 block in inet proto tcp from 172.16.0.0/12 port = ssh to 12.34.56.78/32 port = 6668 keep state -@35 block in inet proto tcp from 172.16.0.0/12 port = ssh to 12.34.56.78/32 port = 6667 keep state +@34 block in inet proto tcp from 172.16.0.0/12 port = ssh to 12.34.56.78 port = 6668 keep state +@35 block in inet proto tcp from 172.16.0.0/12 port = ssh to 12.34.56.78 port = 6667 keep state @36 block in inet proto tcp from 172.16.0.0/12 port = ssh to 192.168.0.0/16 port = 6668 keep state @37 block in inet proto tcp from 172.16.0.0/12 port = ssh to 192.168.0.0/16 port = 6667 keep state -@38 block in inet proto tcp from 10.0.0.0/8 port = ftp to 12.34.56.78/32 port = 6668 keep state -@39 block in inet proto tcp from 10.0.0.0/8 port = ftp to 12.34.56.78/32 port = 6667 keep state +@38 block in inet proto tcp from 10.0.0.0/8 port = ftp to 12.34.56.78 port = 6668 keep state +@39 block in inet proto tcp from 10.0.0.0/8 port = ftp to 12.34.56.78 port = 6667 keep state @40 block in inet proto tcp from 10.0.0.0/8 port = ftp to 192.168.0.0/16 port = 6668 keep state @41 block in inet proto tcp from 10.0.0.0/8 port = ftp to 192.168.0.0/16 port = 6667 keep state -@42 block in inet proto tcp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 6668 keep state -@43 block in inet proto tcp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 6667 keep state +@42 block in inet proto tcp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 6668 keep state +@43 block in inet proto tcp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 6667 keep state @44 block in inet proto tcp from 10.0.0.0/8 port = ssh to 192.168.0.0/16 port = 6668 keep state @45 block in inet proto tcp from 10.0.0.0/8 port = ssh to 192.168.0.0/16 port = 6667 keep state diff --git a/regress/sbin/pfctl/pf5.ok b/regress/sbin/pfctl/pf5.ok index 801c08d900c..c2fd7d68543 100644 --- a/regress/sbin/pfctl/pf5.ok +++ b/regress/sbin/pfctl/pf5.ok @@ -1,11 +1,11 @@ foo = ssh, ftp bar = other thing inside = 10.0.0.0/8 -@0 block in inet proto udp from 10.0.0.0/8 port = 113 to 12.34.56.78/32 port = 16 keep state -@1 block in inet proto udp from 10.0.0.0/8 port = 113 to 12.34.56.78/32 port = 6667 keep state -@2 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78/32 port = 16 keep state -@3 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78/32 port = 6667 keep state -@4 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 16 keep state -@5 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78/32 port = 6667 keep state -@6 block in inet proto udp from 10.0.0.0/8 port = echo to 12.34.56.78/32 port = 16 keep state -@7 block in inet proto udp from 10.0.0.0/8 port = echo to 12.34.56.78/32 port = 6667 keep state +@0 block in inet proto udp from 10.0.0.0/8 port = 113 to 12.34.56.78 port = 16 keep state +@1 block in inet proto udp from 10.0.0.0/8 port = 113 to 12.34.56.78 port = 6667 keep state +@2 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78 port = 16 keep state +@3 block in inet proto udp from 10.0.0.0/8 port = 21 to 12.34.56.78 port = 6667 keep state +@4 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 16 keep state +@5 block in inet proto udp from 10.0.0.0/8 port = ssh to 12.34.56.78 port = 6667 keep state +@6 block in inet proto udp from 10.0.0.0/8 port = echo to 12.34.56.78 port = 16 keep state +@7 block in inet proto udp from 10.0.0.0/8 port = echo to 12.34.56.78 port = 6667 keep state diff --git a/regress/sbin/pfctl/pf7.ok b/regress/sbin/pfctl/pf7.ok index 16202ac16d8..03119742943 100644 --- a/regress/sbin/pfctl/pf7.ok +++ b/regress/sbin/pfctl/pf7.ok @@ -4,12 +4,12 @@ @3 block return-rst in log on tun0 proto tcp all @4 block return-icmp out log on tun0 proto udp all @5 block return-icmp in log on tun0 proto udp all -@6 block out log quick on tun0 inet from ! 157.161.48.183/32 to any -@7 block in quick on tun0 inet from any to 255.255.255.255/32 +@6 block out log quick on tun0 inet from ! 157.161.48.183 to any +@7 block in quick on tun0 inet from any to 255.255.255.255 @8 block in log quick on tun0 inet from 10.0.0.0/8 to any @9 block in log quick on tun0 inet from 172.16.0.0/12 to any @10 block in log quick on tun0 inet from 192.168.0.0/16 to any -@11 block in log quick on tun0 inet from 255.255.255.255/32 to any +@11 block in log quick on tun0 inet from 255.255.255.255 to any @12 pass out on tun0 inet proto icmp all icmp-type echoreq code 0 keep state @13 pass in on tun0 inet proto icmp all icmp-type echoreq code 0 keep state @14 pass out on tun0 proto udp all keep state diff --git a/regress/sbin/pfctl/pf8.ok b/regress/sbin/pfctl/pf8.ok index 584758ac97c..fcb4edfa2b5 100644 --- a/regress/sbin/pfctl/pf8.ok +++ b/regress/sbin/pfctl/pf8.ok @@ -1,3 +1,3 @@ extern = { ! 10.0.0.0/8, 10.1.2.3 } -@0 block out log on tun1 inet from 10.1.2.3/32 to any +@0 block out log on tun1 inet from 10.1.2.3 to any @1 block out log on tun1 inet from ! 10.0.0.0/8 to any diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 19a50de9ff5..13fa80b595a 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.60 2002/04/23 14:32:23 dhartmei Exp $ */ +/* $OpenBSD: parse.y,v 1.61 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -68,7 +68,7 @@ struct node_proto { }; struct node_host { - struct pf_addr addr; + struct pf_addr_wrap addr; struct pf_addr mask; u_int8_t af; u_int8_t not; @@ -473,7 +473,16 @@ host : address { } ; -address : STRING { +address : '(' STRING ')' { + $$ = calloc(1, sizeof(struct node_host)); + if ($$ == NULL) + err(1, "address: calloc"); + $$->af = 0; + $$->addr.addr_dyn = (struct pf_addr_dyn *)1; + strncpy($$->addr.addr.pfa.ifname, $2, + sizeof($$->addr.addr.pfa.ifname)); + } + | STRING { struct hostent *hp; struct ifaddrs *ifa; @@ -489,7 +498,8 @@ address : STRING { if ($$ == NULL) err(1, "address: calloc"); $$->af = AF_INET; - memcpy(&$$->addr, &sin->sin_addr, + $$->addr.addr_dyn = NULL; + memcpy(&$$->addr.addr, &sin->sin_addr, sizeof(u_int32_t)); } else if ((ifa = ifa6_lookup($1))) { struct sockaddr_in6 *sin6 = @@ -501,7 +511,8 @@ address : STRING { if ($$ == NULL) err(1, "address: calloc"); $$->af = AF_INET6; - memcpy(&$$->addr, &sin6->sin6_addr, + $$->addr.addr_dyn = NULL; + memcpy(&$$->addr.addr, &sin6->sin6_addr, sizeof(struct pf_addr)); } else { yyerror("interface %s has no IP " @@ -519,7 +530,8 @@ address : STRING { if ($$ == NULL) err(1, "address: calloc"); $$->af = AF_INET6; - memcpy(&$$->addr, hp->h_addr, + $$->addr.addr_dyn = NULL; + memcpy(&$$->addr.addr, hp->h_addr, sizeof(struct pf_addr)); } } else { @@ -527,7 +539,9 @@ address : STRING { if ($$ == NULL) err(1, "address: calloc"); $$->af = AF_INET; - memcpy(&$$->addr, hp->h_addr, sizeof(u_int32_t)); + $$->addr.addr_dyn = NULL; + memcpy(&$$->addr.addr, hp->h_addr, + sizeof(u_int32_t)); } } | NUMBER '.' NUMBER '.' NUMBER '.' NUMBER { @@ -541,7 +555,8 @@ address : STRING { if ($$ == NULL) err(1, "address: calloc"); $$->af = AF_INET; - $$->addr.addr32[0] = htonl(($1 << 24) | + $$->addr.addr_dyn = NULL; + $$->addr.addr.addr32[0] = htonl(($1 << 24) | ($3 << 16) | ($5 << 8) | $7); } | IPV6ADDR { $$ = $1; } @@ -819,7 +834,7 @@ redirection : /* empty */ { $$ = NULL; } } ; -natrule : no NAT interface proto FROM ipspec TO ipspec redirection +natrule : no NAT interface af proto FROM ipspec TO ipspec redirection { struct pf_nat nat; @@ -836,59 +851,92 @@ natrule : no NAT interface proto FROM ipspec TO ipspec redirection nat.ifnot = $3->not; free($3); } - if ($4 != NULL) { - nat.proto = $4->proto; - free($4); + nat.af = $4; + if ($5 != NULL) { + nat.proto = $5->proto; + free($5); } - if ($6 != NULL && $8 != NULL && $6->af != $8->af) { + if ($7 != NULL && $9 != NULL && $7->af != $9->af) { yyerror("nat ip versions must match"); YYERROR; } - if ($6 != NULL) { - nat.af = $6->af; - memcpy(&nat.saddr, &$6->addr, + if ($7 != NULL) { + if ($7->addr.addr_dyn != NULL) { + if (!nat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $7->af = nat.af; + } + if (nat.af && $7->af != nat.af) { + yyerror("nat ip versions must match"); + YYERROR; + } + nat.af = $7->af; + memcpy(&nat.saddr, &$7->addr, sizeof(nat.saddr)); - memcpy(&nat.smask, &$6->mask, + memcpy(&nat.smask, &$7->mask, sizeof(nat.smask)); - nat.snot = $6->not; - free($6); + nat.snot = $7->not; + free($7); } - if ($8 != NULL) { - nat.af = $8->af; - memcpy(&nat.daddr, &$8->addr, + if ($9 != NULL) { + if ($9->addr.addr_dyn != NULL) { + if (!nat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $9->af = nat.af; + } + if (nat.af && $9->af != nat.af) { + yyerror("nat ip versions must match"); + YYERROR; + } + nat.af = $9->af; + memcpy(&nat.daddr, &$9->addr, sizeof(nat.daddr)); - memcpy(&nat.dmask, &$8->mask, + memcpy(&nat.dmask, &$9->mask, sizeof(nat.dmask)); - nat.dnot = $8->not; - free($8); + nat.dnot = $9->not; + free($9); } if (nat.no) { - if ($9 != NULL) { + if ($10 != NULL) { yyerror("'no nat' rule does not need '->'"); YYERROR; } } else { - if ($9 == NULL || $9->address == NULL) { + if ($10 == NULL || $10->address == NULL) { yyerror("'nat' rule requires '-> address'"); YYERROR; } - if (nat.af && $9->address->af != nat.af) { + if ($10->address->addr.addr_dyn != NULL) { + if (!nat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $10->address->af = nat.af; + } + if (nat.af && $10->address->af != nat.af) { yyerror("nat ip versions must match"); YYERROR; } - nat.af = $9->address->af; - memcpy(&nat.raddr, &$9->address->addr, + nat.af = $10->address->af; + memcpy(&nat.raddr, &$10->address->addr, sizeof(nat.raddr)); - free($9->address); - free($9); + free($10->address); + free($10); } pfctl_add_nat(pf, &nat); } ; -binatrule : no BINAT interface proto FROM address TO ipspec redirection +binatrule : no BINAT interface af proto FROM address TO ipspec redirection { struct pf_binat binat; @@ -904,57 +952,90 @@ binatrule : no BINAT interface proto FROM address TO ipspec redirection sizeof(binat.ifname)); free($3); } - if ($4 != NULL) { - binat.proto = $4->proto; - free($4); + binat.af = $4; + if ($5 != NULL) { + binat.proto = $5->proto; + free($5); } - if ($6 != NULL && $8 != NULL && $6->af != $8->af) { + if ($7 != NULL && $9 != NULL && $7->af != $9->af) { yyerror("binat ip versions must match"); YYERROR; } - if ($6 != NULL) { - binat.af = $6->af; - memcpy(&binat.saddr, &$6->addr, + if ($7 != NULL) { + if ($7->addr.addr_dyn != NULL) { + if (!binat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $7->af = binat.af; + } + if (binat.af && $7->af != binat.af) { + yyerror("binat ip versions must match"); + YYERROR; + } + binat.af = $7->af; + memcpy(&binat.saddr, &$7->addr, sizeof(binat.saddr)); - free($6); + free($7); } - if ($8 != NULL) { - binat.af = $8->af; - memcpy(&binat.daddr, &$8->addr, + if ($9 != NULL) { + if ($9->addr.addr_dyn != NULL) { + if (!binat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $9->af = binat.af; + } + if (binat.af && $9->af != binat.af) { + yyerror("binat ip versions must match"); + YYERROR; + } + binat.af = $9->af; + memcpy(&binat.daddr, &$9->addr, sizeof(binat.daddr)); - memcpy(&binat.dmask, &$8->mask, + memcpy(&binat.dmask, &$9->mask, sizeof(binat.dmask)); - binat.dnot = $8->not; - free($8); + binat.dnot = $9->not; + free($9); } if (binat.no) { - if ($9 != NULL) { + if ($10 != NULL) { yyerror("'no binat' rule does not need" " '->'"); YYERROR; } } else { - if ($9 == NULL || $9->address == NULL) { + if ($10 == NULL || $10->address == NULL) { yyerror("'binat' rule requires" " '-> address'"); YYERROR; } - if (binat.af && $9->address->af != binat.af) { + if ($10->address->addr.addr_dyn != NULL) { + if (!binat.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $10->address->af = binat.af; + } + if (binat.af && $10->address->af != binat.af) { yyerror("binat ip versions must match"); YYERROR; } - binat.af = $9->address->af; - memcpy(&binat.raddr, &$9->address->addr, + binat.af = $10->address->af; + memcpy(&binat.raddr, &$10->address->addr, sizeof(binat.raddr)); - free($9->address); - free($9); + free($10->address); + free($10); } pfctl_add_binat(pf, &binat); } -rdrrule : no RDR interface proto FROM ipspec TO ipspec dport redirection +rdrrule : no RDR interface af proto FROM ipspec TO ipspec dport redirection { struct pf_rdr rdr; @@ -971,58 +1052,90 @@ rdrrule : no RDR interface proto FROM ipspec TO ipspec dport redirection rdr.ifnot = $3->not; free($3); } - if ($4 != NULL) { - rdr.proto = $4->proto; - free($4); + if ($5 != NULL) { + rdr.proto = $5->proto; + free($5); } - if ($6 != NULL && $8 != NULL && $6->af != $8->af) { + if ($7 != NULL && $9 != NULL && $7->af != $9->af) { yyerror("rdr ip versions must match"); YYERROR; } - if ($6 != NULL) { - rdr.af = $6->af; - memcpy(&rdr.saddr, &$6->addr, + if ($7 != NULL) { + if ($7->addr.addr_dyn != NULL) { + if (!rdr.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $7->af = rdr.af; + } + if (rdr.af && $7->af != rdr.af) { + yyerror("rdr ip versions must match"); + YYERROR; + } + rdr.af = $7->af; + memcpy(&rdr.saddr, &$7->addr, sizeof(rdr.saddr)); - memcpy(&rdr.smask, &$6->mask, + memcpy(&rdr.smask, &$7->mask, sizeof(rdr.smask)); - rdr.snot = $6->not; - free($6); + rdr.snot = $7->not; + free($7); } - if ($8 != NULL) { - rdr.af = $8->af; - memcpy(&rdr.daddr, &$8->addr, + if ($9 != NULL) { + if ($9->addr.addr_dyn != NULL) { + if (!rdr.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $9->af = rdr.af; + } + if (rdr.af && $9->af != rdr.af) { + yyerror("rdr ip versions must match"); + YYERROR; + } + rdr.af = $9->af; + memcpy(&rdr.daddr, &$9->addr, sizeof(rdr.daddr)); - memcpy(&rdr.dmask, &$8->mask, + memcpy(&rdr.dmask, &$9->mask, sizeof(rdr.dmask)); - rdr.dnot = $8->not; - free($8); + rdr.dnot = $9->not; + free($9); } - rdr.dport = $9.a; - rdr.dport2 = $9.b; - rdr.opts |= $9.t; + rdr.dport = $10.a; + rdr.dport2 = $10.b; + rdr.opts |= $10.t; if (rdr.no) { - if ($10 != NULL) { + if ($11 != NULL) { yyerror("'no rdr' rule does not need '->'"); YYERROR; } } else { - if ($10 == NULL || $10->address == NULL) { + if ($11 == NULL || $11->address == NULL) { yyerror("'rdr' rule requires '-> address'"); YYERROR; } - if (rdr.af && $10->address->af != rdr.af) { + if ($11->address->addr.addr_dyn != NULL) { + if (!rdr.af) { + yyerror("address family (inet/" + "inet6) undefined"); + YYERROR; + } + $11->address->af = rdr.af; + } + if (rdr.af && $11->address->af != rdr.af) { yyerror("rdr ip versions must match"); YYERROR; } - rdr.af = $10->address->af; - memcpy(&rdr.raddr, &$10->address->addr, + rdr.af = $11->address->af; + memcpy(&rdr.raddr, &$11->address->addr, sizeof(rdr.raddr)); - free($10->address); - rdr.rport = $10->rport.a; - rdr.opts |= $10->rport.t; - free($10); + free($11->address); + rdr.rport = $11->rport.a; + rdr.opts |= $11->rport.t; + free($11); } if (rdr.proto && rdr.proto != IPPROTO_TCP && @@ -1064,7 +1177,12 @@ route : /* empty */ { | ROUTETO STRING ':' address { $$.string = strdup($2); $$.rt = PF_ROUTETO; - $$.addr = &$4->addr; + if ($4->addr.addr_dyn != NULL) { + yyerror("route-to does not support" + " dynamic addresses"); + YYERROR; + } + $$.addr = &$4->addr.addr; $$.af = $4->af; } | ROUTETO STRING { @@ -1075,7 +1193,12 @@ route : /* empty */ { | DUPTO STRING ':' address { $$.string = strdup($2); $$.rt = PF_DUPTO; - $$.addr = &$4->addr; + if ($4->addr.addr_dyn != NULL) { + yyerror("dup-to does not support" + " dynamic addresses"); + YYERROR; + } + $$.addr = &$4->addr.addr; $$.af = $4->af; } | DUPTO STRING { @@ -1179,6 +1302,11 @@ rule_consistent(struct pf_rule *r) yyerror("allow-opts can only be specified for pass rules"); problems++; } + if (!r->af && (r->src.addr.addr_dyn != NULL || + r->dst.addr.addr_dyn != NULL)) { + yyerror("dynamic addresses require address family (inet/inet6)"); + problems++; + } if (r->rule_flag & PFRULE_FRAGMENT && (r->src.port_op || r->dst.port_op || r->flagset || r->type || r->code)) { yyerror("fragments can be filtered only on IP header fields"); @@ -1635,7 +1763,8 @@ top: if(!notv6addr && inet_pton(AF_INET6, lookahead, &addr) == 1) { node = calloc(1, sizeof(struct node_host)); node->af = AF_INET6; - memcpy (&node->addr, &addr, sizeof(addr)); + node->addr.addr_dyn = NULL; + memcpy (&node->addr.addr, &addr, sizeof(addr)); yylval.v.host = node; return IPV6ADDR; } else { @@ -1695,7 +1824,8 @@ top: #define allowed_in_string(x) \ (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ x != '{' && x != '}' && x != '<' && x != '>' && \ - x != '!' && x != '=' && x != '/' && x != '#' && x != ',' && x != ':')) + x != '!' && x != '=' && x != '/' && x != '#' && \ + x != ',' && x != ':' && x != '(' && x != ')')) if (isalnum(c)) { do { diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 56424ee8083..e7a4a2f7136 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.60 2002/04/01 20:01:16 dhartmei Exp $ */ +/* $OpenBSD: pfctl.c,v 1.61 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -301,10 +301,10 @@ pfctl_kill_states(int dev, int opts) sources++; if (psk.psk_af == AF_INET) - psk.psk_src.addr.v4 = + psk.psk_src.addr.addr.v4 = ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr; else if (psk.psk_af == AF_INET6) - psk.psk_src.addr.v6 = + psk.psk_src.addr.addr.v6 = ((struct sockaddr_in6 *)resp[0]->ai_addr)-> sin6_addr; else @@ -335,11 +335,11 @@ pfctl_kill_states(int dev, int opts) dests++; if (psk.psk_af == AF_INET) - psk.psk_dst.addr.v4 = + psk.psk_dst.addr.addr.v4 = ((struct sockaddr_in *)resp[1]-> ai_addr)->sin_addr; else if (psk.psk_af == AF_INET6) - psk.psk_dst.addr.v6 = + psk.psk_dst.addr.addr.v6 = ((struct sockaddr_in6 *)resp[1]-> ai_addr)->sin6_addr; else diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index d7714290314..74eb673a698 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.65 2002/04/23 14:32:23 dhartmei Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.66 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -55,7 +55,7 @@ #include "pfctl_parser.h" int unmask (struct pf_addr *, u_int8_t); -void print_addr (struct pf_addr *, struct pf_addr *, u_int8_t); +void print_addr (struct pf_addr_wrap *, struct pf_addr *, u_int8_t); void print_host (struct pf_state_host *, u_int8_t, int); void print_seq (struct pf_state_peer *); void print_port (u_int8_t, u_int16_t, u_int16_t, char *); @@ -277,17 +277,23 @@ unmask(struct pf_addr *m, u_int8_t af) } void -print_addr(struct pf_addr *addr, struct pf_addr *mask, u_int8_t af) +print_addr(struct pf_addr_wrap *addr, struct pf_addr *mask, u_int8_t af) { char buf[48]; - if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL) - printf("?"); - else - printf("%s", buf); + if (addr->addr_dyn != NULL) + printf("(%s)", addr->addr.pfa.ifname); + else { + if (inet_ntop(af, &addr->addr, buf, sizeof(buf)) == NULL) + printf("?"); + else + printf("%s", buf); + } if (mask != NULL) { - if (!PF_AZERO(mask, af)) - printf("/%u", unmask(mask, af)); + int bits = unmask(mask, af); + + if (bits != (af == AF_INET ? 32 : 128)) + printf("/%u", bits); } } @@ -304,6 +310,7 @@ print_name(struct pf_addr *addr, struct pf_addr *mask, int af) printf("%s", hp->h_name); } if (mask != NULL) { + if (!PF_AZERO(mask, af)) printf("/%u", unmask(mask, af)); } @@ -316,8 +323,13 @@ print_host(struct pf_state_host *h, u_int8_t af, int opts) if (opts & PF_OPT_USEDNS) print_name(&h->addr, NULL, af); - else - print_addr(&h->addr, NULL, af); + else { + struct pf_addr_wrap aw; + + aw.addr = h->addr; + aw.addr_dyn = NULL; + print_addr(&aw, NULL, af); + } if (p) { if (af == AF_INET) @@ -392,6 +404,12 @@ print_nat(struct pf_nat *n) printf("! "); printf("%s ", n->ifname); } + if (n->af) { + if (n->af == AF_INET) + printf("inet "); + else + printf("inet6 "); + } if (n->proto) { struct protoent *p = getprotobynumber(n->proto); if (p != NULL) @@ -400,7 +418,7 @@ print_nat(struct pf_nat *n) printf("proto %u ", n->proto); } printf("from "); - if (!PF_AZERO(&n->saddr, n->af) || !PF_AZERO(&n->smask, n->af)) { + if (!PF_AZERO(&n->saddr.addr, n->af) || !PF_AZERO(&n->smask, n->af)) { if (n->snot) printf("! "); print_addr(&n->saddr, &n->smask, n->af); @@ -408,7 +426,7 @@ print_nat(struct pf_nat *n) } else printf("any "); printf("to "); - if (!PF_AZERO(&n->daddr, n->af) || !PF_AZERO(&n->dmask, n->af)) { + if (!PF_AZERO(&n->daddr.addr, n->af) || !PF_AZERO(&n->dmask, n->af)) { if (n->dnot) printf("! "); print_addr(&n->daddr, &n->dmask, n->af); @@ -432,6 +450,12 @@ print_binat(struct pf_binat *b) printf("on "); printf("%s ", b->ifname); } + if (b->af) { + if (b->af == AF_INET) + printf("inet "); + else + printf("inet6 "); + } if (b->proto) { struct protoent *p = getprotobynumber(b->proto); if (p != NULL) @@ -443,7 +467,7 @@ print_binat(struct pf_binat *b) print_addr(&b->saddr, NULL, b->af); printf(" "); printf("to "); - if (!PF_AZERO(&b->daddr, b->af) || !PF_AZERO(&b->dmask, b->af)) { + if (!PF_AZERO(&b->daddr.addr, b->af) || !PF_AZERO(&b->dmask, b->af)) { if (b->dnot) printf("! "); print_addr(&b->daddr, &b->dmask, b->af); @@ -469,6 +493,12 @@ print_rdr(struct pf_rdr *r) printf("! "); printf("%s ", r->ifname); } + if (r->af) { + if (r->af == AF_INET) + printf("inet "); + else + printf("inet6 "); + } if (r->proto) { struct protoent *p = getprotobynumber(r->proto); if (p != NULL) @@ -477,7 +507,7 @@ print_rdr(struct pf_rdr *r) printf("proto %u ", r->proto); } printf("from "); - if (!PF_AZERO(&r->saddr, r->af) || !PF_AZERO(&r->smask, r->af)) { + if (!PF_AZERO(&r->saddr.addr, r->af) || !PF_AZERO(&r->smask, r->af)) { if (r->snot) printf("! "); print_addr(&r->saddr, &r->smask, r->af); @@ -485,7 +515,7 @@ print_rdr(struct pf_rdr *r) } else printf("any "); printf("to "); - if (!PF_AZERO(&r->daddr, r->af) || !PF_AZERO(&r->dmask, r->af)) { + if (!PF_AZERO(&r->daddr.addr, r->af) || !PF_AZERO(&r->dmask, r->af)) { if (r->dnot) printf("! "); print_addr(&r->daddr, &r->dmask, r->af); @@ -685,8 +715,12 @@ print_rule(struct pf_rule *r) if (r->rt_ifname[0]) printf("%s", r->rt_ifname); if (r->af && !PF_AZERO(&r->rt_addr, r->af)) { + struct pf_addr_wrap aw; + + aw.addr = r->rt_addr; + aw.addr_dyn = NULL; printf(":"); - print_addr(&r->rt_addr, NULL, r->af); + print_addr(&aw, NULL, r->af); } printf(" "); } @@ -703,17 +737,17 @@ print_rule(struct pf_rule *r) else printf("proto %u ", r->proto); } - if (PF_AZERO(&r->src.addr, AF_INET6) && + if (PF_AZERO(&r->src.addr.addr, AF_INET6) && PF_AZERO(&r->src.mask, AF_INET6) && !r->src.noroute && !r->dst.noroute && - !r->src.port_op && PF_AZERO(&r->dst.addr, AF_INET6) && + !r->src.port_op && PF_AZERO(&r->dst.addr.addr, AF_INET6) && PF_AZERO(&r->dst.mask, AF_INET6) && !r->dst.port_op) printf("all "); else { printf("from "); if (r->src.noroute) printf("no-route "); - else if (PF_AZERO(&r->src.addr, AF_INET6) && + else if (PF_AZERO(&r->src.addr.addr, AF_INET6) && PF_AZERO(&r->src.mask, AF_INET6)) printf("any "); else { @@ -730,7 +764,7 @@ print_rule(struct pf_rule *r) printf("to "); if (r->dst.noroute) printf("no-route "); - else if (PF_AZERO(&r->dst.addr, AF_INET6) && + else if (PF_AZERO(&r->dst.addr.addr, AF_INET6) && PF_AZERO(&r->dst.mask, AF_INET6)) printf("any "); else { diff --git a/share/man/man5/nat.conf.5 b/share/man/man5/nat.conf.5 index 3b3bec24c03..2930f525c55 100644 --- a/share/man/man5/nat.conf.5 +++ b/share/man/man5/nat.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nat.conf.5,v 1.23 2002/02/27 15:15:29 dhartmei Exp $ +.\" $OpenBSD: nat.conf.5,v 1.24 2002/04/24 18:10:25 dhartmei Exp $ .\" .\" Copyright (c) 2001 Ian Darwin. All rights reserved. .\" @@ -119,11 +119,9 @@ set load-time. When the address of an interface (or host name) changes (by DHCP or PPP, for instance), the rule set must be reloaded for the change to be reflected in the kernel. -See -.Xr dhclient-script 8 -or -.Xr ppp 8 -for information on how to automate this task. +Interface names surrounded by parentheses cause an automatic update of +the rule whenever the referenced interface changes its address. +Reloading the rule set is not required in this case. If specified, .Em mask-bits refers to the number of bits in the netmask. @@ -191,23 +189,21 @@ listening for outbound ftp sessions captured to port 8081. # translate outgoing packets' source addresses (any protocol) # in my case, any address but the gateway's external address is mapped # -nat on kue0 from ! 157.161.48.183 to any -> 157.161.48.183 +nat on kue0 from ! (kue0) to any -> (kue0) # BINAT # translate outgoing packets' source address (any protocol) # translate incoming packets' destination address to an internal machine # (bidirectional) -binat on kue0 from 10.1.2.150 to any -> 157.161.48.184 +binat on kue0 from 10.1.2.150 to any -> (kue0) # RDR # translate incoming packets' destination addresses # as an example, redirect a TCP and UDP port to an internal machine # NOTE: the lines below are split for readability # -rdr on kue0 proto tcp from any to 157.161.48.183/32 port 8080 \e - -> 10.1.2.151 port 22 -rdr on kue0 proto udp from any to 157.161.48.183/32 port 8080 \e - -> 10.1.2.151 port 53 +rdr on kue0 proto tcp from any to (kue0) port 8080 -> 10.1.2.151 port 22 +rdr on kue0 proto udp from any to (kue0) port 8080 -> 10.1.2.151 port 53 # RDR # translate outgoing ftp control connections to send them to localhost diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index 19c996c8969..d867b13dcf1 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pf.conf.5,v 1.39 2002/04/23 14:32:23 dhartmei Exp $ +.\" $OpenBSD: pf.conf.5,v 1.40 2002/04/24 18:10:25 dhartmei Exp $ .\" .\" Copyright (c) 2001, Daniel Hartmeier .\" All rights reserved. @@ -68,12 +68,14 @@ af = "inet" | "inet6" . proto-list = ( proto-name | proto-number ) [ "," proto-list ] . hosts = "all" | - "from" ( "any" | "no-route" | host | "{" host-list "}" ) [ port ] - "to" ( "any" | "no-route" | host | "{" host-list "}" ) [ port ] . + "from" ( "any" | "no-route" | host | "{" host-list "}" ) + [ port ] + "to" ( "any" | "no-route" | host | "{" host-list "}" ) + [ port ] . host = [ "!" ] address [ "/" mask-bits ] . -address = ( interface-name | host-name | ipv4-dotted-quad | - ipv6-coloned-hex ) . +address = ( interface-name | '(' interface-name ')' | host-name | + ipv4-dotted-quad | ipv6-coloned-hex ) . host-list = host [ "," host-list ] . port = "port" ( unary-op | binary-op | "{" port-list "}" ) . port-list = ( unary-op | binary-op ) [ "," port-list ] . @@ -228,15 +230,13 @@ means any address which is not currently routable. .El .Pp Host name resolution and interface to address translation are done at -rule set load-time. +rule set load-time. When the address of an interface (or host name) changes (by DHCP or PPP, for instance), the rule set must be reloaded for the change to be reflected in the kernel. -See -.Xr dhclient-script 8 -or -.Xr ppp 8 -for information on how to automate this task. +Interface names surrounded by parentheses cause an automatic update of +the rule whenever the referenced interface changes its address. +Reloading the rule set is not required in this case. .Pp Ports can be specified using these operators .Bd -literal diff --git a/sys/net/pf.c b/sys/net/pf.c index af5df4d570a..684a455e36d 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.203 2002/04/23 14:32:22 dhartmei Exp $ */ +/* $OpenBSD: pf.c,v 1.204 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -175,7 +175,7 @@ int *pftm_timeouts[PFTM_MAX] = { &pftm_tcp_first_packet, struct pool pf_tree_pl, pf_rule_pl, pf_nat_pl, pf_sport_pl; -struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl; +struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl, pf_addr_pl; struct pf_pool_limit { void *pp; @@ -202,6 +202,10 @@ struct pf_tree_node *pf_tree_search(struct pf_tree_node *, void pf_insert_state(struct pf_state *); void pf_purge_expired_states(void); void pf_purge_timeout(void *); +int pf_dynaddr_setup(struct pf_addr_wrap *, u_int8_t); +void pf_dynaddr_update(void *); +void pf_dynaddr_remove(struct pf_addr_wrap *); +void pf_dynaddr_copyout(struct pf_addr_wrap *); void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); void pf_print_state(struct pf_state *); @@ -405,9 +409,19 @@ pf_compare_rules(struct pf_rule *a, struct pf_rule *b) a->min_ttl != b->min_ttl || a->allow_opts != b->allow_opts) return (1); - if (memcmp(&a->src, &b->src, sizeof(struct pf_rule_addr))) + if (PF_ANEQ(&a->src.addr.addr, &b->src.addr.addr, a->af) || + PF_ANEQ(&a->src.mask, &b->src.mask, a->af) || + a->src.port[0] != b->src.port[0] || + a->src.port[1] != b->src.port[1] || + a->src.not != b->src.not || + a->src.port_op != b->src.port_op) return (1); - if (memcmp(&a->dst, &b->dst, sizeof(struct pf_rule_addr))) + if (PF_ANEQ(&a->dst.addr.addr, &b->dst.addr.addr, a->af) || + PF_ANEQ(&a->dst.mask, &b->dst.mask, a->af) || + a->dst.port[0] != b->dst.port[0] || + a->dst.port[1] != b->dst.port[1] || + a->dst.not != b->dst.not || + a->dst.port_op != b->dst.port_op) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -424,15 +438,15 @@ pf_compare_nats(struct pf_nat *a, struct pf_nat *b) a->ifnot != b->ifnot || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); if (PF_ANEQ(&a->smask, &b->smask, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -447,13 +461,13 @@ pf_compare_binats(struct pf_binat *a, struct pf_binat *b) a->af != b->af || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -474,15 +488,15 @@ pf_compare_rdrs(struct pf_rdr *a, struct pf_rdr *b) a->opts != b->opts || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); if (PF_ANEQ(&a->smask, &b->smask, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -879,6 +893,103 @@ pf_purge_expired_states(void) } } +int +pf_dynaddr_setup(struct pf_addr_wrap *aw, u_int8_t af) +{ + if (aw->addr_dyn == NULL) + return (0); + aw->addr_dyn = pool_get(&pf_addr_pl, PR_NOWAIT); + if (aw->addr_dyn == NULL) + return (1); + bcopy(aw->addr.pfa.ifname, aw->addr_dyn->ifname, + sizeof(aw->addr_dyn->ifname)); + aw->addr_dyn->ifp = ifunit(aw->addr_dyn->ifname); + if (aw->addr_dyn->ifp == NULL) { + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; + return (1); + } + aw->addr_dyn->addr = &aw->addr; + aw->addr_dyn->af = af; + aw->addr_dyn->undefined = 1; + aw->addr_dyn->hook_cookie = hook_establish( + aw->addr_dyn->ifp->if_addrhooks, 1, + pf_dynaddr_update, aw->addr_dyn); + if (aw->addr_dyn->hook_cookie == NULL) { + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; + return (1); + } + pf_dynaddr_update(aw->addr_dyn); + return (0); +} + +void +pf_dynaddr_update(void *p) +{ + struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; + struct ifaddr *ia; + int s, changed = 0; + + if (ad == NULL || ad->ifp == NULL) + panic("pf_dynaddr_update"); + s = splsoftnet(); + TAILQ_FOREACH(ia, &ad->ifp->if_addrlist, ifa_list) + if (ia->ifa_addr != NULL && + ia->ifa_addr->sa_family == ad->af) { + if (ad->af == AF_INET) { + struct in_addr *a, *b; + + a = &ad->addr->v4; + b = &((struct sockaddr_in *)ia->ifa_addr) + ->sin_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } else if (ad->af == AF_INET6) { + struct in6_addr *a, *b; + + a = &ad->addr->v6; + b = &((struct sockaddr_in6 *)ia->ifa_addr) + ->sin6_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } + if (changed) + ad->undefined = 0; + break; + } + if (ia == NULL) + ad->undefined = 1; + splx(s); +} + +void +pf_dynaddr_remove(struct pf_addr_wrap *aw) +{ + if (aw->addr_dyn == NULL) + return; + hook_disestablish(aw->addr_dyn->ifp->if_addrhooks, + aw->addr_dyn->hook_cookie); + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; +} + +void +pf_dynaddr_copyout(struct pf_addr_wrap *aw) +{ + if (aw->addr_dyn == NULL) + return; + bcopy(aw->addr_dyn->ifname, aw->addr.pfa.ifname, + sizeof(aw->addr.pfa.ifname)); + aw->addr_dyn = (struct pf_addr_dyn *)1; +} + void pf_print_host(struct pf_addr *addr, u_int16_t p, u_int8_t af) { @@ -1003,6 +1114,8 @@ pfattach(int num) NULL); pool_init(&pf_sport_pl, sizeof(struct pf_port_node), 0, 0, 0, "pfsport", NULL); + pool_init(&pf_addr_pl, sizeof(struct pf_addr_dyn), 0, 0, 0, "pfaddr", + NULL); TAILQ_INIT(&pf_rules[0]); TAILQ_INIT(&pf_rules[1]); @@ -1129,6 +1242,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((rule = TAILQ_FIRST(pf_rules_inactive)) != NULL) { TAILQ_REMOVE(pf_rules_inactive, rule, entries); + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); pool_put(&pf_rule_pl, rule); } *ticket = ++ticket_rules_inactive; @@ -1168,7 +1283,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) rule->nr = tail->nr + 1; else rule->nr = 0; - rule->ifp = NULL; if (rule->ifname[0]) { rule->ifp = ifunit(rule->ifname); if (rule->ifp == NULL) { @@ -1187,6 +1301,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else rule->rt_ifp = NULL; + if (pf_dynaddr_setup(&rule->src.addr, rule->af) || + pf_dynaddr_setup(&rule->dst.addr, rule->af)) { + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); + pool_put(&pf_rule_pl, rule); + error = EINVAL; + break; + } rule->evaluations = rule->packets = rule->bytes = 0; TAILQ_INSERT_TAIL(pf_rules_inactive, rule, entries); break; @@ -1221,6 +1343,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old rule list. */ while ((rule = TAILQ_FIRST(old_rules)) != NULL) { TAILQ_REMOVE(old_rules, rule, entries); + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); pool_put(&pf_rule_pl, rule); } break; @@ -1259,6 +1383,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(rule, &pr->rule, sizeof(struct pf_rule)); + pf_dynaddr_copyout(&pr->rule.src.addr); + pf_dynaddr_copyout(&pr->rule.dst.addr); splx(s); break; } @@ -1295,7 +1421,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newrule->ifp = NULL; if (newrule->ifname[0]) { newrule->ifp = ifunit(newrule->ifname); if (newrule->ifp == NULL) { @@ -1303,8 +1428,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } - } - newrule->rt_ifp = NULL; + } else + newrule->ifp = NULL; if (newrule->rt_ifname[0]) { newrule->rt_ifp = ifunit(newrule->rt_ifname); if (newrule->rt_ifname == NULL) { @@ -1312,6 +1437,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newrule->rt_ifp = NULL; + if (pf_dynaddr_setup(&newrule->src.addr, newrule->af) || + pf_dynaddr_setup(&newrule->dst.addr, newrule->af)) { + pf_dynaddr_remove(&newrule->src.addr); + pf_dynaddr_remove(&newrule->dst.addr); + pool_put(&pf_rule_pl, newrule); + error = EINVAL; + break; } newrule->evaluations = newrule->packets = 0; newrule->bytes = 0; @@ -1343,6 +1477,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (n->state->rule == oldrule) n->state->rule = NULL; TAILQ_REMOVE(pf_rules_active, oldrule, entries); + pf_dynaddr_remove(&oldrule->src.addr); + pf_dynaddr_remove(&oldrule->dst.addr); pool_put(&pf_rule_pl, oldrule); } else { if (oldrule == NULL) @@ -1371,6 +1507,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_nat *nat; while ((nat = TAILQ_FIRST(pf_nats_inactive)) != NULL) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); TAILQ_REMOVE(pf_nats_inactive, nat, entries); pool_put(&pf_nat_pl, nat); } @@ -1415,6 +1554,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else nat->ifp = NULL; + if (pf_dynaddr_setup(&nat->saddr, nat->af) || + pf_dynaddr_setup(&nat->daddr, nat->af) || + pf_dynaddr_setup(&nat->raddr, nat->af)) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); + pool_put(&pf_nat_pl, nat); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_nats_inactive, nat, entries); break; } @@ -1439,6 +1588,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old nat list */ while ((nat = TAILQ_FIRST(old_nats)) != NULL) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); TAILQ_REMOVE(old_nats, nat, entries); pool_put(&pf_nat_pl, nat); } @@ -1480,6 +1632,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(nat, &pn->nat, sizeof(struct pf_nat)); + pf_dynaddr_copyout(&pn->nat.saddr); + pf_dynaddr_copyout(&pn->nat.daddr); + pf_dynaddr_copyout(&pn->nat.raddr); splx(s); break; } @@ -1515,7 +1670,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newnat->ifp = NULL; if (newnat->ifname[0]) { newnat->ifp = ifunit(newnat->ifname); if (newnat->ifp == NULL) { @@ -1523,6 +1677,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newnat->ifp = NULL; + if (pf_dynaddr_setup(&newnat->saddr, newnat->af) || + pf_dynaddr_setup(&newnat->daddr, newnat->af) || + pf_dynaddr_setup(&newnat->raddr, newnat->af)) { + pf_dynaddr_remove(&newnat->saddr); + pf_dynaddr_remove(&newnat->daddr); + pf_dynaddr_remove(&newnat->raddr); + pool_put(&pf_nat_pl, newnat); + error = EINVAL; + break; } } @@ -1545,6 +1710,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } if (pcn->action == PF_CHANGE_REMOVE) { + pf_dynaddr_remove(&oldnat->saddr); + pf_dynaddr_remove(&oldnat->daddr); + pf_dynaddr_remove(&oldnat->raddr); TAILQ_REMOVE(pf_nats_active, oldnat, entries); pool_put(&pf_nat_pl, oldnat); } else { @@ -1570,6 +1738,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((binat = TAILQ_FIRST(pf_binats_inactive)) != NULL) { TAILQ_REMOVE(pf_binats_inactive, binat, entries); + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); pool_put(&pf_binat_pl, binat); } *ticket = ++ticket_binats_inactive; @@ -1613,6 +1784,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else binat->ifp = NULL; + if (pf_dynaddr_setup(&binat->saddr, binat->af) || + pf_dynaddr_setup(&binat->daddr, binat->af) || + pf_dynaddr_setup(&binat->raddr, binat->af)) { + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); + pool_put(&pf_binat_pl, binat); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_binats_inactive, binat, entries); break; } @@ -1638,6 +1819,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old binat list */ while ((binat = TAILQ_FIRST(old_binats)) != NULL) { TAILQ_REMOVE(old_binats, binat, entries); + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); pool_put(&pf_binat_pl, binat); } break; @@ -1678,6 +1862,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(binat, &pb->binat, sizeof(struct pf_binat)); + pf_dynaddr_copyout(&pb->binat.saddr); + pf_dynaddr_copyout(&pb->binat.daddr); + pf_dynaddr_copyout(&pb->binat.raddr); splx(s); break; } @@ -1714,7 +1901,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newbinat->ifp = NULL; if (newbinat->ifname[0]) { newbinat->ifp = ifunit(newbinat->ifname); if (newbinat->ifp == NULL) { @@ -1722,6 +1908,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newbinat->ifp = NULL; + if (pf_dynaddr_setup(&newbinat->saddr, newbinat->af) || + pf_dynaddr_setup(&newbinat->daddr, newbinat->af) || + pf_dynaddr_setup(&newbinat->raddr, newbinat->af)) { + pf_dynaddr_remove(&newbinat->saddr); + pf_dynaddr_remove(&newbinat->daddr); + pf_dynaddr_remove(&newbinat->raddr); + pool_put(&pf_binat_pl, newbinat); + error = EINVAL; + break; } } @@ -1745,6 +1942,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pcn->action == PF_CHANGE_REMOVE) { TAILQ_REMOVE(pf_binats_active, oldbinat, entries); + pf_dynaddr_remove(&oldbinat->saddr); + pf_dynaddr_remove(&oldbinat->daddr); + pf_dynaddr_remove(&oldbinat->raddr); pool_put(&pf_binat_pl, oldbinat); } else { if (oldbinat == NULL) @@ -1770,6 +1970,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((rdr = TAILQ_FIRST(pf_rdrs_inactive)) != NULL) { TAILQ_REMOVE(pf_rdrs_inactive, rdr, entries); + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); pool_put(&pf_rdr_pl, rdr); } *ticket = ++ticket_rdrs_inactive; @@ -1813,6 +2016,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else rdr->ifp = NULL; + if (pf_dynaddr_setup(&rdr->saddr, rdr->af) || + pf_dynaddr_setup(&rdr->daddr, rdr->af) || + pf_dynaddr_setup(&rdr->raddr, rdr->af)) { + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); + pool_put(&pf_rdr_pl, rdr); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_rdrs_inactive, rdr, entries); break; } @@ -1838,6 +2051,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old rdr list */ while ((rdr = TAILQ_FIRST(old_rdrs)) != NULL) { TAILQ_REMOVE(old_rdrs, rdr, entries); + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); pool_put(&pf_rdr_pl, rdr); } break; @@ -1878,6 +2094,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(rdr, &pr->rdr, sizeof(struct pf_rdr)); + pf_dynaddr_copyout(&pr->rdr.saddr); + pf_dynaddr_copyout(&pr->rdr.daddr); + pf_dynaddr_copyout(&pr->rdr.raddr); splx(s); break; } @@ -1913,7 +2132,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newrdr->ifp = NULL; if (newrdr->ifname[0]) { newrdr->ifp = ifunit(newrdr->ifname); if (newrdr->ifp == NULL) { @@ -1921,6 +2139,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newrdr->ifp = NULL; + if (pf_dynaddr_setup(&newrdr->saddr, newrdr->af) || + pf_dynaddr_setup(&newrdr->daddr, newrdr->af) || + pf_dynaddr_setup(&newrdr->raddr, newrdr->af)) { + pf_dynaddr_remove(&newrdr->saddr); + pf_dynaddr_remove(&newrdr->daddr); + pf_dynaddr_remove(&newrdr->raddr); + pool_put(&pf_rdr_pl, newrdr); + error = EINVAL; + break; } } @@ -1944,6 +2173,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pcn->action == PF_CHANGE_REMOVE) { TAILQ_REMOVE(pf_rdrs_active, oldrdr, entries); + pf_dynaddr_remove(&oldrdr->saddr); + pf_dynaddr_remove(&oldrdr->daddr); + pf_dynaddr_remove(&oldrdr->raddr); pool_put(&pf_rdr_pl, oldrdr); } else { if (oldrdr == NULL) @@ -1988,9 +2220,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) st = n->state; if ((!psk->psk_af || st->af == psk->psk_af) && (!psk->psk_proto || psk->psk_proto == st->proto) && - PF_MATCHA(psk->psk_src.not, &psk->psk_src.addr, + PF_MATCHA(psk->psk_src.not, &psk->psk_src.addr.addr, &psk->psk_src.mask, &st->lan.addr, st->af) && - PF_MATCHA(psk->psk_dst.not, &psk->psk_dst.addr, + PF_MATCHA(psk->psk_dst.not, &psk->psk_dst.addr.addr, &psk->psk_dst.mask, &st->ext.addr, st->af) && (psk->psk_src.port_op == 0 || pf_match_port(psk->psk_src.port_op, @@ -2304,7 +2536,9 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) PF_CALC_SKIP_STEP(PF_SKIP_AF, s->af == r->af); PF_CALC_SKIP_STEP(PF_SKIP_PROTO, s->proto == r->proto); PF_CALC_SKIP_STEP(PF_SKIP_SRC_ADDR, - PF_AEQ(&s->src.addr, &r->src.addr, r->af) && + s->src.addr.addr_dyn == NULL && + r->src.addr.addr_dyn == NULL && + PF_AEQ(&s->src.addr.addr, &r->src.addr.addr, r->af) && PF_AEQ(&s->src.mask, &r->src.mask, r->af) && s->src.not == r->src.not); PF_CALC_SKIP_STEP(PF_SKIP_SRC_PORT, @@ -2312,7 +2546,9 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) s->src.port[1] == r->src.port[1] && s->src.port_op == r->src.port_op); PF_CALC_SKIP_STEP(PF_SKIP_DST_ADDR, - PF_AEQ(&s->dst.addr, &r->dst.addr, r->af) && + s->dst.addr.addr_dyn == NULL && + r->dst.addr.addr_dyn == NULL && + PF_AEQ(&s->dst.addr.addr, &r->dst.addr.addr, r->af) && PF_AEQ(&s->dst.mask, &r->dst.mask, r->af) && s->dst.not == r->dst.not); PF_CALC_SKIP_STEP(PF_SKIP_DST_PORT, @@ -2829,13 +3065,18 @@ pf_get_nat(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, (n->ifp != ifp && n->ifnot)) && (!n->proto || n->proto == proto) && (!n->af || n->af == af) && - PF_MATCHA(n->snot, &n->saddr, &n->smask, saddr, af) && - PF_MATCHA(n->dnot, &n->daddr, &n->dmask, daddr, af)) + (n->saddr.addr_dyn == NULL || + !n->saddr.addr_dyn->undefined) && + PF_MATCHA(n->snot, &n->saddr.addr, &n->smask, saddr, af) && + (n->daddr.addr_dyn == NULL || + !n->daddr.addr_dyn->undefined) && + PF_MATCHA(n->dnot, &n->daddr.addr, &n->dmask, daddr, af)) nm = n; else n = TAILQ_NEXT(n, entries); } - if (nm && nm->no) + if (nm && (nm->no || (nm->raddr.addr_dyn != NULL && + nm->raddr.addr_dyn->undefined))) return (NULL); return (nm); } @@ -2854,20 +3095,34 @@ pf_get_binat(int direction, struct ifnet *ifp, u_int8_t proto, if (direction == PF_OUT && b->ifp == ifp && (!b->proto || b->proto == proto) && (!b->af || b->af == af) && - PF_MATCHA(0, &b->saddr, &fullmask, saddr, af) && - PF_MATCHA(b->dnot, &b->daddr, &b->dmask, daddr, af)) + (b->saddr.addr_dyn == NULL || + !b->saddr.addr_dyn->undefined) && + PF_MATCHA(0, &b->saddr.addr, &fullmask, saddr, af) && + (b->daddr.addr_dyn == NULL || + !b->daddr.addr_dyn->undefined) && + PF_MATCHA(b->dnot, &b->daddr.addr, &b->dmask, daddr, af)) bm = b; else if (direction == PF_IN && b->ifp == ifp && (!b->proto || b->proto == proto) && (!b->af || b->af == af) && - PF_MATCHA(0, &b->raddr, &fullmask, saddr, af) && - PF_MATCHA(b->dnot, &b->daddr, &b->dmask, daddr, af)) + (b->raddr.addr_dyn == NULL || + !b->raddr.addr_dyn->undefined) && + PF_MATCHA(0, &b->raddr.addr, &fullmask, saddr, af) && + (b->daddr.addr_dyn == NULL || + !b->daddr.addr_dyn->undefined) && + PF_MATCHA(b->dnot, &b->daddr.addr, &b->dmask, daddr, af)) bm = b; else b = TAILQ_NEXT(b, entries); } if (bm && bm->no) return (NULL); + if (bm && direction == PF_OUT && bm->raddr.addr_dyn != NULL && + bm->raddr.addr_dyn->undefined) + return (NULL); + if (bm && direction == PF_IN && bm->saddr.addr_dyn != NULL && + bm->saddr.addr_dyn->undefined) + return (NULL); return (bm); } @@ -2883,8 +3138,12 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, (r->ifp != ifp && r->ifnot)) && (!r->proto || r->proto == proto) && (!r->af || r->af == af) && - PF_MATCHA(r->snot, &r->saddr, &r->smask, saddr, af) && - PF_MATCHA(r->dnot, &r->daddr, &r->dmask, daddr, af) && + (r->saddr.addr_dyn == NULL || + !r->saddr.addr_dyn->undefined) && + PF_MATCHA(r->snot, &r->saddr.addr, &r->smask, saddr, af) && + (r->daddr.addr_dyn == NULL || + !r->daddr.addr_dyn->undefined) && + PF_MATCHA(r->dnot, &r->daddr.addr, &r->dmask, daddr, af) && ((!r->dport2 && (!r->dport || dport == r->dport)) || (r->dport2 && (ntohs(dport) >= ntohs(r->dport)) && ntohs(dport) <= ntohs(r->dport2)))) @@ -2892,7 +3151,8 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, else r = TAILQ_NEXT(r, entries); } - if (rm && rm->no) + if (rm && (rm->no || (rm->raddr.addr_dyn != NULL && + rm->raddr.addr_dyn->undefined))) return (NULL); return (rm); } @@ -2933,7 +3193,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, saddr, af); bport = th->th_sport; pf_change_ap(saddr, &th->th_sport, pd->ip_sum, - &th->th_sum, &binat->raddr, th->th_sport, 0, af); + &th->th_sum, &binat->raddr.addr, th->th_sport, 0, af); rewrite++; } /* check outgoing packet for NAT */ @@ -2946,7 +3206,8 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, return (PF_DROP); PF_ACPY(&baddr, saddr, af); pf_change_ap(saddr, &th->th_sport, pd->ip_sum, - &th->th_sum, &nat->raddr, htons(nport), 0, af); + &th->th_sum, &nat->raddr.addr, htons(nport), + 0, af); rewrite++; } } else { @@ -2962,7 +3223,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, nport = bport; PF_ACPY(&baddr, daddr, af); pf_change_ap(daddr, &th->th_dport, pd->ip_sum, - &th->th_sum, &rdr->raddr, nport, 0, af); + &th->th_sum, &rdr->raddr.addr, nport, 0, af); rewrite++; } /* check incoming packet for BINAT */ @@ -2971,7 +3232,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); bport = th->th_dport; pf_change_ap(daddr, &th->th_dport, pd->ip_sum, - &th->th_sum, &binat->saddr, th->th_dport, 0, af); + &th->th_sum, &binat->saddr.addr, th->th_dport, 0, af); rewrite++; } } @@ -2993,7 +3254,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, saddr, af)) + &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], th->th_sport)) @@ -3002,7 +3263,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, daddr, af)) + &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], th->th_dport)) @@ -3166,7 +3427,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, saddr, af); bport = uh->uh_sport; pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, - &uh->uh_sum, &binat->raddr, uh->uh_sport, 1, af); + &uh->uh_sum, &binat->raddr.addr, uh->uh_sport, 1, af); rewrite++; } /* check outgoing packet for NAT */ @@ -3179,7 +3440,8 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, return (PF_DROP); PF_ACPY(&baddr, saddr, af); pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, - &uh->uh_sum, &nat->raddr, htons(nport), 1, af); + &uh->uh_sum, &nat->raddr.addr, htons(nport), + 1, af); rewrite++; } } else { @@ -3196,7 +3458,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, - &uh->uh_sum, &rdr->raddr, nport, 1, af); + &uh->uh_sum, &rdr->raddr.addr, nport, 1, af); rewrite++; } /* check incoming packet for BINAT */ @@ -3205,7 +3467,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); bport = uh->uh_dport; pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, - &uh->uh_sum, &binat->saddr, uh->uh_dport, 1, af); + &uh->uh_sum, &binat->saddr.addr, uh->uh_dport, 1, af); rewrite++; } } @@ -3227,7 +3489,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, @@ -3237,7 +3499,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, @@ -3413,13 +3675,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, pd->ip_sum, - binat->raddr.v4.s_addr, 0); + binat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, - &binat->raddr, 0); + &binat->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3433,13 +3695,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, - pd->ip_sum, nat->raddr.v4.s_addr, 0); + pd->ip_sum, nat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, - &nat->raddr, 0); + &nat->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3454,13 +3716,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, rdr->raddr.v4.s_addr, 0); + pd->ip_sum, rdr->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, - &rdr->raddr, 0); + &rdr->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3474,13 +3736,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, binat->saddr.v4.s_addr, 0); + pd->ip_sum, binat->saddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, - &binat->saddr, 0); + &binat->saddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3505,13 +3767,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, saddr, af)) + &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(daddr, af)) r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, daddr, af)) + &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->ifp != NULL && r->ifp != ifp) r = TAILQ_NEXT(r, entries); @@ -3632,12 +3894,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, pd->ip_sum, - binat->raddr.v4.s_addr, 0); + binat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(saddr, &binat->raddr, af); + PF_ACPY(saddr, &binat->raddr.addr, af); break; #endif /* INET6 */ } @@ -3650,12 +3912,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, - pd->ip_sum, nat->raddr.v4.s_addr, 0); + pd->ip_sum, nat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(saddr, &nat->raddr, af); + PF_ACPY(saddr, &nat->raddr.addr, af); break; #endif /* INET6 */ } @@ -3669,12 +3931,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, rdr->raddr.v4.s_addr, 0); + pd->ip_sum, rdr->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(daddr, &rdr->raddr, af); + PF_ACPY(daddr, &rdr->raddr.addr, af); break; #endif /* INET6 */ } @@ -3687,12 +3949,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, binat->saddr.v4.s_addr, 0); + pd->ip_sum, binat->saddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(daddr, &binat->saddr, af); + PF_ACPY(daddr, &binat->saddr.addr, af); break; #endif /* INET6 */ } @@ -3716,13 +3978,13 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, pd->src, af)) + &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, pd->dst, af)) + &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->rule_flag & PFRULE_FRAGMENT) r = TAILQ_NEXT(r, entries); @@ -3829,13 +4091,13 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, pd->src, af)) + &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, pd->dst, af)) + &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->src.port_op || r->dst.port_op || r->flagset || r->type || r->code) diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index c4fb2447653..5cf6404ea1f 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.23 2002/04/20 18:26:03 dhartmei Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.24 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -451,11 +451,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) else if (r->proto && r->proto != h->ip_p) r = r->skip[PF_SKIP_PROTO]; else if (!PF_AZERO(&r->src.mask, AF_INET) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, (struct pf_addr *)&h->ip_src.s_addr, AF_INET)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (!PF_AZERO(&r->dst.mask, AF_INET) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, (struct pf_addr *)&h->ip_dst.s_addr, AF_INET)) r = r->skip[PF_SKIP_DST_ADDR]; else @@ -590,7 +590,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, else if (r->src.noroute && pf_routable(pd->src, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, @@ -599,7 +599,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 824be2b28bd..dfac723cae6 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.67 2002/04/23 14:32:22 dhartmei Exp $ */ +/* $OpenBSD: pfvar.h,v 1.68 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -60,6 +60,7 @@ struct pf_addr { u_int8_t addr8[16]; u_int16_t addr16[8]; u_int32_t addr32[4]; + char ifname[IFNAMSIZ]; } pfa; /* 128-bit address */ #define v4 pfa.v4 #define v6 pfa.v6 @@ -68,6 +69,20 @@ struct pf_addr { #define addr32 pfa.addr32 }; +struct pf_addr_wrap { + struct pf_addr addr; + struct pf_addr_dyn *addr_dyn; +}; + +struct pf_addr_dyn { + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + struct pf_addr *addr; + u_int8_t af; + void *hook_cookie; + u_int8_t undefined; +}; + /* * Address manipulation macros */ @@ -182,25 +197,17 @@ struct pf_addr { #endif /* PF_INET_INET6 */ struct pf_rule_addr { - struct pf_addr addr; - struct pf_addr mask; - u_int16_t port[2]; - u_int8_t not; - u_int8_t port_op; - u_int8_t noroute; + struct pf_addr_wrap addr; + struct pf_addr mask; + u_int16_t port[2]; + u_int8_t not; + u_int8_t port_op; + u_int8_t noroute; }; struct pf_rule { - char ifname[IFNAMSIZ]; - char rt_ifname[IFNAMSIZ]; -#define PF_RULE_LABEL_SIZE 32 - char label[PF_RULE_LABEL_SIZE]; - struct ifnet *ifp; - struct ifnet *rt_ifp; - struct pf_rule_addr src; - struct pf_rule_addr dst; - struct pf_addr rt_addr; - + struct pf_rule_addr src; + struct pf_rule_addr dst; #define PF_SKIP_ACTION 0 #define PF_SKIP_IFP 1 #define PF_SKIP_DIR 2 @@ -211,36 +218,44 @@ struct pf_rule { #define PF_SKIP_DST_ADDR 7 #define PF_SKIP_DST_PORT 8 #define PF_SKIP_COUNT 9 - struct pf_rule *skip[PF_SKIP_COUNT]; - TAILQ_ENTRY(pf_rule) entries; + struct pf_rule *skip[PF_SKIP_COUNT]; +#define PF_RULE_LABEL_SIZE 32 + char label[PF_RULE_LABEL_SIZE]; + struct pf_addr rt_addr; + char ifname[IFNAMSIZ]; + char rt_ifname[IFNAMSIZ]; + TAILQ_ENTRY(pf_rule) entries; - u_int64_t evaluations; - u_int64_t packets; - u_int64_t bytes; + u_int64_t evaluations; + u_int64_t packets; + u_int64_t bytes; - u_int16_t nr; - u_int16_t return_icmp; + struct ifnet *ifp; + struct ifnet *rt_ifp; - u_int8_t action; - u_int8_t direction; - u_int8_t log; - u_int8_t quick; + u_int16_t nr; + u_int16_t return_icmp; + + u_int8_t action; + u_int8_t direction; + u_int8_t log; + u_int8_t quick; #define PF_STATE_NORMAL 0x1 #define PF_STATE_MODULATE 0x2 - u_int8_t keep_state; - u_int8_t af; - u_int8_t proto; - u_int8_t type; - u_int8_t code; - - u_int8_t flags; - u_int8_t flagset; - - u_int8_t rule_flag; - u_int8_t min_ttl; /* minimum ttl for packet normalize */ - u_int8_t allow_opts; - u_int8_t rt; + u_int8_t keep_state; + u_int8_t af; + u_int8_t proto; + u_int8_t type; + u_int8_t code; + + u_int8_t flags; + u_int8_t flagset; + + u_int8_t rule_flag; + u_int8_t min_ttl; + u_int8_t allow_opts; + u_int8_t rt; }; #define PFRULE_RETURNRST 0x01 @@ -282,55 +297,55 @@ struct pf_state { }; struct pf_nat { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_nat) entries; - struct pf_addr saddr; - struct pf_addr smask; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int8_t af; - u_int8_t proto; - u_int8_t snot; - u_int8_t dnot; - u_int8_t ifnot; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_nat) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr smask; + struct pf_addr dmask; + u_int8_t af; + u_int8_t proto; + u_int8_t snot; + u_int8_t dnot; + u_int8_t ifnot; + u_int8_t no; }; struct pf_binat { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_binat) entries; - struct pf_addr saddr; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int8_t af; - u_int8_t proto; - u_int8_t dnot; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_binat) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr dmask; + u_int8_t af; + u_int8_t proto; + u_int8_t dnot; + u_int8_t no; }; struct pf_rdr { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_rdr) entries; - struct pf_addr saddr; - struct pf_addr smask; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int16_t dport; - u_int16_t dport2; - u_int16_t rport; - u_int8_t af; - u_int8_t proto; - u_int8_t snot; - u_int8_t dnot; - u_int8_t ifnot; - u_int8_t opts; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_rdr) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr smask; + struct pf_addr dmask; + u_int16_t dport; + u_int16_t dport2; + u_int16_t rport; + u_int8_t af; + u_int8_t proto; + u_int8_t snot; + u_int8_t dnot; + u_int8_t ifnot; + u_int8_t opts; + u_int8_t no; }; struct pf_tree_key { |