
NetBSD and OpenBSD don't set the address family on the "netmask" address.
Work around that by just setting the address family field after ioctl() and
before checking it.

if_hwaddr() was broken, code looping all interfaces was causing segmentation
fault on freeifaddrs()

$OpenBSD: patch-Interface_xs,v 1.2 2010/08/30 03:48:17 kevlo Exp $
--- Interface.xs.orig	Fri Jun  6 16:51:42 2008
+++ Interface.xs	Sun Aug 29 01:53:48 2010
@@ -2,6 +2,9 @@
 #include "perl.h"
 #include "XSUB.h"
 
+#include <stdio.h>
+#include <string.h>
+
 /* socket definitions */
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -511,6 +514,9 @@ if_netmask(sock, name, ...)
 	  operation = SIOCGIFNETMASK;
      }
      if (!Ioctl(sock,operation,&ifr)) XSRETURN_UNDEF;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+     ifr.ifr_addr.sa_family = AF_INET;
+#endif
      if (ifr.ifr_addr.sa_family != AF_INET) croak ("Address is not in the AF_INET family.\n");
      RETVAL = inet_ntoa(((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr);
 #endif
@@ -566,7 +572,7 @@ if_hwaddr(sock, name, ...)
      IOCTL_CMD_T    operation;
      struct ifreq   ifr;
 #if (defined(USE_GETIFADDRS) && defined(HAVE_SOCKADDR_DL_STRUCT))
-     struct ifaddrs* ifap = NULL;
+     struct ifaddrs *ifap, *ifa;
      struct sockaddr_dl* sdl;
      sa_family_t  family;
      char *sdlname, *haddr, *s;
@@ -582,20 +588,17 @@ if_hwaddr(sock, name, ...)
 #if (defined(USE_GETIFADDRS) && defined(HAVE_SOCKADDR_DL_STRUCT))
      getifaddrs(&ifap);
 
-     while(1) {
-       if (ifap == NULL) break;
-       if (strncmp(name, ifap -> ifa_name, IFNAMSIZ) == 0) {
-         family = ifap -> ifa_addr -> sa_family;
+     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+       if (strncmp(name, ifa->ifa_name, IFNAMSIZ) == 0) {
+         family = ifa->ifa_addr->sa_family;
          if (family == AF_LINK) {
-           sdl = (struct sockaddr_dl *) ifap->ifa_addr;
+           sdl = (struct sockaddr_dl *) ifa->ifa_addr;
            haddr = sdl->sdl_data + sdl->sdl_nlen;
            hlen = sdl->sdl_alen;
            break;
          }
        }
-       ifap = ifap -> ifa_next;
      } 
-     freeifaddrs(ifap);
 
      s = hwaddr; 
      s[0] = '\0';
@@ -608,6 +611,9 @@ if_hwaddr(sock, name, ...)
          s += len;
        }
      }
+
+     freeifaddrs(ifap);
+
      RETVAL = hwaddr;
 #elif (defined(HAS_IOCTL) && defined(SIOCGIFHWADDR))
      bzero((void*)&ifr,sizeof(struct ifreq));
