Initial import to Tizen 06/1606/1 1.0 1.0_branch accepted/trunk/20120904.165950 submit/trunk/20120831.221344
authorJimmy Huang <jimmy.huang@linux.intel.com>
Fri, 31 Aug 2012 22:13:35 +0000 (15:13 -0700)
committerJimmy Huang <jimmy.huang@linux.intel.com>
Fri, 31 Aug 2012 22:13:35 +0000 (15:13 -0700)
Signed-off-by: Jimmy Huang <jimmy.huang@linux.intel.com>
PKG-INFO [new file with mode: 0644]
README [new file with mode: 0644]
netifaces.c [new file with mode: 0644]
netifaces.egg-info/PKG-INFO [new file with mode: 0755]
netifaces.egg-info/SOURCES.txt [new file with mode: 0755]
netifaces.egg-info/dependency_links.txt [new file with mode: 0755]
netifaces.egg-info/top_level.txt [new file with mode: 0755]
packaging/python-netifaces.changes [new file with mode: 0644]
packaging/python-netifaces.spec [new file with mode: 0644]
setup.cfg [new file with mode: 0644]
setup.py [new file with mode: 0644]

diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644 (file)
index 0000000..9dcb201
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,25 @@
+Metadata-Version: 1.0
+Name: netifaces
+Version: 0.6
+Summary: Portable network interface information.
+Home-page: http://alastairs-place.net/netifaces
+Author: Alastair Houghton
+Author-email: alastair@alastairs-place.net
+License: MIT License
+Description: netifaces provides a (hopefully portable-ish) way for Python programmers to
+        get access to a list of the network interfaces on the local machine, and to
+        obtain the addresses of those network interfaces.
+        
+        The package has been tested on Mac OS X, Windows XP, Windows Vista, Linux
+        and Solaris.  On Windows, it is currently not able to retrieve IPv6
+        addresses, owing to shortcomings of the Windows API.
+        
+        It should work on other UNIX-like systems provided they implement
+        either getifaddrs() or support the SIOCGIFxxx socket options, although the
+        data provided by the socket options is normally less complete.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: System :: Networking
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..c820760
--- /dev/null
+++ b/README
@@ -0,0 +1,156 @@
+netifaces 0.4
+=============
+
+1. What is this?
+----------------
+
+It's been annoying me for some time that there's no easy way to get the
+address(es) of the machine's network interfaces from Python.  There is
+a good reason for this difficulty, which is that it is virtually impossible
+to do so in a portable manner.  However, it seems to me that there should
+be a package you can easy_install that will take care of working out the
+details of doing so on the machine you're using, then you can get on with
+writing Python code without concerning yourself with the nitty gritty of
+system-dependent low-level networking APIs.
+
+This package attempts to solve that problem.
+
+2. How do I use it?
+-------------------
+
+First you need to install it, which you can do by typing
+
+  tar xvzf netifaces-0.4.tar.gz
+  cd netifaces-0.4
+  python setup.py install
+
+Once that's done, you'll need to start Python and do something like the
+following:
+
+  >>> import netifaces
+
+Then if you enter
+
+  >>> netifaces.interfaces()
+  ['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']
+
+you'll see the list of interface identifiers for your machine.
+
+You can ask for the addresses of a particular interface by doing
+
+  >>> netifaces.ifaddresses('lo0')
+  {18: [{'addr': ''}], 2: [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}], 30: [{'peer': '::1', 'netmask': 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'addr': '::1'}, {'peer': '', 'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::1%lo0'}]}
+
+Hmmmm.  That result looks a bit cryptic; let's break it apart and explain
+what each piece means.  It returned a dictionary, so let's look there first:
+
+  { 18: [...], 2: [...], 30: [...] }
+
+Each of the numbers refers to a particular address family.  In this case, we
+have three address families listed; on my system, 18 is AF_LINK (which means
+the link layer interface, e.g. Ethernet), 2 is AF_INET (normal Internet
+addresses), and 30 is AF_INET6 (IPv6).
+
+But wait!  Don't use these numbers in your code.  The numeric values here are
+system dependent; fortunately, I thought of that when writing netifaces, so
+the module declares a range of values that you might need.  e.g.
+
+  >>> netifaces.AF_LINK
+  18
+
+Again, on your system, the number may be different.
+
+So, what we've established is that the dictionary that's returned has one
+entry for each address family for which this interface has an address.  Let's
+take a look at the AF_INET addresses now:
+
+  >>> addrs = netifaces.ifaddresses('lo0')
+  >>> addrs[netifaces.AF_INET]
+  [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
+
+You might be wondering why this value is a list.  The reason is that it's
+possible for an interface to have more than one address, even within the
+same family.  I'll say that again: *you can have more than one address of
+the same type associated with each interface*.
+
+*Asking for "the" address of a particular interface doesn't make sense.*
+
+Right, so, we can see that this particular interface only has one address,
+and, because it's a loopback interface, it's point-to-point and therefore
+has a *peer* address rather than a broadcast address.
+
+Let's look at a more interesting interface.
+
+  >>> addrs = netifaces.ifaddresses('en0')
+  >>> addrs[netifaces.AF_INET]
+  [{'broadcast': '10.15.255.255', 'netmask': '255.240.0.0', 'addr': '10.0.1.4'}, {'broadcast': '192.168.0.255', 'addr': '192.168.0.47'}]
+
+This interface has two addresses (see, I told you...)  Both of them are
+regular IPv4 addresses, although in one case the netmask has been changed
+from its default.  The netmask *may not* appear on your system if it's set
+to the default for the address range.
+
+Because this interface isn't point-to-point, it also has broadcast addresses.
+
+Now, say we want, instead of the IP addresses, to get the MAC address; that
+is, the hardware address of the Ethernet adapter running this interface.  We
+can do
+
+  >>> addrs[netifaces.AF_LINK]
+  [{'addr': '00:12:34:56:78:9a'}]
+
+Note that this may not be available on platforms without getifaddrs(), unless
+they happen to implement SIOCGIFHWADDR.  Note also that you just get the
+address; it's unlikely that you'll see anything else with an AF_LINK address.
+Oh, and don't assume that all AF_LINK addresses are Ethernet; you might, for
+instance, be on a Mac, in which case:
+
+  >>> addrs = netifaces.ifaddresses('fw0')
+  >>> addrs[netifaces.AF_LINK]
+  [{'addr': '00:12:34:56:78:9a:bc:de'}]
+
+No, that isn't an exceptionally long Ethernet MAC address---it's a FireWire
+address.
+
+3. This is great!  What platforms does it work on?
+--------------------------------------------------
+
+Well, see, here's the thing.  It's been tested on Mac OS X, and it seems to
+work.  (OS X helpfully has some of the SIOCGIFxxx ioctl()s, which means that
+most of those have been tested too, the only glaring exception being the
+SIOCGIFHWADDR ioctl(), which OS X just doesn't have.)
+
+It should probably work on most of the other UNIX-like systems with relatively
+minor changes.  If you do have to change something, send it to me at
+<alastair AT alastairs-place.net> and I'll see if I can merge it in.
+
+It also works just fine on Windows, using the GetAdaptersInfo() function.
+Note, though, that on Windows it isn't possible (yet) to retrieve IPv6
+addresses.  I don't use Windows at the moment, so this isn't a priority for
+me.  If you know how to fix it, drop me a line and I'll consider adding any
+necessary code.
+
+4. What license is this under?
+------------------------------
+
+It's an MIT-style license.  Here goes:
+
+Copyright (c) 2007, 2008 Alastair Houghton
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/netifaces.c b/netifaces.c
new file mode 100644 (file)
index 0000000..bc4298b
--- /dev/null
@@ -0,0 +1,1262 @@
+#include <Python.h>
+
+#ifndef WIN32
+
+#  include <sys/types.h>
+#  include <sys/socket.h>
+#  include <net/if.h>
+#  include <netdb.h>
+
+#  if HAVE_SOCKET_IOCTLS
+#    include <sys/ioctl.h>
+#    include <netinet/in.h>
+#    include <arpa/inet.h>
+#if defined(__sun)
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/sockio.h>
+#endif
+#  endif /* HAVE_SOCKET_IOCTLS */
+
+/* For logical interfaces support we convert all names to same name prefixed with l */
+#if HAVE_SIOCGLIFNUM
+#define CNAME(x) l##x
+#else
+#define CNAME(x) x
+#endif
+
+#if HAVE_NET_IF_DL_H
+#  include <net/if_dl.h>
+#endif
+
+/* For the benefit of stupid platforms (Linux), include all the sockaddr
+   definitions we can lay our hands on. It can also be useful for the benefit
+   of another stupid platform (FreeBSD, see PR 152036). */
+#include <netinet/in.h>
+#  if HAVE_NETASH_ASH_H
+#    include <netash/ash.h>
+#  endif
+#  if HAVE_NETATALK_AT_H
+#    include <netatalk/at.h>
+#  endif
+#  if HAVE_NETAX25_AX25_H
+#    include <netax25/ax25.h>
+#  endif
+#  if HAVE_NETECONET_EC_H
+#    include <neteconet/ec.h>
+#  endif
+#  if HAVE_NETIPX_IPX_H
+#    include <netipx/ipx.h>
+#  endif
+#  if HAVE_NETPACKET_PACKET_H
+#    include <netpacket/packet.h>
+#  endif
+#  if HAVE_NETROSE_ROSE_H
+#    include <netrose/rose.h>
+#  endif
+#  if HAVE_LINUX_IRDA_H
+#    include <linux/irda.h>
+#  endif
+#  if HAVE_LINUX_ATM_H
+#    include <linux/atm.h>
+#  endif
+#  if HAVE_LINUX_LLC_H
+#    include <linux/llc.h>
+#  endif
+#  if HAVE_LINUX_TIPC_H
+#    include <linux/tipc.h>
+#  endif
+#  if HAVE_LINUX_DN_H
+#    include <linux/dn.h>
+#  endif
+
+/* Map address families to sizes of sockaddr structs */
+static int af_to_len(int af) 
+{
+  switch (af) {
+  case AF_INET: return sizeof (struct sockaddr_in);
+#if defined(AF_INET6) && HAVE_SOCKADDR_IN6
+  case AF_INET6: return sizeof (struct sockaddr_in6);
+#endif
+#if defined(AF_AX25) && HAVE_SOCKADDR_AX25
+#  if defined(AF_NETROM)
+  case AF_NETROM: /* I'm assuming this is carried over x25 */
+#  endif
+  case AF_AX25: return sizeof (struct sockaddr_ax25);
+#endif
+#if defined(AF_IPX) && HAVE_SOCKADDR_IPX
+  case AF_IPX: return sizeof (struct sockaddr_ipx);
+#endif
+#if defined(AF_APPLETALK) && HAVE_SOCKADDR_AT
+  case AF_APPLETALK: return sizeof (struct sockaddr_at);
+#endif
+#if defined(AF_ATMPVC) && HAVE_SOCKADDR_ATMPVC
+  case AF_ATMPVC: return sizeof (struct sockaddr_atmpvc);
+#endif
+#if defined(AF_ATMSVC) && HAVE_SOCKADDR_ATMSVC
+  case AF_ATMSVC: return sizeof (struct sockaddr_atmsvc);
+#endif
+#if defined(AF_X25) && HAVE_SOCKADDR_X25
+  case AF_X25: return sizeof (struct sockaddr_x25);
+#endif
+#if defined(AF_ROSE) && HAVE_SOCKADDR_ROSE
+  case AF_ROSE: return sizeof (struct sockaddr_rose);
+#endif
+#if defined(AF_DECnet) && HAVE_SOCKADDR_DN
+  case AF_DECnet: return sizeof (struct sockaddr_dn);
+#endif
+#if defined(AF_PACKET) && HAVE_SOCKADDR_LL
+  case AF_PACKET: return sizeof (struct sockaddr_ll);
+#endif
+#if defined(AF_ASH) && HAVE_SOCKADDR_ASH
+  case AF_ASH: return sizeof (struct sockaddr_ash);
+#endif
+#if defined(AF_ECONET) && HAVE_SOCKADDR_EC
+  case AF_ECONET: return sizeof (struct sockaddr_ec);
+#endif
+#if defined(AF_IRDA) && HAVE_SOCKADDR_IRDA
+  case AF_IRDA: return sizeof (struct sockaddr_irda);
+#endif
+  }
+  return sizeof (struct sockaddr);
+}
+
+#if !HAVE_SOCKADDR_SA_LEN
+#define SA_LEN(sa)      af_to_len(sa->sa_family)
+#if HAVE_SIOCGLIFNUM
+#define SS_LEN(sa)      af_to_len(sa->ss_family)
+#else
+#define SS_LEN(sa)      SA_LEN(sa)
+#endif
+#else
+#define SA_LEN(sa)      sa->sa_len
+#endif /* !HAVE_SOCKADDR_SA_LEN */
+
+#  if HAVE_GETIFADDRS
+#    include <ifaddrs.h>
+#  endif /* HAVE_GETIFADDRS */
+
+#  if !HAVE_GETIFADDRS && (!HAVE_SOCKET_IOCTLS || !HAVE_SIOCGIFCONF)
+/* If the platform doesn't define, what we need, barf.  If you're seeing this,
+   it means you need to write suitable code to retrieve interface information
+   on your system. */
+#    error You need to add code for your platform.
+#  endif
+
+#else /* defined(WIN32) */
+
+#  include <winsock2.h>
+#  include <iphlpapi.h>
+
+#endif /* defined(WIN32) */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* On systems without AF_LINK (Windows, for instance), define it anyway, but
+   give it a crazy value.  On Linux, which has AF_PACKET but not AF_LINK,
+   define AF_LINK as the latter instead. */
+#ifndef AF_LINK
+#  ifdef AF_PACKET
+#    define AF_LINK  AF_PACKET
+#  else
+#    define AF_LINK  -1000
+#  endif
+#  define HAVE_AF_LINK 0
+#else
+#  define HAVE_AF_LINK 1
+#endif
+
+#if !defined(WIN32)
+#if  !HAVE_GETNAMEINFO
+#undef getnameinfo
+#undef NI_NUMERICHOST
+
+#define getnameinfo our_getnameinfo
+#define NI_NUMERICHOST 1
+
+/* A very simple getnameinfo() for platforms without */
+static int
+getnameinfo (const struct sockaddr *addr, int addr_len,
+             char *buffer, int buflen,
+             char *buf2, int buf2len,
+             int flags)
+{
+  switch (addr->sa_family) {
+  case AF_INET:
+    {
+      const struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+      const unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr;
+      char tmpbuf[20];
+
+      sprintf (tmpbuf, "%d.%d.%d.%d",
+               bytes[0], bytes[1], bytes[2], bytes[3]);
+
+      strncpy (buffer, tmpbuf, buflen);
+    }
+    break;
+#ifdef AF_INET6
+  case AF_INET6:
+    {
+      const struct sockaddr_in6 *sin = (const struct sockaddr_in6 *)addr;
+      const unsigned char *bytes = sin->sin6_addr.s6_addr;
+      int n;
+      char tmpbuf[80], *ptr = tmpbuf;
+      int done_double_colon = FALSE;
+      int colon_mode = FALSE;
+
+      for (n = 0; n < 8; ++n) {
+        unsigned char b1 = bytes[2 * n];
+        unsigned char b2 = bytes[2 * n + 1];
+
+        if (b1) {
+          if (colon_mode) {
+            colon_mode = FALSE;
+            *ptr++ = ':';
+          }
+          sprintf (ptr, "%x%02x", b1, b2);
+          ptr += strlen (ptr);
+          *ptr++ = ':';
+        } else if (b2) {
+          if (colon_mode) {
+            colon_mode = FALSE;
+            *ptr++ = ':';
+          }
+          sprintf (ptr, "%x", b2);
+          ptr += strlen (ptr);
+          *ptr++ = ':';
+        } else {
+          if (!colon_mode) {
+            if (done_double_colon) {
+              *ptr++ = '0';
+              *ptr++ = ':';
+            } else {
+              if (n == 0)
+                *ptr++ = ':';
+              colon_mode = TRUE;
+              done_double_colon = TRUE;
+            }
+          }
+        }
+      }
+      if (colon_mode) {
+        colon_mode = FALSE;
+        *ptr++ = ':';
+        *ptr++ = '\0';
+      } else {
+        *--ptr = '\0';
+      }
+
+      strncpy (buffer, tmpbuf, buflen);
+    }
+    break;
+#endif /* AF_INET6 */
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+#endif
+
+static int
+string_from_sockaddr (struct sockaddr *addr,
+                      char *buffer,
+                      int buflen)
+{
+  struct sockaddr* bigaddr = 0;
+  int failure;
+  struct sockaddr* gniaddr;
+  socklen_t gnilen;
+
+  if (!addr || addr->sa_family == AF_UNSPEC)
+    return -1;
+
+  if (SA_LEN(addr) < af_to_len(addr->sa_family)) {
+    /* Someteims ifa_netmask can be truncated. So let's detruncate it.  FreeBSD
+     * PR: kern/152036: getifaddrs(3) returns truncated sockaddrs for netmasks
+     * -- http://www.freebsd.org/cgi/query-pr.cgi?pr=152036 */
+    gnilen = af_to_len(addr->sa_family);
+    bigaddr = calloc(1, gnilen);
+    if (!bigaddr)
+      return -1;
+    memcpy(bigaddr, addr, SA_LEN(addr));
+#if HAVE_SOCKADDR_SA_LEN
+    bigaddr->sa_len = gnilen;
+#endif
+    gniaddr = bigaddr;
+  } else {
+    gnilen = SA_LEN(addr);
+    gniaddr = addr;
+  }
+
+  failure = getnameinfo (gniaddr, gnilen,
+                   buffer, buflen,
+                   NULL, 0,
+                   NI_NUMERICHOST);
+
+  if (bigaddr) {
+    free(bigaddr);
+    bigaddr = 0;
+  }
+
+  if (failure) {
+    int n, len;
+    char *ptr;
+    const char *data;
+      
+    len = SA_LEN(addr);
+
+#if HAVE_AF_LINK
+    /* BSD-like systems have AF_LINK */
+    if (addr->sa_family == AF_LINK) {
+      struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
+      len = dladdr->sdl_alen;
+      data = LLADDR(dladdr);
+    } else {
+#endif
+#if defined(AF_PACKET)
+      /* Linux has AF_PACKET instead */
+      if (addr->sa_family == AF_PACKET) {
+        struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
+        len = lladdr->sll_halen;
+        data = (const char *)lladdr->sll_addr;
+      } else {
+#endif
+        /* We don't know anything about this sockaddr, so just display
+           the entire data area in binary. */
+        len -= (sizeof (struct sockaddr) - sizeof (addr->sa_data));
+        data = addr->sa_data;
+#if defined(AF_PACKET)
+      }
+#endif
+#if HAVE_AF_LINK
+    }
+#endif
+
+    if (buflen < 3 * len)
+      return -1;
+
+    ptr = buffer;
+    buffer[0] = '\0';
+
+    for (n = 0; n < len; ++n) {
+      sprintf (ptr, "%02x:", data[n] & 0xff);
+      ptr += 3;
+    }
+    *--ptr = '\0';
+  }
+
+  return 0;
+}
+#endif /* !defined(WIN32) */
+
+static int
+add_to_family (PyObject *result, int family, PyObject *dict)
+{
+  PyObject *py_family = PyInt_FromLong (family);
+  PyObject *list = PyDict_GetItem (result, py_family);
+
+  if (!py_family) {
+    Py_DECREF (dict);
+    Py_XDECREF (list);
+    return FALSE;
+  }
+
+  if (!list) {
+    list = PyList_New (1);
+    if (!list) {
+      Py_DECREF (dict);
+      Py_DECREF (py_family);
+      return FALSE;
+    }
+
+    PyList_SET_ITEM (list, 0, dict);
+    PyDict_SetItem (result, py_family, list);
+    Py_DECREF (list);
+  } else {
+    PyList_Append (list, dict);
+    Py_DECREF (dict);
+  }
+
+  return TRUE;
+}
+
+static PyObject *
+ifaddrs (PyObject *self, PyObject *args)
+{
+  const char *ifname;
+  PyObject *result;
+  int found = FALSE;
+#if defined(WIN32)
+  PIP_ADAPTER_INFO pAdapterInfo = NULL;
+  PIP_ADAPTER_INFO pInfo = NULL;
+  ULONG ulBufferLength = 0;
+  DWORD dwRet;
+  PIP_ADDR_STRING str;
+#endif
+
+  if (!PyArg_ParseTuple (args, "s", &ifname))
+    return NULL;
+
+  result = PyDict_New ();
+
+  if (!result)
+    return NULL;
+
+#if defined(WIN32)
+  /* First, retrieve the adapter information.  We do this in a loop, in
+     case someone adds or removes adapters in the meantime. */
+  do {
+    dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
+
+    if (dwRet == ERROR_BUFFER_OVERFLOW) {
+      if (pAdapterInfo)
+        free (pAdapterInfo);
+      pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
+
+      if (!pAdapterInfo) {
+        Py_DECREF (result);
+        PyErr_SetString (PyExc_MemoryError, "Not enough memory");
+        return NULL;
+      }
+    }
+  } while (dwRet == ERROR_BUFFER_OVERFLOW);
+
+  /* If we failed, then fail in Python too */
+  if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
+    Py_DECREF (result);
+    if (pAdapterInfo)
+      free (pAdapterInfo);
+
+    PyErr_SetString (PyExc_OSError,
+                     "Unable to obtain adapter information.");
+    return NULL;
+  }
+
+  for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) {
+    char buffer[256];
+
+    if (strcmp (pInfo->AdapterName, ifname) != 0)
+      continue;
+
+    found = TRUE;
+
+    /* Do the physical address */
+    if (256 >= 3 * pInfo->AddressLength) {
+      PyObject *hwaddr, *dict;
+      char *ptr = buffer;
+      unsigned n;
+      
+      *ptr = '\0';
+      for (n = 0; n < pInfo->AddressLength; ++n) {
+        sprintf (ptr, "%02x:", pInfo->Address[n] & 0xff);
+        ptr += 3;
+      }
+      *--ptr = '\0';
+
+      hwaddr = PyString_FromString (buffer);
+      dict = PyDict_New ();
+
+      if (!dict) {
+        Py_XDECREF (hwaddr);
+        Py_DECREF (result);
+        free (pAdapterInfo);
+        return NULL;
+      }
+
+      PyDict_SetItemString (dict, "addr", hwaddr);
+      Py_DECREF (hwaddr);
+
+      if (!add_to_family (result, AF_LINK, dict)) {
+        Py_DECREF (result);
+        free (pAdapterInfo);
+        return NULL;
+      }
+    }
+
+    for (str = &pInfo->IpAddressList; str; str = str->Next) {
+      PyObject *addr = PyString_FromString (str->IpAddress.String);
+      PyObject *mask = PyString_FromString (str->IpMask.String);
+      PyObject *bcast = NULL;
+      PyObject *dict;
+
+      /* If this isn't the loopback interface, work out the broadcast
+         address, for better compatibility with other platforms. */
+      if (pInfo->Type != MIB_IF_TYPE_LOOPBACK) {
+        unsigned long inaddr = inet_addr (str->IpAddress.String);
+        unsigned long inmask = inet_addr (str->IpMask.String);
+        struct in_addr in;
+        char *brstr;
+
+        in.S_un.S_addr = (inaddr | ~inmask) & 0xfffffffful;
+
+        brstr = inet_ntoa (in);
+
+        if (brstr)
+          bcast = PyString_FromString (brstr);
+      }
+
+      dict = PyDict_New ();
+
+      if (!dict) {
+        Py_XDECREF (addr);
+        Py_XDECREF (mask);
+        Py_XDECREF (bcast);
+        Py_DECREF (result);
+        free (pAdapterInfo);
+        return NULL;
+      }
+
+      if (addr)
+        PyDict_SetItemString (dict, "addr", addr);
+      if (mask)
+        PyDict_SetItemString (dict, "netmask", mask);
+      if (bcast)
+        PyDict_SetItemString (dict, "broadcast", bcast);
+
+      Py_XDECREF (addr);
+      Py_XDECREF (mask);
+      Py_XDECREF (bcast);
+
+      if (!add_to_family (result, AF_INET, dict)) {
+        Py_DECREF (result);
+        free (pAdapterInfo);
+        return NULL;
+      }
+    }
+  }
+
+  free (pAdapterInfo);
+#elif HAVE_GETIFADDRS
+  struct ifaddrs *addrs = NULL;
+  struct ifaddrs *addr = NULL;
+
+  if (getifaddrs (&addrs) < 0) {
+    Py_DECREF (result);
+    PyErr_SetFromErrno (PyExc_OSError);
+    return NULL;
+  }
+
+  for (addr = addrs; addr; addr = addr->ifa_next) {
+    char buffer[256];
+    PyObject *pyaddr = NULL, *netmask = NULL, *braddr = NULL;
+
+    if (strcmp (addr->ifa_name, ifname) != 0)
+      continue;
+    /* Sometimes there are records without addresses (e.g. in the case of a
+       dial-up connection via ppp, which on Linux can have a link address
+       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;  
+
+    found = TRUE;
+
+    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)
+      netmask = PyString_FromString (buffer);
+
+    if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0)
+      braddr = PyString_FromString (buffer);
+
+    PyObject *dict = PyDict_New();
+
+    if (!dict) {
+      Py_XDECREF (pyaddr);
+      Py_XDECREF (netmask);
+      Py_XDECREF (braddr);
+      Py_DECREF (result);
+      freeifaddrs (addrs);
+      return NULL;
+    }
+
+    if (pyaddr)
+      PyDict_SetItemString (dict, "addr", pyaddr);
+    if (netmask)
+      PyDict_SetItemString (dict, "netmask", netmask);
+
+    if (braddr) {
+      if (addr->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
+        PyDict_SetItemString (dict, "peer", braddr);
+      else
+        PyDict_SetItemString (dict, "broadcast", braddr);
+    }
+
+    Py_XDECREF (pyaddr);
+    Py_XDECREF (netmask);
+    Py_XDECREF (braddr);
+
+    if (!add_to_family (result, addr->ifa_addr->sa_family, dict)) {
+      Py_DECREF (result);
+      freeifaddrs (addrs);
+      return NULL;
+    }
+  }
+
+  freeifaddrs (addrs);
+#elif HAVE_SOCKET_IOCTLS
+  
+  int sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+  if (sock < 0) {
+    Py_DECREF (result);
+    PyErr_SetFromErrno (PyExc_OSError);
+    return NULL;
+  }
+
+  struct CNAME(ifreq) ifr;
+  PyObject *addr = NULL, *netmask = NULL, *braddr = NULL, *dstaddr = NULL;
+  int is_p2p = FALSE;
+  char buffer[256];
+
+  strncpy (ifr.CNAME(ifr_name), ifname, IFNAMSIZ);
+
+#if HAVE_SIOCGIFHWADDR
+  if (ioctl (sock, SIOCGIFHWADDR, &ifr) == 0) {
+    found = TRUE;
+
+    if (string_from_sockaddr (ifr->CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) {
+      PyObject *hwaddr = PyString_FromString (buffer);
+      PyObject *dict = PyDict_New ();
+      PyObject *list = PyList_New (1);
+      PyObject *family = PyInt_FromLong (AF_LINK);
+
+      if (!hwaddr || !dict || !list || !family) {
+        Py_XDECREF (hwaddr);
+        Py_XDECREF (dict);
+        Py_XDECREF (list)
+        Py_XDECREF (family);
+        Py_XDECREF (result);
+        close (sock);
+        return NULL;
+      }
+
+      PyDict_SetItemString (dict, "addr", hwaddr);
+      Py_DECREF (hwaddr);
+
+      PyList_SET_ITEM (list, 0, dict);
+
+      PyDict_SetItem (result, family, list);
+      Py_DECREF (family);
+      Py_DECREF (list);
+    }
+  }
+#endif
+
+#if HAVE_SIOCGIFADDR
+#if HAVE_SIOCGLIFNUM
+  if (ioctl (sock, SIOCGLIFADDR, &ifr) == 0) {
+#else
+  if (ioctl (sock, SIOCGIFADDR, &ifr) == 0) {
+#endif
+    found = TRUE;
+
+    if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
+      addr = PyString_FromString (buffer);
+  }
+#endif
+
+#if HAVE_SIOCGIFNETMASK
+#if HAVE_SIOCGLIFNUM
+  if (ioctl (sock, SIOCGLIFNETMASK, &ifr) == 0) {
+#else
+  if (ioctl (sock, SIOCGIFNETMASK, &ifr) == 0) {
+#endif
+    found = TRUE;
+
+    if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
+      netmask = PyString_FromString (buffer);
+  }
+#endif
+
+#if HAVE_SIOCGIFFLAGS
+#if HAVE_SIOCGLIFNUM
+  if (ioctl (sock, SIOCGLIFFLAGS, &ifr) == 0) {
+#else
+  if (ioctl (sock, SIOCGIFFLAGS, &ifr) == 0) {
+#endif
+    found = TRUE;
+
+    if (ifr.CNAME(ifr_flags) & IFF_POINTOPOINT)
+      is_p2p = TRUE;
+  }
+#endif
+
+#if HAVE_SIOCGIFBRDADDR
+#if HAVE_SIOCGLIFNUM
+  if (!is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) {
+#else
+  if (!is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) {
+#endif
+    found = TRUE;
+
+    if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
+      braddr = PyString_FromString (buffer);
+  }
+#endif
+
+#if HAVE_SIOCGIFDSTADDR
+#if HAVE_SIOCGLIFNUM
+  if (is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) {
+#else
+  if (is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) {
+#endif
+    found = TRUE;
+
+    if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
+      dstaddr = PyString_FromString (buffer);
+  }
+#endif
+
+  PyObject *dict = PyDict_New();
+
+  if (!dict) {
+    Py_XDECREF (addr);
+    Py_XDECREF (netmask);
+    Py_XDECREF (braddr);
+    Py_XDECREF (dstaddr);
+    Py_DECREF (result);
+    close (sock);
+    return NULL;
+  }
+
+  if (addr)
+    PyDict_SetItemString (dict, "addr", addr);
+  if (netmask)
+    PyDict_SetItemString (dict, "netmask", netmask);
+  if (braddr)
+    PyDict_SetItemString (dict, "broadcast", braddr);
+  if (dstaddr)
+    PyDict_SetItemString (dict, "peer", dstaddr);
+
+  Py_XDECREF (addr);
+  Py_XDECREF (netmask);
+  Py_XDECREF (braddr);
+  Py_XDECREF (dstaddr);
+
+  if (!PyDict_Size (dict))
+    Py_DECREF (dict);
+  else {
+    PyObject *list = PyList_New(1);
+  
+    if (!list) {
+      Py_DECREF (dict);
+      Py_DECREF (result);
+      close (sock);
+      return NULL;
+    }
+
+    PyList_SET_ITEM (list, 0, dict);
+
+    PyObject *family = PyInt_FromLong (AF_INET);
+    if (!family) {
+      Py_DECREF (result);
+      Py_DECREF (list);
+      close (sock);
+      return NULL;
+    }
+
+    PyDict_SetItem (result, family, list);
+    Py_DECREF (family);
+    Py_DECREF (list);
+  }
+
+  close (sock);
+
+#endif /* HAVE_SOCKET_IOCTLS */
+
+  if (found)
+    return result;
+  else {
+    Py_DECREF (result);
+    PyErr_SetString (PyExc_ValueError, 
+                     "You must specify a valid interface name.");
+    return NULL;
+  }
+}
+
+static PyObject *
+interfaces (PyObject *self)
+{
+  PyObject *result;
+
+#if defined(WIN32)
+  PIP_ADAPTER_INFO pAdapterInfo = NULL;
+  PIP_ADAPTER_INFO pInfo = NULL;
+  ULONG ulBufferLength = 0;
+  DWORD dwRet;
+
+  /* First, retrieve the adapter information */
+  do {
+    dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
+
+    if (dwRet == ERROR_BUFFER_OVERFLOW) {
+      if (pAdapterInfo)
+        free (pAdapterInfo);
+      pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
+
+      if (!pAdapterInfo) {
+        PyErr_SetString (PyExc_MemoryError, "Not enough memory");
+        return NULL;
+      }
+    }
+  } while (dwRet == ERROR_BUFFER_OVERFLOW);
+
+  /* If we failed, then fail in Python too */
+  if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
+    if (pAdapterInfo)
+      free (pAdapterInfo);
+
+    PyErr_SetString (PyExc_OSError,
+                     "Unable to obtain adapter information.");
+    return NULL;
+  }
+
+  result = PyList_New(0);
+
+  if (dwRet == ERROR_NO_DATA) {
+    free (pAdapterInfo);
+    return result;
+  }
+
+  for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) {
+    PyObject *ifname = PyString_FromString (pInfo->AdapterName);
+
+    PyList_Append (result, ifname);
+    Py_DECREF (ifname);
+  }
+
+  free (pAdapterInfo);
+#elif HAVE_GETIFADDRS
+  const char *prev_name = NULL;
+  struct ifaddrs *addrs = NULL;
+  struct ifaddrs *addr = NULL;
+
+  result = PyList_New (0);
+
+  if (getifaddrs (&addrs) < 0) {
+    Py_DECREF (result);
+    PyErr_SetFromErrno (PyExc_OSError);
+    return NULL;
+  }
+
+  for (addr = addrs; addr; addr = addr->ifa_next) {
+    if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0) {
+      PyObject *ifname = PyString_FromString (addr->ifa_name);
+    
+      if (!PySequence_Contains (result, ifname))
+        PyList_Append (result, ifname);
+      Py_DECREF (ifname);
+      prev_name = addr->ifa_name;
+    }
+  }
+
+  freeifaddrs (addrs);
+#elif HAVE_SIOCGIFCONF
+  const char *prev_name = NULL;
+  int fd = socket (AF_INET, SOCK_DGRAM, 0);
+  struct CNAME(ifconf) ifc;
+  int len = -1, n;
+
+  if (fd < 0) {
+    PyErr_SetFromErrno (PyExc_OSError);
+    return NULL;
+  }
+
+  // Try to find out how much space we need
+#if HAVE_SIOCGSIZIFCONF
+  if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0)
+    len = -1;
+#elif HAVE_SIOCGLIFNUM
+  { struct lifnum lifn;
+    lifn.lifn_family = AF_UNSPEC;
+    lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
+    ifc.lifc_family = AF_UNSPEC;
+    ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
+    if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0)
+      len = -1;
+    else
+      len = lifn.lifn_count;
+  }
+#endif
+
+  // As a last resort, guess
+  if (len < 0)
+    len = 64;
+
+  ifc.CNAME(ifc_len) = len * sizeof (struct CNAME(ifreq));
+  ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len));
+
+  if (!ifc.CNAME(ifc_buf)) {
+    PyErr_SetString (PyExc_MemoryError, "Not enough memory");
+    close (fd);
+    return NULL;
+  }
+
+#if HAVE_SIOCGLIFNUM
+  if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) {
+#else
+  if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
+#endif
+    free (ifc.CNAME(ifc_req));
+    PyErr_SetFromErrno (PyExc_OSError);
+    close (fd);
+    return NULL;
+  }
+
+  result = PyList_New (0);
+  struct CNAME(ifreq) *pfreq = ifc.CNAME(ifc_req);
+  for (n = 0; n < ifc.CNAME(ifc_len)/sizeof(struct CNAME(ifreq));
+      n++,pfreq++) {
+    if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0) {
+      PyObject *name = PyString_FromString (pfreq->CNAME(ifr_name));
+
+      if (!PySequence_Contains (result, name))
+        PyList_Append (result, name);
+      Py_XDECREF (name);
+
+      prev_name = pfreq->CNAME(ifr_name);
+    }
+  }
+
+  free (ifc.CNAME(ifc_buf));
+  close (fd);
+#endif /* HAVE_SIOCGIFCONF */
+
+  return result;
+}
+
+static PyMethodDef methods[] = {
+  { "ifaddresses", (PyCFunction)ifaddrs, METH_VARARGS,
+    "Obtain information about the specified network interface.\n"
+"\n"
+"Returns a dict whose keys are equal to the address family constants,\n"
+"e.g. netifaces.AF_INET, and whose values are a list of addresses in\n"
+"that family that are attached to the network interface." },
+  { "interfaces", (PyCFunction)interfaces, METH_NOARGS,
+    "Obtain a list of the interfaces available on this machine." },
+  { NULL, NULL, 0, NULL }
+};
+
+PyMODINIT_FUNC
+initnetifaces (void)
+{
+  PyObject *m;
+
+#ifdef WIN32
+  WSADATA wsad;
+  int iResult;
+  
+  iResult = WSAStartup(MAKEWORD (2, 2), &wsad);
+#endif
+
+  m = Py_InitModule ("netifaces", methods);
+
+  /* Address families (auto-detect using #ifdef) */
+  PyObject *address_family_dict = PyDict_New();
+#ifdef AF_UNSPEC  
+  PyModule_AddIntConstant (m, "AF_UNSPEC", AF_UNSPEC);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNSPEC),
+          PyString_FromString("AF_UNSPEC"));
+#endif
+#ifdef AF_UNIX
+  PyModule_AddIntConstant (m, "AF_UNIX", AF_UNIX);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNIX),
+          PyString_FromString("AF_UNIX"));
+#endif
+#ifdef AF_FILE
+  PyModule_AddIntConstant (m, "AF_FILE", AF_FILE);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FILE),
+          PyString_FromString("AF_FILE"));
+#endif
+#ifdef AF_INET
+  PyModule_AddIntConstant (m, "AF_INET", AF_INET);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET),
+          PyString_FromString("AF_INET"));
+#endif
+#ifdef AF_AX25
+  PyModule_AddIntConstant (m, "AF_AX25", AF_AX25);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_AX25),
+          PyString_FromString("AF_AX25"));
+#endif
+#ifdef AF_IMPLINK  
+  PyModule_AddIntConstant (m, "AF_IMPLINK", AF_IMPLINK);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IMPLINK),
+          PyString_FromString("AF_IMPLINK"));
+#endif
+#ifdef AF_PUP  
+  PyModule_AddIntConstant (m, "AF_PUP", AF_PUP);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PUP),
+          PyString_FromString("AF_PUP"));
+#endif
+#ifdef AF_CHAOS
+  PyModule_AddIntConstant (m, "AF_CHAOS", AF_CHAOS);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CHAOS),
+          PyString_FromString("AF_CHAOS"));
+#endif
+#ifdef AF_NS
+  PyModule_AddIntConstant (m, "AF_NS", AF_NS);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NS),
+          PyString_FromString("AF_NS"));
+#endif
+#ifdef AF_ISO
+  PyModule_AddIntConstant (m, "AF_ISO", AF_ISO);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISO),
+          PyString_FromString("AF_ISO"));
+#endif
+#ifdef AF_ECMA
+  PyModule_AddIntConstant (m, "AF_ECMA", AF_ECMA);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECMA),
+          PyString_FromString("AF_ECMA"));
+#endif
+#ifdef AF_DATAKIT
+  PyModule_AddIntConstant (m, "AF_DATAKIT", AF_DATAKIT);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DATAKIT),
+          PyString_FromString("AF_DATAKIT"));
+#endif
+#ifdef AF_CCITT
+  PyModule_AddIntConstant (m, "AF_CCITT", AF_CCITT);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CCITT),
+          PyString_FromString("AF_CCITT"));
+#endif
+#ifdef AF_SNA
+  PyModule_AddIntConstant (m, "AF_SNA", AF_SNA);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA),
+          PyString_FromString("AF_SNA"));
+#endif
+#ifdef AF_DECnet
+  PyModule_AddIntConstant (m, "AF_DECnet", AF_DECnet);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DECnet),
+          PyString_FromString("AF_DECnet"));
+#endif
+#ifdef AF_DLI
+  PyModule_AddIntConstant (m, "AF_DLI", AF_DLI);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DLI),
+          PyString_FromString("AF_DLI"));
+#endif
+#ifdef AF_LAT
+  PyModule_AddIntConstant (m, "AF_LAT", AF_LAT);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LAT),
+          PyString_FromString("AF_LAT"));
+#endif
+#ifdef AF_HYLINK
+  PyModule_AddIntConstant (m, "AF_HYLINK", AF_HYLINK);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_HYLINK),
+          PyString_FromString("AF_HYLINK"));
+#endif
+#ifdef AF_APPLETALK
+  PyModule_AddIntConstant (m, "AF_APPLETALK", AF_APPLETALK);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_APPLETALK),
+          PyString_FromString("AF_APPLETALK"));
+#endif
+#ifdef AF_ROUTE
+  PyModule_AddIntConstant (m, "AF_ROUTE", AF_ROUTE);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROUTE),
+          PyString_FromString("AF_ROUTE"));
+#endif
+#ifdef AF_LINK
+  PyModule_AddIntConstant (m, "AF_LINK", AF_LINK);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LINK),
+          PyString_FromString("AF_LINK"));
+#endif
+#ifdef AF_PACKET
+  PyModule_AddIntConstant (m, "AF_PACKET", AF_PACKET);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PACKET),
+          PyString_FromString("AF_PACKET"));
+#endif
+#ifdef AF_COIP
+  PyModule_AddIntConstant (m, "AF_COIP", AF_COIP);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_COIP),
+          PyString_FromString("AF_COIP"));
+#endif
+#ifdef AF_CNT
+  PyModule_AddIntConstant (m, "AF_CNT", AF_CNT);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CNT),
+          PyString_FromString("AF_CNT"));
+#endif
+#ifdef AF_IPX
+  PyModule_AddIntConstant (m, "AF_IPX", AF_IPX);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IPX),
+          PyString_FromString("AF_IPX"));
+#endif
+#ifdef AF_SIP
+  PyModule_AddIntConstant (m, "AF_SIP", AF_SIP);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SIP),
+          PyString_FromString("AF_SIP"));
+#endif
+#ifdef AF_NDRV
+  PyModule_AddIntConstant (m, "AF_NDRV", AF_NDRV);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NDRV),
+          PyString_FromString("AF_NDRV"));
+#endif
+#ifdef AF_ISDN
+  PyModule_AddIntConstant (m, "AF_ISDN", AF_ISDN);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISDN),
+          PyString_FromString("AF_ISDN"));
+#endif
+#ifdef AF_INET6
+  PyModule_AddIntConstant (m, "AF_INET6", AF_INET6);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET6),
+          PyString_FromString("AF_INET6"));
+#endif
+#ifdef AF_NATM
+  PyModule_AddIntConstant (m, "AF_NATM", AF_NATM);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NATM),
+          PyString_FromString("AF_NATM"));
+#endif
+#ifdef AF_SYSTEM
+  PyModule_AddIntConstant (m, "AF_SYSTEM", AF_SYSTEM);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SYSTEM),
+          PyString_FromString("AF_SYSTEM"));
+#endif
+#ifdef AF_NETBIOS
+  PyModule_AddIntConstant (m, "AF_NETBIOS", AF_NETBIOS);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBIOS),
+          PyString_FromString("AF_NETBIOS"));
+#endif
+#ifdef AF_NETBEUI
+  PyModule_AddIntConstant (m, "AF_NETBEUI", AF_NETBEUI);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBEUI),
+          PyString_FromString("AF_NETBEUI"));
+#endif
+#ifdef AF_PPP
+  PyModule_AddIntConstant (m, "AF_PPP", AF_PPP);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPP),
+          PyString_FromString("AF_PPP"));
+#endif
+#ifdef AF_ATM
+  PyModule_AddIntConstant (m, "AF_ATM", AF_ATM);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATM),
+          PyString_FromString("AF_ATM"));
+#endif
+#ifdef AF_ATMPVC
+  PyModule_AddIntConstant (m, "AF_ATMPVC", AF_ATMPVC);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMPVC),
+          PyString_FromString("AF_ATMPVC"));
+#endif
+#ifdef AF_ATMSVC
+  PyModule_AddIntConstant (m, "AF_ATMSVC", AF_ATMSVC);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMSVC),
+          PyString_FromString("AF_ATMSVC"));
+#endif
+#ifdef AF_NETGRAPH
+  PyModule_AddIntConstant (m, "AF_NETGRAPH", AF_NETGRAPH);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETGRAPH),
+          PyString_FromString("AF_NETGRAPH"));
+#endif
+#ifdef AF_VOICEVIEW
+  PyModule_AddIntConstant (m, "AF_VOICEVIEW", AF_VOICEVIEW);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_VOICEVIEW),
+          PyString_FromString("AF_VOICEVIEW"));
+#endif
+#ifdef AF_FIREFOX
+  PyModule_AddIntConstant (m, "AF_FIREFOX", AF_FIREFOX);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FIREFOX),
+          PyString_FromString("AF_FIREFOX"));
+#endif
+#ifdef AF_UNKNOWN1
+  PyModule_AddIntConstant (m, "AF_UNKNOWN1", AF_UNKNOWN1);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNKNOWN1),
+          PyString_FromString("AF_UNKNOWN1"));
+#endif
+#ifdef AF_BAN
+  PyModule_AddIntConstant (m, "AF_BAN", AF_BAN);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BAN),
+          PyString_FromString("AF_BAN"));
+#endif
+#ifdef AF_CLUSTER
+  PyModule_AddIntConstant (m, "AF_CLUSTER", AF_CLUSTER);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CLUSTER),
+          PyString_FromString("AF_CLUSTER"));
+#endif
+#ifdef AF_12844
+  PyModule_AddIntConstant (m, "AF_12844", AF_12844);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_12844),
+          PyString_FromString("AF_12844"));
+#endif
+#ifdef AF_IRDA
+  PyModule_AddIntConstant (m, "AF_IRDA", AF_IRDA);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IRDA),
+          PyString_FromString("AF_IRDA"));
+#endif
+#ifdef AF_NETDES
+  PyModule_AddIntConstant (m, "AF_NETDES", AF_NETDES);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETDES),
+          PyString_FromString("AF_NETDES"));
+#endif
+#ifdef AF_NETROM
+  PyModule_AddIntConstant (m, "AF_NETROM", AF_NETROM);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETROM),
+          PyString_FromString("AF_NETROM"));
+#endif
+#ifdef AF_BRIDGE
+  PyModule_AddIntConstant (m, "AF_BRIDGE", AF_BRIDGE);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BRIDGE),
+          PyString_FromString("AF_BRIDGE"));
+#endif
+#ifdef AF_X25
+  PyModule_AddIntConstant (m, "AF_X25", AF_X25);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_X25),
+          PyString_FromString("AF_X25"));
+#endif
+#ifdef AF_ROSE
+  PyModule_AddIntConstant (m, "AF_ROSE", AF_ROSE);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROSE),
+          PyString_FromString("AF_ROSE"));
+#endif
+#ifdef AF_SECURITY
+  PyModule_AddIntConstant (m, "AF_SECURITY", AF_SECURITY);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SECURITY),
+          PyString_FromString("AF_SECURITY"));
+#endif
+#ifdef AF_KEY
+  PyModule_AddIntConstant (m, "AF_KEY", AF_KEY);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_KEY),
+          PyString_FromString("AF_KEY"));
+#endif
+#ifdef AF_NETLINK
+  PyModule_AddIntConstant (m, "AF_NETLINK", AF_NETLINK);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETLINK),
+          PyString_FromString("AF_NETLINK"));
+#endif
+#ifdef AF_ASH
+  PyModule_AddIntConstant (m, "AF_ASH", AF_ASH);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ASH),
+          PyString_FromString("AF_ASH"));
+#endif
+#ifdef AF_ECONET
+  PyModule_AddIntConstant (m, "AF_ECONET", AF_ECONET);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECONET),
+          PyString_FromString("AF_ECONET"));
+#endif
+#ifdef AF_SNA
+  PyModule_AddIntConstant (m, "AF_SNA", AF_SNA);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA),
+          PyString_FromString("AF_SNA"));
+#endif
+#ifdef AF_PPPOX
+  PyModule_AddIntConstant (m, "AF_PPPOX", AF_PPPOX);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPPOX),
+          PyString_FromString("AF_PPPOX"));
+#endif
+#ifdef AF_WANPIPE
+  PyModule_AddIntConstant (m, "AF_WANPIPE", AF_WANPIPE);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_WANPIPE),
+          PyString_FromString("AF_WANPIPE"));
+#endif
+#ifdef AF_BLUETOOTH
+  PyModule_AddIntConstant (m, "AF_BLUETOOTH", AF_BLUETOOTH);
+  PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BLUETOOTH),
+          PyString_FromString("AF_BLUETOOTH"));
+#endif
+  PyModule_AddObject(m, "address_families", address_family_dict);
+}
diff --git a/netifaces.egg-info/PKG-INFO b/netifaces.egg-info/PKG-INFO
new file mode 100755 (executable)
index 0000000..9dcb201
--- /dev/null
@@ -0,0 +1,25 @@
+Metadata-Version: 1.0
+Name: netifaces
+Version: 0.6
+Summary: Portable network interface information.
+Home-page: http://alastairs-place.net/netifaces
+Author: Alastair Houghton
+Author-email: alastair@alastairs-place.net
+License: MIT License
+Description: netifaces provides a (hopefully portable-ish) way for Python programmers to
+        get access to a list of the network interfaces on the local machine, and to
+        obtain the addresses of those network interfaces.
+        
+        The package has been tested on Mac OS X, Windows XP, Windows Vista, Linux
+        and Solaris.  On Windows, it is currently not able to retrieve IPv6
+        addresses, owing to shortcomings of the Windows API.
+        
+        It should work on other UNIX-like systems provided they implement
+        either getifaddrs() or support the SIOCGIFxxx socket options, although the
+        data provided by the socket options is normally less complete.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: System :: Networking
diff --git a/netifaces.egg-info/SOURCES.txt b/netifaces.egg-info/SOURCES.txt
new file mode 100755 (executable)
index 0000000..3699ec0
--- /dev/null
@@ -0,0 +1,8 @@
+README
+netifaces.c
+setup.cfg
+setup.py
+netifaces.egg-info/PKG-INFO
+netifaces.egg-info/SOURCES.txt
+netifaces.egg-info/dependency_links.txt
+netifaces.egg-info/top_level.txt
\ No newline at end of file
diff --git a/netifaces.egg-info/dependency_links.txt b/netifaces.egg-info/dependency_links.txt
new file mode 100755 (executable)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/netifaces.egg-info/top_level.txt b/netifaces.egg-info/top_level.txt
new file mode 100755 (executable)
index 0000000..3f008fd
--- /dev/null
@@ -0,0 +1 @@
+netifaces
diff --git a/packaging/python-netifaces.changes b/packaging/python-netifaces.changes
new file mode 100644 (file)
index 0000000..7b445ea
--- /dev/null
@@ -0,0 +1,2 @@
+* Fri Aug 31 22:13:02 UTC 2012 - jimmy.huang@intel.com
+- Intial import from upstream.
diff --git a/packaging/python-netifaces.spec b/packaging/python-netifaces.spec
new file mode 100644 (file)
index 0000000..5caa207
--- /dev/null
@@ -0,0 +1,37 @@
+Name:       python-netifaces
+Version:    0.6
+Release:    1
+Group:      System/Libraries
+License:    MIT
+Url:        http://alastairs-place.net/netifaces/
+Summary:    Portable network interface information
+Source:     http://alastairs-place.net/projects/netifaces/netifaces-%{version}.tar.gz
+BuildRequires:  pkgconfig(python)
+BuildRequires:  python-setuptools
+
+%description
+netifaces provides a (hopefully portable-ish) way for Python programmers to
+get access to a list of the network interfaces on the local machine, and to
+obtain the addresses of those network interfaces.
+
+The package has been tested on Mac OS X, Windows XP, Windows Vista, Linux and
+Solaris. On Windows, it is currently not able to retrieve IPv6 addresses,
+owing to shortcomings of the Windows API.
+
+It should work on other UNIX-like systems provided they implement either
+getifaddrs() or support the SIOCGIFxxx socket options, although the data
+provided by the socket options is normally less complete.
+
+%prep
+%setup -q -n netifaces-%{version}
+
+%build
+python setup.py build
+
+%install
+python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%doc README
+%{python_sitearch}/*
diff --git a/setup.cfg b/setup.cfg
new file mode 100644 (file)
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..a9335e4
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,409 @@
+import setuptools
+import os
+import sys
+import distutils.spawn
+from setuptools import setup, Extension
+from setuptools.command.build_ext import build_ext
+from distutils.errors import *
+import pickle
+
+# Disable hard links, otherwise building distributions fails
+del os.link
+
+# On Windows, we need ws2_32 and iphlpapi
+if getattr(sys, 'getwindowsversion', None):
+    libraries = ['ws2_32', 'iphlpapi']
+    def_macros = [('WIN32', 1)]
+else:
+    mos = getattr(sys, 'platform', None)
+    libraries = []
+    if mos.startswith('sunos'):
+        libraries = ['socket', 'nsl']
+    def_macros = []
+
+iface_mod = Extension('netifaces', sources=['netifaces.c'],
+                      libraries=libraries,
+                      define_macros=def_macros)
+
+#
+#  There must be a better way to do this...
+#
+class my_build_ext(build_ext):
+    def build_extensions(self):
+        self.check_requirements()
+        build_ext.build_extensions(self)
+
+    def test_build(self, contents, link=True, execute=True, libraries=None,
+                   include_dirs=None, library_dirs=None):
+        name = os.path.join(self.build_temp, 'conftest-%s.c' % self.conftestidx)
+        self.conftestidx += 1
+        if os.path.exists(name):
+            os.unlink(name)
+        thefile = open(name, 'w')
+        print >>thefile, contents
+        thefile.close()
+
+        tmpext = Extension('_dummy', [], libraries = libraries)
+        libraries = self.get_libraries(tmpext)
+        
+        sys.stdout.flush()
+        sys.stderr.flush()
+        mystdout = os.dup(1)
+        mystderr = os.dup(2)
+        result = True
+        try:
+            os.dup2(self.ctout, 1)
+            os.dup2(self.ctout, 2)
+            try:
+                objects = self.compiler.compile([name],
+                                                output_dir=self.build_temp,
+                                                include_dirs=include_dirs,
+                                                debug=self.debug)
+                if link:
+                    self.compiler.link_executable(objects,
+                                                  'conftest',
+                                                  output_dir=self.build_temp,
+                                                  library_dirs=library_dirs,
+                                                  libraries=libraries,
+                                                  debug=self.debug)
+                    if execute:
+                        abspath = os.path.abspath(os.path.join(self.build_temp,
+                                                               'conftest'))
+                        pipe = os.popen(abspath, 'r')
+                        result = pipe.read().strip()
+                        status = pipe.close()
+                        if status is None:
+                            status = 0
+                        if result == '':
+                            result = True
+                        if status != 0:
+                            result = False
+                        
+            finally:
+                os.dup2(mystdout, 1)
+                os.dup2(mystderr, 2)
+        except CompileError:
+            return False
+        except DistutilsExecError:
+            return False
+        return result
+
+    def check_requirements(self):
+        # Load the cached config data from a previous run if possible; compiling
+        # things to test for features is slow
+        cache_file = os.path.join(self.build_temp, 'config.cache')
+        if os.path.exists(cache_file):
+            myfile = open(cache_file, 'r')
+            try:
+                results = pickle.load(myfile)
+            finally:
+                myfile.close()
+        else:
+            results = {}
+
+        self.conftestidx = 0
+        
+        print "checking for getifaddrs...",
+
+        result = results.get('have_getifaddrs', 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, 'conftest.out')
+            self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
+            testrig = """
+            #include <sys/types.h>
+            #include <sys/socket.h>
+            #include <ifaddrs.h>
+            int main(void) {
+              struct ifaddrs *addrs;
+              int ret;
+              ret = getifaddrs(&addrs);
+              freeifaddrs (addrs);
+              return 0;
+            }
+            """
+            if self.test_build(testrig):
+                result = True
+            else:
+                result = False
+
+        if result:
+            print "found. %s" % cached
+            self.compiler.define_macro('HAVE_GETIFADDRS', 1)
+        else:
+            print "not found. %s" % cached
+
+        results['have_getifaddrs'] = result
+
+        print "checking for getnameinfo...",
+
+        result = results.get('have_getnameinfo', 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, 'conftest2.out')
+            self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
+            testrig = """
+            #include <sys/types.h>
+            #include <sys/socket.h>
+            #include <arpa/inet.h>
+            #include <netdb.h>
+            #include <stdlib.h>
+            int main(void) {
+              struct sockaddr_in sin;
+              char buffer[256];
+              int ret;
+
+              sin.sin_family = AF_INET;
+              sin.sin_port = 0;
+              sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+              
+              ret = getnameinfo ((struct sockaddr *)&sin, sizeof (sin),
+                                 buffer, sizeof (buffer),
+                                 NULL, 0,
+                                 NI_NUMERICHOST);
+
+              return 0;
+            }
+            """
+            if self.test_build(testrig,libraries=libraries):
+                result = True
+            else:
+                result = False
+
+        if result:
+            print "found. %s" % cached
+            self.compiler.define_macro('HAVE_GETNAMEINFO', 1)
+        else:
+            print "not found. %s" % cached
+
+        results['have_getnameinfo'] = result
+
+        if not results['have_getifaddrs']:
+            print "checking for socket IOCTLs...",
+
+            result = results.get('have_socket_ioctls', None)
+            if result is not None:
+                cached = '(cached)'
+            else:
+                cached = ''
+
+                result = []
+                ioctls = ('SIOCGIFCONF',
+                          'SIOCGSIZIFCONF',
+                          'SIOCGIFHWADDR',
+                          'SIOCGIFADDR',
+                          'SIOCGIFFLAGS',
+                          'SIOCGIFDSTADDR',
+                          'SIOCGIFBRDADDR',
+                          'SIOCGIFNETMASK',
+                          'SIOCGLIFNUM',
+                          'SIOCGLIFCONF',
+                          'SIOCGLIFFLAGS')
+                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 <arpa/inet.h>
+                    %(addedinc)s
+                    int main(void) {
+                        int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP);
+                        struct 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:
+                print "%r. %s" % (result, cached)
+                for ioctl in result:
+                    self.compiler.define_macro('HAVE_%s' % ioctl, 1)
+                self.compiler.define_macro('HAVE_SOCKET_IOCTLS', 1)
+            else:
+                print "not found. %s" % cached
+
+            results['have_socket_ioctls'] = result
+
+        print "checking for optional header files...",
+
+        result = results.get('have_headers', None)
+        if result is not None:
+            cached = '(cached)'
+        else:
+            cached = ''
+
+            result =[]
+            headers = ('net/if_dl.h', 'netash/ash.h',
+                       'netatalk/at.h', 'netax25/ax25.h',
+                       'neteconet/ec.h', 'netipx/ipx.h',
+                       'netpacket/packet.h', 'netrose/rose.h',
+                       'linux/irda.h', 'linux/atm.h',
+                       'linux/llc.h', 'linux/tipc.h',
+                       'linux/dn.h')
+
+            for header in headers:
+                testrig = """
+                #include <sys/types.h>
+                #include <sys/socket.h>
+                #include <net/if.h>
+                #include <%s>
+                int main (void) { return 0; }
+                """ % header
+
+                if self.test_build(testrig, link=False, execute=False):
+                    result.append(header)
+
+        if result:
+            print "%s. %s" % (' '.join(result), cached)
+            for header in result:
+                macro = header.upper().replace('.', '_').replace('/', '_')
+                self.compiler.define_macro('HAVE_%s' % macro, 1)
+        else:
+            print "none found. %s" % cached
+
+        optional_headers = result
+        results['have_headers'] = result
+
+        print "checking whether struct sockaddr has a length field...",
+
+        result = results.get('have_sockaddr_sa_len', None)
+        if result is not None:
+            cached = '(cached)'
+        else:
+            cached = ''
+
+            testrig = """
+            #include <sys/types.h>
+            #include <sys/socket.h>
+            #include <net/if.h>
+
+            int main (void) {
+              struct sockaddr sa;
+              sa.sa_len = 5;
+              return 0;
+            }
+            """
+
+            result = self.test_build(testrig, execute=False)
+
+        if result:
+            print 'yes. %s' % cached
+            self.compiler.define_macro('HAVE_SOCKADDR_SA_LEN', 1)
+        else:
+            print 'no. %s' % cached
+
+        results['have_sockaddr_sa_len'] = result
+
+        if not results['have_sockaddr_sa_len']:
+            # GAK! On certain stupid platforms (Linux), there's no sa_len.
+            # Macho Linux programmers apparently think that it's not needed,
+            # however, unfortunately, getifaddrs() doesn't return the
+            # lengths, because they're in the sa_len field on just about
+            # everything but Linux.
+            print "checking which sockaddr_xxx structs are defined...",
+            
+            result = results.get('have_sockaddrs', None)
+            if result is not None:
+                cached = '(cached)'
+            else:
+                cached = ''
+
+                sockaddrs = ('at', 'ax25', 'dl', 'eon', 'in', 'in6',
+                             'inarp', 'ipx', 'iso', 'ns', 'un', 'x25',
+                             'rose', 'ash', 'ec', 'll', 'atmpvc', 'atmsvc',
+                             'dn', 'irda', 'llc')
+                result = []
+                for sockaddr in sockaddrs:
+                    testrig = """
+                    #include <sys/types.h>
+                    #include <sys/socket.h>
+                    #include <sys/un.h>
+                    #include <net/if.h>
+                    #include <netinet/in.h>
+                    %(includes)s
+                    
+                    int main (void) {
+                      struct sockaddr_%(sockaddr)s sa;
+                      return 0;
+                    }
+                    """ % { 'includes': '\n'.join(["#include <%s>" % header
+                                                   for header
+                                                   in optional_headers]),
+                            'sockaddr': sockaddr }
+
+                    if self.test_build(testrig, execute=False):
+                        result.append(sockaddr)
+                
+            if result:
+                print '%s. %s' % (' '.join(result), cached)
+                for sockaddr in result:
+                    self.compiler.define_macro('HAVE_SOCKADDR_%s' \
+                                               % sockaddr.upper(), 1)
+            else:
+                print 'none! %s' % cached
+
+            results['have_sockaddrs'] = result
+
+       # Save the results to our config.cache file
+        myfile = open(cache_file, 'w')
+        try:
+            pickle.dump(results, myfile)
+        finally:
+            myfile.close()
+
+# Don't bother detecting socket ioctls on Windows
+if not getattr(sys, 'getwindowsversion', None):
+    setuptools.command.build_ext.build_ext = my_build_ext
+
+setup (name='netifaces',
+       version='0.6',
+       description="Portable network interface information.",
+       license="MIT License",
+       long_description="""\
+netifaces provides a (hopefully portable-ish) way for Python programmers to
+get access to a list of the network interfaces on the local machine, and to
+obtain the addresses of those network interfaces.
+
+The package has been tested on Mac OS X, Windows XP, Windows Vista, Linux
+and Solaris.  On Windows, it is currently not able to retrieve IPv6
+addresses, owing to shortcomings of the Windows API.
+
+It should work on other UNIX-like systems provided they implement
+either getifaddrs() or support the SIOCGIFxxx socket options, although the
+data provided by the socket options is normally less complete.
+""",
+       author='Alastair Houghton',
+       author_email='alastair@alastairs-place.net',
+       url='http://alastairs-place.net/netifaces',
+       classifiers=[
+    'Development Status :: 4 - Beta',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: MIT License',
+    'Topic :: System :: Networking',
+    ],
+       ext_modules=[iface_mod])