import of dnsmasq-2.41.tar.gz
diff --git a/src/bpf.c b/src/bpf.c
index 2dbc4f1..1b71f3c 100644
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -1,20 +1,22 @@
-/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 dated June, 1991.
-
+   the Free Software Foundation; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+ 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
+     
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "dnsmasq.h"
 
-#ifndef HAVE_LINUX_NETWORK
-
-#include <net/bpf.h>
+#if defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
 
 static struct iovec ifconf = {
   .iov_base = NULL,
@@ -26,6 +28,107 @@
   .iov_len = 0
 };
 
+int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
+{
+  char *ptr;
+  struct ifreq *ifr;
+  struct ifconf ifc;
+  int fd, errsav, ret = 0;
+  int lastlen = 0;
+  size_t len = 0;
+  
+  if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
+    return 0;
+  
+  while(1)
+    {
+      len += 10*sizeof(struct ifreq);
+      
+      if (!expand_buf(&ifconf, len))
+	goto err;
+      
+      ifc.ifc_len = len;
+      ifc.ifc_buf = ifconf.iov_base;
+      
+      if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
+	{
+	  if (errno != EINVAL || lastlen != 0)
+	    goto err;
+	}
+      else
+	{
+	  if (ifc.ifc_len == lastlen)
+	    break; /* got a big enough buffer now */
+	  lastlen = ifc.ifc_len;
+	}
+    }
+  
+  for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len; ptr += len )
+    {
+      /* subsequent entries may not be aligned, so copy into
+	 an aligned buffer to avoid nasty complaints about 
+	 unaligned accesses. */
+#ifdef HAVE_SOCKADDR_SA_LEN
+      len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE;
+#else
+      len = sizeof(struct ifreq);
+#endif
+      if (!expand_buf(&ifreq, len))
+	goto err;
+
+      ifr = (struct ifreq *)ifreq.iov_base;
+      memcpy(ifr, ptr, len);
+           
+      if (ifr->ifr_addr.sa_family == AF_INET && ipv4_callback)
+	{
+	  struct in_addr addr, netmask, broadcast;
+	  broadcast.s_addr = 0;
+	  addr = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
+	  if (ioctl(fd, SIOCGIFNETMASK, ifr) == -1)
+	    continue;
+	  netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
+	  if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1)
+	    broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr; 
+	  if (!((*ipv4_callback)(addr, 
+				 (int)if_nametoindex(ifr->ifr_name),
+				 netmask, broadcast, 
+				 parm)))
+	    goto err;
+	}
+#ifdef HAVE_IPV6
+      else if (ifr->ifr_addr.sa_family == AF_INET6 && ipv6_callback)
+	{
+	  struct in6_addr *addr = &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr;
+	  /* voodoo to clear interface field in address */
+	  if (!(daemon->options & OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
+	    {
+	      addr->s6_addr[2] = 0;
+	      addr->s6_addr[3] = 0;
+	    }
+	  if (!((*ipv6_callback)(addr,
+				 (int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
+				 (int)if_nametoindex(ifr->ifr_name),
+				 parm)))
+	    goto err;
+	}
+#endif
+    }
+  
+  ret = 1;
+
+ err:
+  errsav = errno;
+  close(fd);  
+  errno = errsav;
+
+  return ret;
+}
+#endif
+
+
+#if defined(HAVE_BSD_NETWORK)
+#include <net/bpf.h>
+
 void init_bpf(void)
 {
   int i = 0;
@@ -116,8 +219,10 @@
   udp.uh_sum = 0;
   udp.uh_ulen = sum = htons(sizeof(struct udphdr) + len);
   sum += htons(IPPROTO_UDP);
-  for (i = 0; i < 4; i++)
-    sum += ((u16 *)&ip.ip_src)[i];
+  sum += ip.ip_src.s_addr & 0xffff;
+  sum += (ip.ip_src.s_addr >> 16) & 0xffff;
+  sum += ip.ip_dst.s_addr & 0xffff;
+  sum += (ip.ip_dst.s_addr >> 16) & 0xffff;
   for (i = 0; i < sizeof(struct udphdr)/2; i++)
     sum += ((u16 *)&udp)[i];
   for (i = 0; i < (len + 1) / 2; i++)
@@ -140,100 +245,6 @@
   while (writev(daemon->dhcp_raw_fd, iov, 4) == -1 && retry_send());
 }
 
-int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
-{
-  char *ptr;
-  struct ifreq *ifr;
-  struct ifconf ifc;
-  int fd, errsav, ret = 0;
-  int lastlen = 0;
-  size_t len = 0;
-  
-  if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-    return 0;
-  
-  while(1)
-    {
-      len += 10*sizeof(struct ifreq);
-      
-      if (!expand_buf(&ifconf, len))
-	goto err;
-      
-      ifc.ifc_len = len;
-      ifc.ifc_buf = ifconf.iov_base;
-      
-      if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
-	{
-	  if (errno != EINVAL || lastlen != 0)
-	    goto err;
-	}
-      else
-	{
-	  if (ifc.ifc_len == lastlen)
-	    break; /* got a big enough buffer now */
-	  lastlen = ifc.ifc_len;
-	}
-    }
-  
-  for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len; ptr += len )
-    {
-      /* subsequent entries may not be aligned, so copy into
-	 an aligned buffer to avoid nasty complaints about 
-	 unaligned accesses. */
-#ifdef HAVE_SOCKADDR_SA_LEN
-      len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE;
-#else
-      len = sizeof(struct ifreq);
 #endif
-      if (!expand_buf(&ifreq, len))
-	goto err;
 
-      ifr = ifreq.iov_base;
-      memcpy(ifr, ptr, len);
-           
-      if (ifr->ifr_addr.sa_family == AF_INET && ipv4_callback)
-	{
-	  struct in_addr addr, netmask, broadcast;
-	  broadcast.s_addr = 0;
-	  addr = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
-	  if (ioctl(fd, SIOCGIFNETMASK, ifr) == -1)
-	    continue;
-	  netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
-	  if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1)
-	    broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr; 
-	  if (!((*ipv4_callback)(addr, 
-				 (int)if_nametoindex(ifr->ifr_name),
-				 netmask, broadcast, 
-				 parm)))
-	    goto err;
-	}
-#ifdef HAVE_IPV6
-      else if (ifr->ifr_addr.sa_family == AF_INET6 && ipv6_callback)
-	{
-	  struct in6_addr *addr = &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr;
-	  /* voodoo to clear interface field in address */
-	  if (!(daemon->options & OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
-	    {
-	      addr->s6_addr[2] = 0;
-	      addr->s6_addr[3] = 0;
-	    }
-	  if (!((*ipv6_callback)(addr,
-				 (int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
-				 (int)if_nametoindex(ifr->ifr_name),
-				 parm)))
-	    goto err;
-	}
-#endif
-    }
-  
-  ret = 1;
 
- err:
-  errsav = errno;
-  close(fd);  
-  errno = errsav;
-
-  return ret;
-}
-
-#endif