Hello community,

here is the log from the commit of package python-netifaces for 
openSUSE:Factory checked in at 2017-04-28 09:12:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-netifaces (Old)
 and      /work/SRC/openSUSE:Factory/.python-netifaces.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-netifaces"

Fri Apr 28 09:12:11 2017 rev:11 rq:484783 version:0.10.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-netifaces/python-netifaces.changes        
2014-05-26 14:43:43.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-netifaces.new/python-netifaces.changes   
2017-04-28 09:12:24.153703661 +0200
@@ -1,0 +2,17 @@
+Fri Mar 31 17:31:37 UTC 2017 - [email protected]
+
+- Use pypi.io as source url.
+
+-------------------------------------------------------------------
+Sat Mar 18 19:50:34 UTC 2017 - [email protected]
+
+- Update to version 0.10.5:
+  * Fix setup.py in case there's no print
+  * Fix a potential one-byte stack overwrite
+  * Fix possible null pointer deference
+  * Respect interface priorities when determining default gateway
+  * Use CIDR notation for IPv6 netmasks
+  * Ignore broadcast addresses in the 169.254.0.0/16 range
+- Convert package to python singlespec.
+
+-------------------------------------------------------------------

Old:
----
  netifaces-0.10.4.tar.gz

New:
----
  netifaces-0.10.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-netifaces.spec ++++++
--- /var/tmp/diff_new_pack.2GfRn8/_old  2017-04-28 09:12:24.989585791 +0200
+++ /var/tmp/diff_new_pack.2GfRn8/_new  2017-04-28 09:12:24.993585227 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-netifaces
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 # Copyright (c) 2011 Novell
 #
 # All modifications and additions to the file contributed by third parties
@@ -17,21 +17,21 @@
 #
 
 
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-netifaces
-Version:        0.10.4
+Version:        0.10.5
 Release:        0
 Summary:        Portable network interface information
 License:        MIT
 Group:          Development/Languages/Python
 Url:            http://alastairs-place.net/projects/netifaces/
-Source:         
https://pypi.python.org/packages/source/n/netifaces/netifaces-%{version}.tar.gz
-BuildRequires:  python-devel
-BuildRequires:  python-setuptools
-Provides:       netifaces
+Source:         
https://pypi.io/packages/source/n/netifaces/netifaces-%{version}.tar.gz
+BuildRequires:  %{python_module devel}
+BuildRequires:  %{python_module setuptools}
+BuildRequires:  python-rpm-macros
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-%{!?python_sitearch: %global python_sitearch %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
-%endif
+
+%python_subpackages
 
 %description
 netifaces provides a (hopefully portable-ish) way for Python programmers to
@@ -50,12 +50,12 @@
 %setup -q -n netifaces-%{version}
 
 %build
-python setup.py build
+%python_build
 
 %install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%python_install
 
-%files
+%files %{python_files}
 %defattr(-,root,root,-)
 %doc README.rst
 %{python_sitearch}/*

++++++ netifaces-0.10.4.tar.gz -> netifaces-0.10.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/netifaces-0.10.4/PKG-INFO 
new/netifaces-0.10.5/PKG-INFO
--- old/netifaces-0.10.4/PKG-INFO       2014-05-19 13:40:12.000000000 +0200
+++ new/netifaces-0.10.5/PKG-INFO       2016-08-23 17:28:47.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: netifaces
-Version: 0.10.4
+Version: 0.10.5
 Summary: Portable network interface information.
 Home-page: https://bitbucket.org/al45tair/netifaces
 Author: Alastair Houghton
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/netifaces-0.10.4/netifaces.c 
new/netifaces-0.10.5/netifaces.c
--- old/netifaces-0.10.4/netifaces.c    2014-05-19 13:38:09.000000000 +0200
+++ new/netifaces-0.10.5/netifaces.c    2016-08-23 17:00:14.000000000 +0200
@@ -45,6 +45,14 @@
 #    include <arpa/inet.h>
 #  endif
 
+#  if HAVE_GETIFADDRS
+#    if HAVE_IPV6_SOCKET_IOCTLS
+#      include <sys/ioctl.h>
+#      include <netinet/in.h>
+#      include <netinet/in_var.h>
+#    endif
+#  endif
+
 #  if HAVE_SOCKET_IOCTLS
 #    include <sys/ioctl.h>
 #    include <netinet/in.h>
@@ -397,7 +405,8 @@
       sprintf (ptr, "%02x:", data[n] & 0xff);
       ptr += 3;
     }
-    *--ptr = '\0';
+    if (len)
+      *--ptr = '\0';
   }
 
   if (!buffer[0])
@@ -405,6 +414,94 @@
 
   return 0;
 }
+
+/* Tries to format in CIDR form where possible; falls back to using
+   string_from_sockaddr(). */
+static int
+string_from_netmask (struct sockaddr *addr,
+                     char *buffer,
+                     int buflen)
+{
+#ifdef AF_INET6
+  if (addr && addr->sa_family == AF_INET6) {
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
+    unsigned n = 16;
+    unsigned zeroes = 0;
+    unsigned prefix;
+    unsigned bytes;
+    char *bufptr = buffer;
+    char *bufend = buffer + buflen;
+    char pfxbuf[16];
+
+    while (n--) {
+      unsigned char byte = sin6->sin6_addr.s6_addr[n];
+
+      /* We need to count the rightmost zeroes */
+      unsigned char x = byte;
+      unsigned zx = 8;
+
+      x &= -x;
+      if (x)
+        --zx;
+      if (x & 0x0f)
+        zx -= 4;
+      if (x & 0x03)
+        zx -= 2;
+      if (x & 0x05)
+        zx -= 1;
+
+      zeroes += zx;
+
+      if (byte)
+        break;
+    }
+
+    prefix = 128 - zeroes;
+    bytes = 2 * ((prefix + 15) / 16);
+
+    for (n = 0; n < bytes; ++n) {
+      unsigned char byte = sin6->sin6_addr.s6_addr[n];
+      char ch1, ch2;
+
+      if (n && !(n & 1)) {
+        if (bufptr < bufend)
+          *bufptr++ = ':';
+      }
+
+      ch1 = '0' + (byte >> 4);
+      if (ch1 > '9')
+        ch1 += 'a' - '0' - 10;
+      ch2 = '0' + (byte & 0xf);
+      if (ch2 > '9')
+        ch2 += 'a' - '0' - 10;
+
+      if (bufptr < bufend)
+        *bufptr++ = ch1;
+      if (bufptr < bufend)
+        *bufptr++ = ch2;
+    }
+
+    if (bytes < 16) {
+      if (bufend - bufptr > 2) {
+        *bufptr++ = ':';
+        *bufptr++ = ':';
+      }
+    }
+
+    sprintf (pfxbuf, "/%u", prefix);
+
+    if (bufend - bufptr > strlen(pfxbuf))
+      strcpy (bufptr, pfxbuf);
+
+    if (buflen)
+      buffer[buflen - 1] = '\0';
+
+    return 0;
+  }
+#endif
+
+  return string_from_sockaddr(addr, buffer, buflen);
+}
 #endif /* !defined(WIN32) */
 
 #if defined(WIN32)
@@ -440,6 +537,135 @@
 
   return 0;
 }
