The kernel does not set the address family for the socket addresses
authorbluhm <bluhm@openbsd.org>
Sun, 16 Sep 2018 19:36:33 +0000 (19:36 +0000)
committerbluhm <bluhm@openbsd.org>
Sun, 16 Sep 2018 19:36:33 +0000 (19:36 +0000)
that are used for netmask, broadcast, and destination address.  In
pfctl(8) take the family of the interface address and write it to
the other addresses.  This fixes some bugs when copy_satopfaddr()
copied only part of IPv6 addresses.  Print a warning if the address
family is unknown.
OK kn@

sbin/pfctl/pfctl_parser.c

index e9a2699..9a1673a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pfctl_parser.c,v 1.337 2018/09/13 06:03:27 kn Exp $ */
+/*     $OpenBSD: pfctl_parser.c,v 1.338 2018/09/16 19:36:33 bluhm Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -216,8 +216,10 @@ copy_satopfaddr(struct pf_addr *pfa, struct sockaddr *sa)
 {
        if (sa->sa_family == AF_INET6)
                pfa->v6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
-       else
+       else if (sa->sa_family == AF_INET)
                pfa->v4 = ((struct sockaddr_in *)sa)->sin_addr;
+       else
+               warnx("unhandled af %d", sa->sa_family);
 }
 
 const struct icmptypeent *
@@ -1383,11 +1385,16 @@ ifa_load(void)
                            ifa->ifa_addr)->sdl_index;
                else {
                        copy_satopfaddr(&n->addr.v.a.addr, ifa->ifa_addr);
+                       ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;
                        copy_satopfaddr(&n->addr.v.a.mask, ifa->ifa_netmask);
-                       if (ifa->ifa_broadaddr != NULL)
+                       if (ifa->ifa_broadaddr != NULL) {
+                               ifa->ifa_broadaddr->sa_family = ifa->ifa_addr->sa_family;
                                copy_satopfaddr(&n->bcast, ifa->ifa_broadaddr);
-                       if (ifa->ifa_dstaddr != NULL)
+                       }
+                       if (ifa->ifa_dstaddr != NULL) {
+                               ifa->ifa_dstaddr->sa_family = ifa->ifa_addr->sa_family;
                                copy_satopfaddr(&n->peer, ifa->ifa_dstaddr);
+                       }
                        if (n->af == AF_INET6)
                                n->ifindex = ((struct sockaddr_in6 *)
                                    ifa->ifa_addr)->sin6_scope_id;