+
+static PyObject *
+netmask_from_prefix (unsigned prefix)
+{
+  char buffer[256];
+  char *bufptr = buffer;
+  char *bufend = buffer + sizeof(buffer);
+  unsigned bytes = 2 * ((prefix + 15) / 16);
+  static const unsigned char masks[] = {
+    0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
+  };
+  unsigned n;
+  unsigned left = prefix;
+  char pfxbuf[16];
+
+  for (n = 0; n < bytes; ++n) {
+    unsigned char byte;
+    char ch1, ch2;
+
+    if (left >= 8) {
+      byte = 0xff;
+      left -= 8;
+    } else {
+      byte = masks[left];
+      left = 0;
+    }
+
+    if (n && !(n & 1)) {
+      if (bufptr < bufend)
+        *bufptr++ = ':';
+    }
+
+    ch1 = '0' + (byte >> 4);
+    if (ch1 > '9')
+      ch1 += 'a' - '0' - 10;
+    ch2 = '0' + (byte & 0xf);
+    if (ch2 > '9')
+      ch2 += 'a' - '0' - 10;
+
+    if (bufptr < bufend)
+      *bufptr++ = ch1;
+    if (bufptr < bufend)
+      *bufptr++ = ch2;
+  }
+
+  if (bytes < 16) {
+    if (bufend - bufptr > 2) {
+      *bufptr++ = ':';
+      *bufptr++ = ':';
+    }
+  }
+
+  sprintf (pfxbuf, "/%u", prefix);
+
+  if ((size_t)(bufend - bufptr) > strlen(pfxbuf))
+    strcpy (bufptr, pfxbuf);
+
+  buffer[sizeof(buffer) - 1] = '\0';
+
+  return PyString_FromString(buffer);
+}
+
+/* We dynamically bind to WSAAddressToStringW or WSAAddressToStringA
+   depending on which is available, as the latter is deprecated and
+   the former doesn't exist on all Windows versions on which this code
+   might run. */
+typedef INT (WSAAPI *WSAAddressToStringWPtr)(LPSOCKADDR, DWORD, 
LPWSAPROTOCOL_INFOW, LPWSTR, LPDWORD);
+typedef INT (WSAAPI *WSAAddressToStringAPtr)(LPSOCKADDR, DWORD, 
LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
+
+static WSAAddressToStringWPtr
+get_address_to_string_w(void) {
+  static int ptr_is_set;
+  static WSAAddressToStringWPtr ptr;
+
+  if (!ptr_is_set) {
+    HMODULE hmod = LoadLibrary ("ws2_32.dll");
+    ptr = (WSAAddressToStringWPtr)GetProcAddress (hmod, "WSAAddressToStringW");
+    if (!ptr)
+      FreeLibrary (hmod);
+    ptr_is_set = 1;
+  }
+
+  return ptr;
+}
+
+static WSAAddressToStringAPtr
+get_address_to_string_a(void) {
+  static int ptr_is_set;
+  static WSAAddressToStringAPtr ptr;
+
+  if (!ptr_is_set) {
+    HMODULE hmod = LoadLibrary ("ws2_32.dll");
+    ptr = (WSAAddressToStringAPtr)GetProcAddress (hmod, "WSAAddressToStringA");
+    if (!ptr)
+      FreeLibrary (hmod);
+    ptr_is_set = 1;
+  }
+
+  return ptr;
+}
+
+static PyObject *
+string_from_address(SOCKADDR *addr, DWORD addrlen)
+{
+  WSAAddressToStringWPtr AddressToStringW = get_address_to_string_w();
+
+  if (AddressToStringW) {
+    wchar_t buffer[256];
+    DWORD dwLen = sizeof(buffer) / sizeof(wchar_t);
+    INT iRet;
+
+    iRet = AddressToStringW (addr, addrlen, NULL, buffer, &dwLen);
+
+    if (iRet == 0)
+      return PyUnicode_FromWideChar (buffer, dwLen - 1);
+  } else {
+    char buffer[256];
+    DWORD dwLen = sizeof(buffer);
+    WSAAddressToStringAPtr AddressToStringA = get_address_to_string_a();
+    INT iRet;
+
+    iRet = AddressToStringA (addr, addrlen, NULL, buffer, &dwLen);
+
+    if (iRet == 0)
+      return PyString_FromString (buffer);
+  }
+
+  return NULL;
+}
 #endif
 
 static int
@@ -551,7 +777,7 @@
       PyObject *hwaddr, *dict;
       char *ptr = buffer;
       unsigned n;
-      
+
       *ptr = '\0';
       for (n = 0; n < pInfo->PhysicalAddressLength; ++n) {
         sprintf (ptr, "%02x:", pInfo->PhysicalAddress[n] & 0xff);
@@ -582,188 +808,151 @@
     for (pUniAddr = pInfo->FirstUnicastAddress;
          pUniAddr;
          pUniAddr = pUniAddr->Next) {
-      DWORD dwLen = sizeof (buffer);
-      INT iRet = WSAAddressToStringA (pUniAddr->Address.lpSockaddr,
-                                      pUniAddr->Address.iSockaddrLength,
-                                      NULL,
-                                      buffer,
-                                      &dwLen);
       PyObject *addr;
       PyObject *mask = NULL;
       PyObject *bcast = NULL;
       PIP_ADAPTER_PREFIX pPrefix;
       short family = pUniAddr->Address.lpSockaddr->sa_family;
 
-      if (iRet)
-        continue;
+      addr = string_from_address (pUniAddr->Address.lpSockaddr,
+                                  pUniAddr->Address.iSockaddrLength);
 
-      addr = PyString_FromString (buffer);
+      if (!addr)
+        continue;
 
       /* Find the netmask, where possible */
       if (family == AF_INET) {
-         struct sockaddr_in *pAddr
+        struct sockaddr_in *pAddr
           = (struct sockaddr_in *)pUniAddr->Address.lpSockaddr;
+        int prefix_len = -1;
+        struct sockaddr_in maskAddr, bcastAddr;
+        unsigned toDo;
+        unsigned wholeBytes, remainingBits;
+        unsigned char *pMaskBits, *pBcastBits;
+        PIP_ADAPTER_PREFIX pBest = NULL;
 
         for (pPrefix = pInfo->FirstPrefix;
              pPrefix;
              pPrefix = pPrefix->Next) {
           struct sockaddr_in *pPrefixAddr
             = (struct sockaddr_in *)pPrefix->Address.lpSockaddr;
-          struct sockaddr_in maskAddr, bcastAddr;
-          unsigned toDo;
-          unsigned wholeBytes, remainingBits;
-          unsigned char *pMaskBits, *pBcastBits;
 
-          if (pPrefixAddr->sin_family != AF_INET)
+          if (pPrefixAddr->sin_family != AF_INET
+              || (prefix_len >= 0 && pPrefix->PrefixLength < prefix_len))
             continue;
-          
+
           if (compare_bits (&pPrefixAddr->sin_addr,
                             &pAddr->sin_addr,
-                            pPrefix->PrefixLength) != 0)
-            continue;
-
-          memcpy (&maskAddr,
-                  pPrefix->Address.lpSockaddr,
-                  sizeof (maskAddr));
-          memcpy (&bcastAddr,
-                  pPrefix->Address.lpSockaddr,
-                  sizeof (bcastAddr));
-                  
-          wholeBytes = pPrefix->PrefixLength >> 3;
-          remainingBits = pPrefix->PrefixLength & 7;
-
-          if (wholeBytes >= 4)
-            continue;
-
-          toDo = wholeBytes;
-          pMaskBits = (unsigned char *)&maskAddr.sin_addr;
-
-          while (toDo--)
-            *pMaskBits++ = 0xff;
-
-          toDo = 4 - wholeBytes;
-
-          pBcastBits = (unsigned char *)&bcastAddr.sin_addr + wholeBytes;
-
-          if (remainingBits) {
-            static const unsigned char masks[] = {
-              0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
-            };
-            *pMaskBits++ = masks[remainingBits];
-            *pBcastBits &= masks[remainingBits];
-            *pBcastBits++ |= ~masks[remainingBits];
-            --toDo;
+                            pPrefix->PrefixLength) == 0) {
+            prefix_len = pPrefix->PrefixLength;
+            pBest = pPrefix;
           }
+        }
 
-          while (toDo--) {
-            *pMaskBits++ = 0;
-            *pBcastBits++ = 0xff;
-          }
+        if (!pBest)
+          continue;
 
-          dwLen = sizeof (buffer);
-          iRet = WSAAddressToStringA ((SOCKADDR *)&maskAddr,
-                                     sizeof (maskAddr),
-                                     NULL,
-                                     buffer,
-                                     &dwLen);
-
-          if (iRet == 0)
-            mask = PyString_FromString (buffer);
-          
-          dwLen = sizeof (buffer);
-          iRet = WSAAddressToStringA ((SOCKADDR *)&bcastAddr,
-                                     sizeof (bcastAddr),
-                                     NULL,
-                                     buffer,
-                                     &dwLen);
+        if (prefix_len < 0)
+          prefix_len = 32;
 
-          if (iRet == 0)
-            bcast = PyString_FromString (buffer);
+        memcpy (&maskAddr,
+                pBest->Address.lpSockaddr,
+                sizeof (maskAddr));
+        memcpy (&bcastAddr,
+                pBest->Address.lpSockaddr,
+                sizeof (bcastAddr));
+
+        wholeBytes = prefix_len >> 3;
+        remainingBits = prefix_len & 7;
+
+        toDo = wholeBytes;
+        pMaskBits = (unsigned char *)&maskAddr.sin_addr;
+
+        while (toDo--)
+          *pMaskBits++ = 0xff;
+
+        toDo = 4 - wholeBytes;
+
+        pBcastBits = (unsigned char *)&bcastAddr.sin_addr + wholeBytes;
+
+        if (remainingBits) {
+          static const unsigned char masks[] = {
+            0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
+          };
+          *pMaskBits++ = masks[remainingBits];
+          *pBcastBits &= masks[remainingBits];
+          *pBcastBits++ |= ~masks[remainingBits];
+          --toDo;
+        }
 
-          break;
+        while (toDo--) {
+          *pMaskBits++ = 0;
+          *pBcastBits++ = 0xff;
         }
+
+        mask = string_from_address ((SOCKADDR *)&maskAddr,
+                                    sizeof (maskAddr));
+        bcast = string_from_address ((SOCKADDR *)&bcastAddr,
+                                     sizeof (bcastAddr));
       } else if (family == AF_INET6) {
         struct sockaddr_in6 *pAddr
           = (struct sockaddr_in6 *)pUniAddr->Address.lpSockaddr;
+        int prefix_len = -1;
+        struct sockaddr_in6 bcastAddr;
+        unsigned toDo;
+        unsigned wholeBytes, remainingBits;
+        unsigned char *pBcastBits;
+        PIP_ADAPTER_PREFIX pBest = NULL;
 
         for (pPrefix = pInfo->FirstPrefix;
              pPrefix;
              pPrefix = pPrefix->Next) {
           struct sockaddr_in6 *pPrefixAddr
             = (struct sockaddr_in6 *)pPrefix->Address.lpSockaddr;
-          struct sockaddr_in6 maskAddr, bcastAddr;
-          unsigned toDo;
-          unsigned wholeBytes, remainingBits;
-          unsigned char *pMaskBits, *pBcastBits;
 
-          if (pPrefixAddr->sin6_family != AF_INET6)
+          if (pPrefixAddr->sin6_family != AF_INET6
+              || (prefix_len >= 0 && pPrefix->PrefixLength < prefix_len))
             continue;
-          
+
           if (compare_bits (&pPrefixAddr->sin6_addr,
                             &pAddr->sin6_addr,
-                            pPrefix->PrefixLength) != 0)
-            continue;
-
-          memcpy (&maskAddr,
-                  pPrefix->Address.lpSockaddr,
-                  sizeof (maskAddr));
-          memcpy (&bcastAddr,
-                  pPrefix->Address.lpSockaddr,
-                  sizeof (bcastAddr));
-                  
-          wholeBytes = pPrefix->PrefixLength >> 3;
-          remainingBits = pPrefix->PrefixLength & 7;
-
-          if (wholeBytes >= 8)
-            continue;
-
-          toDo = wholeBytes;
-          pMaskBits = (unsigned char *)&maskAddr.sin6_addr;
-
-          while (toDo--)
-            *pMaskBits++ = 0xff;
-
-          toDo = 8 - wholeBytes;
-
-          pBcastBits = (unsigned char *)&bcastAddr.sin6_addr + wholeBytes;
-
-          if (remainingBits) {
-            static const unsigned char masks[] = {
-              0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
-            };
-            *pMaskBits++ = masks[remainingBits];
-            *pBcastBits &= masks[remainingBits];
-            *pBcastBits++ |= ~masks[remainingBits];
-            --toDo;
-          }
-
-          while (toDo--) {
-            *pMaskBits++ = 0;
-            *pBcastBits++ = 0xff;
+                            pPrefix->PrefixLength) == 0) {
+            prefix_len = pPrefix->PrefixLength;
+            pBest = pPrefix;
           }
+        }
 
-          dwLen = sizeof (buffer);
-          iRet = WSAAddressToStringA ((SOCKADDR *)&maskAddr,
-                                     sizeof (maskAddr),
-                                     NULL,
-                                     buffer,
-                                     &dwLen);
-
-          if (iRet == 0)
-            mask = PyString_FromString (buffer);
-          
-          dwLen = sizeof (buffer);
-          iRet = WSAAddressToStringA ((SOCKADDR *)&bcastAddr,
-                                     sizeof (bcastAddr),
-                                     NULL,
-                                     buffer,
-                                     &dwLen);
+        if (!pBest)
+          continue;
 
-          if (iRet == 0)
-            bcast = PyString_FromString (buffer);
+        if (prefix_len < 0)
+          prefix_len = 128;
 
-          break;
+        memcpy (&bcastAddr,
+                pBest->Address.lpSockaddr,
+                sizeof (bcastAddr));
+
+        wholeBytes = prefix_len >> 3;
+        remainingBits = prefix_len & 7;
+
+        toDo = 16 - wholeBytes;
+
+        pBcastBits = (unsigned char *)&bcastAddr.sin6_addr + wholeBytes;
+
+        if (remainingBits) {
+          static const unsigned char masks[] = {
+            0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
+          };
+          *pBcastBits &= masks[remainingBits];
+          *pBcastBits++ |= ~masks[remainingBits];
+          --toDo;
         }
+
+        while (toDo--)
+          *pBcastBits++ = 0xff;
+
+        mask = netmask_from_prefix (prefix_len);
+        bcast = string_from_address ((SOCKADDR *)&bcastAddr, 
sizeof(bcastAddr));
       }
 
       {
@@ -812,7 +1001,7 @@
 
   for (addr = addrs; addr; addr = addr->ifa_next) {
     char buffer[256];
-    PyObject *pyaddr = NULL, *netmask = NULL, *braddr = NULL;
+    PyObject *pyaddr = NULL, *netmask = NULL, *braddr = NULL, *flags = NULL;
 
     if (strcmp (addr->ifa_name, ifname) != 0)
       continue;
@@ -826,17 +1015,55 @@
        record with no actual address).  We skip these as they aren't useful.
        Thanks to Christian Kauhaus for reporting this issue. */
     if (!addr->ifa_addr)
-      continue;  
+      continue;
+      
+#if HAVE_IPV6_SOCKET_IOCTLS
+    /* For IPv6 addresses we try to get the flags. */
+    if (addr->ifa_addr->sa_family == AF_INET6) {
+      struct sockaddr_in6 *sin;
+      struct in6_ifreq ifr6;
+      
+      int sock6 = socket (AF_INET6, SOCK_DGRAM, 0);
+
+      if (sock6 < 0) {
+        Py_DECREF (result);
+        PyErr_SetFromErrno (PyExc_OSError);
+        freeifaddrs (addrs);
+        return NULL;
+      }
+      
+      sin = (struct sockaddr_in6 *)addr->ifa_addr;
+      strncpy (ifr6.ifr_name, addr->ifa_name, IFNAMSIZ);
+      ifr6.ifr_addr = *sin;
+      
+      if (ioctl (sock6, SIOCGIFAFLAG_IN6, &ifr6) >= 0) {
+        flags = PyLong_FromUnsignedLong (ifr6.ifr_ifru.ifru_flags6);
+      }
+
+      close (sock6);
+    }
+#endif /* HAVE_IPV6_SOCKET_IOCTLS */
 
     if (string_from_sockaddr (addr->ifa_addr, buffer, sizeof (buffer)) == 0)
       pyaddr = PyString_FromString (buffer);
 
-    if (string_from_sockaddr (addr->ifa_netmask, buffer, sizeof (buffer)) == 0)
+    if (string_from_netmask (addr->ifa_netmask, buffer, sizeof (buffer)) == 0)
       netmask = PyString_FromString (buffer);
 
     if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 
0)
       braddr = PyString_FromString (buffer);
 
+    /* Cygwin's implementation of getaddrinfo() is buggy and returns broadcast
+       addresses for 169.254.0.0/16.  Nix them here. */
+    if (addr->ifa_addr->sa_family == AF_INET) {
+      struct sockaddr_in *sin = (struct sockaddr_in *)addr->ifa_addr;
+
+      if ((ntohl(sin->sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000) {
+        Py_XDECREF (braddr);
+        braddr = NULL;
+      }
+    }
+
     {
       PyObject *dict = PyDict_New();
 
@@ -844,6 +1071,7 @@
         Py_XDECREF (pyaddr);
         Py_XDECREF (netmask);
         Py_XDECREF (braddr);
+        Py_XDECREF (flags);
         Py_DECREF (result);
         freeifaddrs (addrs);
         return NULL;
@@ -860,10 +1088,14 @@
         else
           PyDict_SetItemString (dict, "broadcast", braddr);
       }
+      
+      if (flags)
+        PyDict_SetItemString (dict, "flags", flags);
 
       Py_XDECREF (pyaddr);
       Py_XDECREF (netmask);
       Py_XDECREF (braddr);
+      Py_XDECREF (flags);
 
       if (!add_to_family (result, addr->ifa_addr->sa_family, dict)) {
         Py_DECREF (result);
@@ -1246,7 +1478,7 @@
 
     if (dwErr == NO_ERROR) {
       DWORD n;
-      BOOL bFirstInet = TRUE, bFirstInet6 = TRUE;
+      ULONG lBestInetMetric = ~(ULONG)0, lBestInet6Metric = ~(ULONG)0;
 
       result = PyDict_New();
       defaults = PyDict_New();
@@ -1262,12 +1494,9 @@
        PyObject *gateway;
        PyObject *isdefault;
        PyObject *tuple, *deftuple = NULL;
-       char gwbuf[256];
        WCHAR *pwcsName;
        DWORD dwFamily = table->Table[n].NextHop.si_family;
-       BOOL bFirst;
-       DWORD dwLen;
-       INT iRet;
+       BOOL bBest = FALSE;
 
        if (table->Table[n].DestinationPrefix.PrefixLength)
          continue;
@@ -1292,15 +1521,11 @@
        if (GetIfEntry (&ifRow) != NO_ERROR)
          continue;
 
-       dwLen = sizeof (gwbuf);
-       iRet = WSAAddressToStringA ((SOCKADDR *)&table->Table[n].NextHop,
-                                   sizeof (table->Table[n].NextHop),
-                                   NULL,
-                                   gwbuf,
-                                   &dwLen);
+        gateway = string_from_address ((SOCKADDR *)&table->Table[n].NextHop,
+                                       sizeof (table->Table[n].NextHop));
 
-       if (iRet != NO_ERROR)
-         continue;
+        if (!gateway)
+          continue;
 
        /* Strip the prefix from the interface name */
        pwcsName = ifRow.wszName;
@@ -1309,18 +1534,17 @@
 
        switch (dwFamily) {
        case AF_INET:
-         bFirst = bFirstInet;
-         bFirstInet = FALSE;
+          bBest = table->Table[n].Metric < lBestInetMetric;
+          lBestInetMetric = table->Table[n].Metric;
          break;
        case AF_INET6:
-         bFirst = bFirstInet6;
-         bFirstInet6 = FALSE;
+          bBest = table->Table[n].Metric < lBestInet6Metric;
+          lBestInet6Metric = table->Table[n].Metric;
          break;
        }
 
        ifname = PyUnicode_FromUnicode (pwcsName, wcslen (pwcsName));
-       gateway = PyString_FromString (gwbuf);
-       isdefault = bFirst ? Py_True : Py_False;
+       isdefault = bBest ? Py_True : Py_False;
 
        tuple = PyTuple_Pack (3, gateway, ifname, isdefault);
 
@@ -1356,7 +1580,7 @@
     DWORD dwRet;
     DWORD dwSize = 0;
     DWORD n;
-    BOOL bFirst = TRUE;
+    DWORD dwBestMetric = ~(DWORD)0;
 
     do {
       dwRet = GetIpForwardTable (table, &dwSize, FALSE);
@@ -1397,6 +1621,7 @@
       DWORD dwGateway;
       char gwbuf[16];
       WCHAR *pwcsName;
+      BOOL bBest;
 
       if (table->table[n].dwForwardDest
           || !table->table[n].dwForwardNextHop
@@ -1421,10 +1646,13 @@
       if (_wcsnicmp (L"\\DEVICE\\TCPIP_", pwcsName, 14) == 0)
        pwcsName += 14;
 
+      bBest = table->table[n].dwForwardMetric1 < dwBestMetric;
+      if (bBest)
+        dwBestMetric = table->table[n].dwForwardMetric1;
+
       ifname = PyUnicode_FromUnicode (pwcsName, wcslen (pwcsName));
       gateway = PyString_FromString (gwbuf);
-      isdefault = bFirst ? Py_True : Py_False;
-      bFirst = FALSE;
+      isdefault = bBest ? Py_True : Py_False;
 
       tuple = PyTuple_Pack (3, gateway, ifname, isdefault);
 
@@ -1473,6 +1701,9 @@
   int bufsize = pagesize < 8192 ? pagesize : 8192;
   int is_multi = 0;
   int interrupted = 0;
+  int def_priorities[RTNL_FAMILY_MAX];
+
+  memset(def_priorities, 0xff, sizeof(def_priorities));
 
   result = PyDict_New();
   defaults = PyDict_New();
@@ -1582,6 +1813,7 @@
         int ifndx = -1;
         struct rtattr *attrs, *attr;
         int len;
+        int priority;
 
         /* Ignore messages not for us */
         if (pmsg->hdr.nlmsg_seq != seq || pmsg->hdr.nlmsg_pid != sanl.nl_pid)
@@ -1616,7 +1848,7 @@
 
         attr = attrs = RTM_RTA(&pmsg->rt);
         len = RTM_PAYLOAD(&pmsg->hdr);
-
+        priority = -1;
         while (RTA_OK(attr, len)) {
           switch (attr->rta_type) {
           case RTA_GATEWAY:
@@ -1628,6 +1860,9 @@
           case RTA_OIF:
             ifndx = *(int *)RTA_DATA(attr);
             break;
+          case RTA_PRIORITY:
+            priority = *(int *)RTA_DATA(attr);
+            break;
           default:
             break;
           }
@@ -1661,6 +1896,19 @@
              routing tables on Linux. */
 
           isdefault = pmsg->rt.rtm_table == RT_TABLE_MAIN ? Py_True : Py_False;
+
+          /* Try to pick the active default route based on priority (which
+             is displayed in the UI as "metric", confusingly) */
+          if (pmsg->rt.rtm_family < RTNL_FAMILY_MAX) {
+            if (def_priorities[pmsg->rt.rtm_family] == -1)
+              def_priorities[pmsg->rt.rtm_family] = priority;
+            else {
+              if (priority == -1
+                  || priority > def_priorities[pmsg->rt.rtm_family])
+                isdefault = Py_False;
+            }
+          }
+
           pyifname = PyString_FromString (ifname);
           pyaddr = PyString_FromString (buffer);
 
@@ -1673,7 +1921,7 @@
           Py_DECREF (pyifname);
 
           if (tuple && !add_to_family (result, pmsg->rt.rtm_family, tuple)) {
-            Py_DECREF (deftuple);
+            Py_XDECREF (deftuple);
             Py_DECREF (result);
             free (msgbuf);
             close (s);
@@ -1813,7 +2061,8 @@
 #ifdef RTF_IFSCOPE
           PyObject *isdefault = PyBool_FromLong (!(msg->rtm_flags & 
RTF_IFSCOPE));
 #else
-          PyObject *isdefault = Py_INCREF(Py_True);
+          Py_INCREF(Py_True);
+          PyObject *isdefault = Py_True;
 #endif
           tuple = PyTuple_Pack (3, pyaddr, pyifname, isdefault);
 
@@ -2604,6 +2853,21 @@
   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BLUETOOTH),
           PyString_FromString("AF_BLUETOOTH"));
 #endif
+#ifdef IN6_IFF_AUTOCONF
+  PyModule_AddIntConstant (m, "IN6_IFF_AUTOCONF", IN6_IFF_AUTOCONF);
+#endif
+#ifdef IN6_IFF_TEMPORARY
+  PyModule_AddIntConstant (m, "IN6_IFF_TEMPORARY", IN6_IFF_TEMPORARY);
+#endif
+#ifdef IN6_IFF_DYNAMIC
+  PyModule_AddIntConstant (m, "IN6_IFF_DYNAMIC", IN6_IFF_DYNAMIC);
+#endif
+#ifdef IN6_IFF_OPTIMISTIC
+  PyModule_AddIntConstant (m, "IN6_IFF_OPTIMISTIC", IN6_IFF_OPTIMISTIC);
+#endif
+#ifdef IN6_IFF_SECURED
+  PyModule_AddIntConstant (m, "IN6_IFF_SECURED", IN6_IFF_SECURED);
+#endif
   PyModule_AddObject(m, "address_families", address_family_dict);
 
   // Add-in the version number from setup.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/netifaces-0.10.4/netifaces.egg-info/PKG-INFO 
new/netifaces-0.10.5/netifaces.egg-info/PKG-INFO
--- old/netifaces-0.10.4/netifaces.egg-info/PKG-INFO    2014-05-19 
13:40:12.000000000 +0200
+++ new/netifaces-0.10.5/netifaces.egg-info/PKG-INFO    2016-08-23 
17:28:47.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: netifaces
-Version: 0.10.4
+Version: 0.10.5
 Summary: Portable network interface information.
 Home-page: https://bitbucket.org/al45tair/netifaces
 Author: Alastair Houghton
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/netifaces-0.10.4/setup.py 
new/netifaces-0.10.5/setup.py
--- old/netifaces-0.10.4/setup.py       2014-05-19 13:39:39.000000000 +0200
+++ new/netifaces-0.10.5/setup.py       2016-08-23 10:36:16.000000000 +0200
@@ -14,9 +14,15 @@
         f.write(' '.join(str(a) for a in args))
         f.write(end)
 else:
-    output = getattr(__builtins__, 'print')
+    try:
+        import builtins
+    except ImportError:
+        import __builtin__
+        builtins = __builtin__
+        
+    output = getattr(builtins, 'print', lambda x: True)
     
-__version__ = "0.10.4"
+__version__ = "0.10.5"
 
 # Disable hard links, otherwise building distributions fails on OS X
 try:
@@ -203,6 +209,63 @@
 
         results['have_getnameinfo'] = result
 
+        if results['have_getifaddrs']:
+            output("checking for IPv6 socket IOCTLs...", end='')
+
+            result = results.get('have_ipv6_socket_ioctls', None)
+            if result is not None:
+                cached = '(cached)'
+            else:
+                cached = ''
+
+                if not os.path.exists(self.build_temp):
+                    os.makedirs(self.build_temp)
+                outname = os.path.join(self.build_temp, 'conftest4.out')
+                self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | 
os.O_TRUNC)
+
+                result = []
+                ioctls = ('SIOCGIFAFLAG_IN6',)
+                added_includes = ""
+                if mos.startswith('sunos'):
+                    added_includes = """
+                     #include <unistd.h>
+                     #include <stropts.h>
+                     #include <sys/sockio.h>
+                    """
+
+                for ioctl in ioctls:
+                    testrig = """
+                    #include <sys/types.h>
+                    #include <sys/socket.h>
+                    #include <sys/ioctl.h>
+                    #include <net/if.h>
+                    #include <netinet/in.h>
+                    #include <netinet/in_var.h>
+                    #include <arpa/inet.h>
+                    %(addedinc)s
+                    int main(void) {
+                        int fd = socket (AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
+                        struct in6_ifreq ifreq;
+
+                        ioctl(fd, %(ioctl)s, &ifreq);
+
+                        return 0;
+                    }
+                    """ % { 'ioctl': ioctl , 'addedinc': added_includes}
+
+                    if self.test_build(testrig,libraries=libraries):
+                        result.append(ioctl)
+
+            if result:
+                output("%r. %s" % (result, cached))
+                for ioctl in result:
+                    self.compiler.define_macro('HAVE_%s' % ioctl, 1)
+                self.compiler.define_macro('HAVE_IPV6_SOCKET_IOCTLS', 1)
+            else:
+                output("not found. %s" % cached)
+
+            results['have_ipv6_socket_ioctls'] = result
+
         if not results['have_getifaddrs']:
             output("checking for socket IOCTLs...", end='')
 
@@ -355,7 +418,7 @@
 
                 if not os.path.exists(self.build_temp):
                     os.makedirs(self.build_temp)
-                outname = os.path.join(self.build_temp, 'conftest4.out')
+                outname = os.path.join(self.build_temp, 'conftest5.out')
                 self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | 
os.O_TRUNC)
 
                 sockaddrs = ('at', 'ax25', 'dl', 'eon', 'in', 'in6',


Reply via email to