diff options
author | Alastair Houghton <alastair@coriolis-systems.com> | 2018-02-13 15:21:44 +0000 |
---|---|---|
committer | Alastair Houghton <alastair@coriolis-systems.com> | 2018-02-13 15:21:44 +0000 |
commit | 0f750cc85fccf6b5280afd645043fffab0e98735 (patch) | |
tree | acf962c8d72a5c8050eefdd1e71f101d22d7d3b9 | |
parent | 90aa1fec654042bc944aecaf02483f4adc08263b (diff) | |
download | netifaces-0f750cc85fccf6b5280afd645043fffab0e98735.tar.gz |
Removed all files.
-rw-r--r-- | CHANGELOG | 83 | ||||
-rw-r--r-- | PKG-INFO | 25 | ||||
-rw-r--r-- | README.rst | 197 | ||||
-rw-r--r-- | netifaces.c | 2903 | ||||
-rw-r--r-- | pypi_windows_packages.bat | 6 | ||||
-rw-r--r-- | setup.cfg | 5 | ||||
-rw-r--r-- | setup.py | 596 | ||||
-rw-r--r-- | test.py | 50 |
8 files changed, 0 insertions, 3865 deletions
diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index ca84e12..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,83 +0,0 @@ -2017-06-01 Version 0.10.6 - - * Fixed netmask determination on Windows. - * All addresses are now unicode strings on all platforms, - regardless of Python version. - -2016-08-23 Version 0.10.5 - - * Fixed setup.py in case there's no print (thanks Stavros). - * Fixed a potential one-byte stack overwrite (thanks Doug Horn). - * Fixed possible null pointer deference (thanks bastiak). - * Added support for IPv6 address flags on BSD/Mac OS X (thanks - stefann). - * Respect interface priorities when determining default gateway - (on Windows and Linux). - * Use CIDR notation for IPv6 netmasks. - * Ignore broadcast addresses in the 169.254.0.0/16 range (it - appears Cygwin's getaddrinfo() may erroneously generate these). - * Stop using deprecated WSAAddressToStringA() API on Windows - in favour of using WSAAddressToStringW() where available. Falls - back to the older API if required. - -2014-05-19 Version 0.10.4 - - * Fixed a problem with multi-part Netlink messages on Linux. - -2014-05-06 Version 0.10.3 - - * When using Netlink (i.e. Linux), check for the constant - NLM_F_DUMP_INTR, since it only appeared in kernel version 3.1 - -2014-05-03 Version 0.10.2 - - * Added a workaround for broken netlink headers on certain Linux - distributions (the problem being that the netlink headers fail to - include <bits/sockaddr.h>, which causes a build failure). - -2014-05-02 Version 0.10.1 - - * Fixed a problem with the gateways() function that caused it a - crash on PyPy. - * The CI system is now set up to build for PyPy as well, so - problems will be found sooner. - -2014-05-01 Version 0.10.0 - - * Python 3 compatibility. - * Improved Windows source code compatibility. - * Added gateway detection via gateways() function. - * New version number format (skipped 0.9.0 due to its use by - the netifaces-merged fork). - -2012-01-31 Version 0.8 - - All changes in this version relate to the ioctl( ) code path, - which is not used on Windows or on any modern UNIX or UNIX-like - system that implements getaddrinfo(). - - * Fixed bit-rot in the ioctl() code path. - * Fixed a problem with setup.py that might manifest itself if the - config.cache file was manually edited. - * Fixed the ioctl() code path to cope with systems that have - sa_len and return longer than normal struct ifreq requests from - SIOCG[L]IFCONF (for instance, Mac OS X). - -2012-01-30 Version 0.7 - - * Dropped support for Win2K and earlier - * Added support for addresses other than IPv4 on Windows - * Removed empty 'addr' entries for interfaces that don't provide - any addresses. - * Fixed problems with setup script that prevented it running on - Windows, and improved the chances of it working with - cross-compilers somewhat. - * Added a verion property to the module that you can test at - runtime. - -2011-11-04 Version 0.6 - - * Added a workaround for a FreeBSD kernel bug (kern/152036). - * Added address_families dictionary to allow code to look up the - symbolic name corresponding to a given numberic address family - code. diff --git a/PKG-INFO b/PKG-INFO deleted file mode 100644 index 8fe1dcf..0000000 --- a/PKG-INFO +++ /dev/null @@ -1,25 +0,0 @@ -Metadata-Version: 1.0 -Name: netifaces -Version: 0.5 -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.rst b/README.rst deleted file mode 100644 index d08c175..0000000 --- a/README.rst +++ /dev/null @@ -1,197 +0,0 @@ -netifaces 0.10.6 -================ - -.. image:: https://drone.io/bitbucket.org/al45tair/netifaces/status.png - :target: https://drone.io/bitbucket.org/al45tair/netifaces/latest - :alt: Build Status - -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.10.6.tar.gz - cd netifaces-0.10.6 - python setup.py install - -**Note that you will need the relevant developer tools for your platform**, -as netifaces is written in C and installing this way will compile the extension. - -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. - -As of version 0.10.0, you can also obtain a list of gateways on your -machine: - ->>> netifaces.gateways() -{2: [('10.0.1.1', 'en0', True), ('10.2.1.1', 'en1', False)], 30: [('fe80::1', 'en0', True)], 'default': { 2: ('10.0.1.1', 'en0'), 30: ('fe80::1', 'en0') }} - -This dictionary is keyed on address family---in this case, ``AF_INET``---and -each entry is a list of gateways as ``(address, interface, is_default)`` tuples. -Notice that here we have two separate gateways for IPv4 (``AF_INET``); some -operating systems support configurations like this and can either route packets -based on their source, or based on administratively configured routing tables. - -For convenience, we also allow you to index the dictionary with the special -value ``'default'``, which returns a dictionary mapping address families to the -default gateway in each case. Thus you can get the default IPv4 gateway with - ->>> gws = netifaces.gateways() ->>> gws['default'][netifaces.AF_INET] -('10.0.1.1', 'en0') - -Do note that there may be no default gateway for any given address family; -this is currently very common for IPv6 and much less common for IPv4 but it -can happen even for ``AF_INET``. - -BTW, if you're trying to configure your machine to have multiple gateways for -the same address family, it's a very good idea to check the documentation for -your operating system *very* carefully, as some systems become extremely -confused or route packets in a non-obvious manner. - -I'm very interested in hearing from anyone (on any platform) for whom the -``gateways()`` method doesn't produce the expected results. It's quite -complicated extracting this information from the operating system (whichever -operating system we're talking about), and so I expect there's at least one -system out there where this just won't work. - -3. This is great! What platforms does it work on? --------------------------------------------------- - -It gets regular testing on OS X, Linux and Windows. It has also been used -successfully on Solaris, and it's expected to work properly on other UNIX-like -systems as well. If you are running something that is not supported, and -wish to contribute a patch, please use BitBucket to send a pull request. - -4. What license is this under? ------------------------------- - -It's an MIT-style license. Here goes: - -Copyright (c) 2007-2017 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. - -5. Why the jump to 0.10.0? --------------------------- - -Because someone released a fork of netifaces with the version 0.9.0. -Hopefully skipping the version number should remove any confusion. In -addition starting with 0.10.0 Python 3 is now supported and other -features/bugfixes have been included as well. See the CHANGELOG for a -more complete list of changes. diff --git a/netifaces.c b/netifaces.c deleted file mode 100644 index 9408d73..0000000 --- a/netifaces.c +++ /dev/null @@ -1,2903 +0,0 @@ -#include <Python.h> - -/* Before Python 2.6, PyUnicode_FromString doesn't exist */ -#if PY_MAJOR_VERSION < 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6) -PyObject *PyUnicode_FromString(const char *s) -{ - Py_ssize_t len = strlen(s); - if (!len) { - Py_UNICODE uc = 0; - return PyUnicode_FromUnicode(&uc, 0); - } - return PyUnicode_DecodeUTF8(s, len, NULL); -} -#endif - -/* Python 3 compatibility */ -#if PY_MAJOR_VERSION >= 3 -#define PyInt_FromLong PyLong_FromLong - -#define MODULE_ERROR NULL -#define MODULE_RETURN(v) return (v) -#define MODULE_INIT(name) PyMODINIT_FUNC PyInit_##name(void) -#define MODULE_DEF(name,doc,methods) \ - static struct PyModuleDef moduledef = { \ - PyModuleDef_HEAD_INIT, (name), (doc), -1, (methods), }; -#define MODULE_CREATE(obj,name,doc,methods) \ - obj = PyModule_Create(&moduledef); -#else /* PY_MAJOR_VERSION < 3 */ -#define MODULE_ERROR -#define MODULE_RETURN(v) -#define MODULE_INIT(name) void init##name(void) -#define MODULE_DEF(name,doc,methods) -#define MODULE_CREATE(obj,name,doc,methods) \ - obj = Py_InitModule3((name), (methods), (doc)); -#endif - -#ifndef WIN32 - -# include <sys/types.h> -# include <sys/socket.h> -# include <net/if.h> -# include <netdb.h> - -# if HAVE_PF_ROUTE -# include <net/route.h> -# endif - -# if HAVE_SYSCTL_CTL_NET -# include <sys/sysctl.h> -# include <net/route.h> -# endif - -/* RTNL_FAMILY_MAX not there yet in old kernels, see linux commit 25239ce */ -# if HAVE_PF_NETLINK -# include <asm/types.h> -# include <linux/netlink.h> -# include <linux/rtnetlink.h> -# if !defined(RTNL_FAMILY_MAX) -# include <linux/net.h> -# define RTNL_FAMILY_MAX NPROTO -# endif -# 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> -# 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 -#if defined(AF_LINK) && HAVE_SOCKADDR_DL - case AF_LINK: return sizeof (struct sockaddr_dl); -#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) */ - -#define _WIN32_WINNT 0x0501 - -# include <winsock2.h> -# include <ws2tcpip.h> -# include <iphlpapi.h> -# include <netioapi.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 - -/* -- Utility Functions ----------------------------------------------------- */ - -#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)) { - /* Sometimes 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) { - size_t 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; - } - if (len) - *--ptr = '\0'; - } - - if (!buffer[0]) - return -1; - - 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) -static int -compare_bits (const void *pva, - const void *pvb, - unsigned bits) -{ - const unsigned char *pa = (const unsigned char *)pva; - const unsigned char *pb = (const unsigned char *)pvb; - unsigned char a, b; - static unsigned char masks[] = { - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe - }; - while (bits >= 8) { - a = *pa++; - b = *pb++; - if (a < b) - return -1; - else if (a > b) - return +1; - bits -= 8; - } - - if (bits) { - a = *pa++ & masks[bits]; - b = *pb++ & masks[bits]; - if (a < b) - return -1; - else if (a > b) - return +1; - } - - 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 PyUnicode_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 PyUnicode_FromString (buffer); - } - - return NULL; -} -#endif - -static int -add_to_family (PyObject *result, int family, PyObject *obj) -{ - PyObject *py_family; - PyObject *list; - - if (!PyObject_Size (obj)) - return TRUE; - - py_family = PyInt_FromLong (family); - list = PyDict_GetItem (result, py_family); - - if (!py_family) { - Py_DECREF (obj); - Py_XDECREF (list); - return FALSE; - } - - if (!list) { - list = PyList_New (1); - if (!list) { - Py_DECREF (obj); - Py_DECREF (py_family); - return FALSE; - } - - PyList_SET_ITEM (list, 0, obj); - PyDict_SetItem (result, py_family, list); - Py_DECREF (list); - } else { - PyList_Append (list, obj); - Py_DECREF (obj); - } - - return TRUE; -} - -/* -- ifaddresses() --------------------------------------------------------- */ - -static PyObject * -ifaddrs (PyObject *self, PyObject *args) -{ - const char *ifname; - PyObject *result; - int found = FALSE; -#if defined(WIN32) - PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pInfo = NULL; - ULONG ulBufferLength = 0; - DWORD dwRet; - PIP_ADAPTER_UNICAST_ADDRESS pUniAddr; -#elif HAVE_GETIFADDRS - struct ifaddrs *addrs = NULL; - struct ifaddrs *addr = NULL; -#endif - - if (!PyArg_ParseTuple (args, "s", &ifname)) - return NULL; - - result = PyDict_New (); - - if (!result) - return NULL; - -#if defined(WIN32) - /* .. Win32 ............................................................... */ - - /* First, retrieve the adapter information. We do this in a loop, in - case someone adds or removes adapters in the meantime. */ - do { - dwRet = GetAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, - pAdapterAddresses, &ulBufferLength); - - if (dwRet == ERROR_BUFFER_OVERFLOW) { - if (pAdapterAddresses) - free (pAdapterAddresses); - pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc (ulBufferLength); - - if (!pAdapterAddresses) { - 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 (pAdapterAddresses) - free (pAdapterAddresses); - - PyErr_SetString (PyExc_OSError, - "Unable to obtain adapter information."); - return NULL; - } - - for (pInfo = pAdapterAddresses; pInfo; pInfo = pInfo->Next) { - char buffer[256]; - - if (strcmp (pInfo->AdapterName, ifname) != 0) - continue; - - found = TRUE; - - /* Do the physical address */ - if (256 >= 3 * pInfo->PhysicalAddressLength) { - PyObject *hwaddr, *dict; - char *ptr = buffer; - unsigned n; - - *ptr = '\0'; - for (n = 0; n < pInfo->PhysicalAddressLength; ++n) { - sprintf (ptr, "%02x:", pInfo->PhysicalAddress[n] & 0xff); - ptr += 3; - } - *--ptr = '\0'; - - hwaddr = PyUnicode_FromString (buffer); - dict = PyDict_New (); - - if (!dict) { - Py_XDECREF (hwaddr); - Py_DECREF (result); - free (pAdapterAddresses); - return NULL; - } - - PyDict_SetItemString (dict, "addr", hwaddr); - Py_DECREF (hwaddr); - - if (!add_to_family (result, AF_LINK, dict)) { - Py_DECREF (result); - free (pAdapterAddresses); - return NULL; - } - } - - for (pUniAddr = pInfo->FirstUnicastAddress; - pUniAddr; - pUniAddr = pUniAddr->Next) { - PyObject *addr; - PyObject *mask = NULL; - PyObject *bcast = NULL; - PIP_ADAPTER_PREFIX pPrefix; - short family = pUniAddr->Address.lpSockaddr->sa_family; - - addr = string_from_address (pUniAddr->Address.lpSockaddr, - pUniAddr->Address.iSockaddrLength); - - if (!addr) - continue; - - /* Find the netmask, where possible */ - if (family == AF_INET) { - 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; - - if (pPrefixAddr->sin_family != AF_INET - || (prefix_len >= 0 - && pPrefix->PrefixLength < (unsigned)prefix_len) - || (prefix_len >= 0 && pPrefix->PrefixLength == 32)) - continue; - - if (compare_bits (&pPrefixAddr->sin_addr, - &pAddr->sin_addr, - pPrefix->PrefixLength) == 0) { - prefix_len = pPrefix->PrefixLength; - pBest = pPrefix; - } - } - - if (!pBest) - continue; - - if (prefix_len < 0) - prefix_len = 32; - - 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; - } - - 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; - - if (pPrefixAddr->sin6_family != AF_INET6 - || (prefix_len >= 0 - && pPrefix->PrefixLength < (unsigned)prefix_len) - || (prefix_len >= 0 && pPrefix->PrefixLength == 128)) - continue; - - if (compare_bits (&pPrefixAddr->sin6_addr, - &pAddr->sin6_addr, - pPrefix->PrefixLength) == 0) { - prefix_len = pPrefix->PrefixLength; - pBest = pPrefix; - } - } - - if (!pBest) - continue; - - if (prefix_len < 0) - prefix_len = 128; - - 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)); - } - - { - PyObject *dict; - - dict = PyDict_New (); - - if (!dict) { - Py_XDECREF (addr); - Py_XDECREF (mask); - Py_XDECREF (bcast); - Py_DECREF (result); - free (pAdapterAddresses); - 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, family, dict)) { - Py_DECREF (result); - free ((void *)pAdapterAddresses); - return NULL; - } - } - } - } - - free ((void *)pAdapterAddresses); -#elif HAVE_GETIFADDRS - /* .. UNIX, with getifaddrs() ............................................. */ - - 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, *flags = NULL; - - if (strcmp (addr->ifa_name, ifname) != 0) - continue; - - /* We mark the interface as found, even if there are no addresses; - this results in sensible behaviour for these few cases. */ - found = TRUE; - - /* 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; - -#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 = PyUnicode_FromString (buffer); - - if (string_from_netmask (addr->ifa_netmask, buffer, sizeof (buffer)) == 0) - netmask = PyUnicode_FromString (buffer); - - if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0) - braddr = PyUnicode_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(); - - if (!dict) { - Py_XDECREF (pyaddr); - Py_XDECREF (netmask); - Py_XDECREF (braddr); - Py_XDECREF (flags); - 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); - } - - 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); - freeifaddrs (addrs); - return NULL; - } - } - } - - freeifaddrs (addrs); -#elif HAVE_SOCKET_IOCTLS - /* .. UNIX, with SIOC 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 ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) { - PyObject *hwaddr = PyUnicode_FromString (buffer); - PyObject *dict = PyDict_New (); - - if (!hwaddr || !dict) { - Py_XDECREF (hwaddr); - Py_XDECREF (dict); - Py_XDECREF (result); - close (sock); - return NULL; - } - - PyDict_SetItemString (dict, "addr", hwaddr); - Py_DECREF (hwaddr); - - if (!add_to_family (result, AF_LINK, dict)) { - Py_DECREF (result); - close (sock); - return NULL; - } - } - } -#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 = PyUnicode_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 = PyUnicode_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 = PyUnicode_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 = PyUnicode_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 (!add_to_family (result, AF_INET, dict)) { - Py_DECREF (result); - close (sock); - return NULL; - } - } - - 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; - } -} - -/* -- interfaces() ---------------------------------------------------------- */ - -static PyObject * -interfaces (PyObject *self) -{ - PyObject *result; - -#if defined(WIN32) - /* .. Win32 ............................................................... */ - - PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pInfo = NULL; - ULONG ulBufferLength = 0; - DWORD dwRet; - - /* First, retrieve the adapter information */ - do { - dwRet = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, - pAdapterAddresses, &ulBufferLength); - - if (dwRet == ERROR_BUFFER_OVERFLOW) { - if (pAdapterAddresses) - free (pAdapterAddresses); - pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc (ulBufferLength); - - if (!pAdapterAddresses) { - 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 (pAdapterAddresses) - free (pAdapterAddresses); - - PyErr_SetString (PyExc_OSError, - "Unable to obtain adapter information."); - return NULL; - } - - result = PyList_New(0); - - if (dwRet == ERROR_NO_DATA) { - free (pAdapterAddresses); - return result; - } - - for (pInfo = pAdapterAddresses; pInfo; pInfo = pInfo->Next) { - PyObject *ifname = (PyObject *)PyUnicode_FromString (pInfo->AdapterName); - - PyList_Append (result, ifname); - Py_DECREF (ifname); - } - - free (pAdapterAddresses); -#elif HAVE_GETIFADDRS - /* .. UNIX, with 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 = PyUnicode_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 - /* .. UNIX, with SIOC ioctl()s ............................................ */ - - const char *prev_name = NULL; - int fd = socket (AF_INET, SOCK_DGRAM, 0); - struct CNAME(ifconf) ifc; - int len = -1; - - 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) = (int)(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); - struct CNAME(ifreq) *pfreqend = (struct CNAME(ifreq) *)((char *)pfreq - + ifc.CNAME(ifc_len)); - while (pfreq < pfreqend) { - if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0) { - PyObject *name = PyUnicode_FromString (pfreq->CNAME(ifr_name)); - - if (!PySequence_Contains (result, name)) - PyList_Append (result, name); - Py_XDECREF (name); - - prev_name = pfreq->CNAME(ifr_name); - } - -#if !HAVE_SOCKADDR_SA_LEN - ++pfreq; -#else - /* On some platforms, the ifreq struct can *grow*(!) if the socket address - is very long. Mac OS X is such a platform. */ - { - size_t len = sizeof (struct CNAME(ifreq)); - if (pfreq->ifr_addr.sa_len > sizeof (struct sockaddr)) - len = len - sizeof (struct sockaddr) + pfreq->ifr_addr.sa_len; - pfreq = (struct CNAME(ifreq) *)((char *)pfreq + len); - } -#endif - } - - free (ifc.CNAME(ifc_buf)); - close (fd); -#endif /* HAVE_SIOCGIFCONF */ - - return result; -} - -/* -- gateways() ------------------------------------------------------------ */ - -static PyObject * -gateways (PyObject *self) -{ - PyObject *result, *defaults; - -#if defined(WIN32) - /* .. Win32 ............................................................... */ - - /* We try to access GetIPForwardTable2() and FreeMibTable() through - function pointers so that this code will still run on machines - running Windows versions prior to Vista. On those systems, we - fall back to the older GetIPForwardTable() API (and can only find - IPv4 gateways as a result). - - We also fall back to the older API if the newer code fails for - some reason. */ - - HANDLE hIpHelper; - typedef NTSTATUS (WINAPI *PGETIPFORWARDTABLE2)(ADDRESS_FAMILY Family, - PMIB_IPFORWARD_TABLE2 *pTable); - typedef VOID (WINAPI *PFREEMIBTABLE)(PVOID Memory); - - PGETIPFORWARDTABLE2 pGetIpForwardTable2; - PFREEMIBTABLE pFreeMibTable; - - hIpHelper = GetModuleHandle (TEXT("iphlpapi.dll")); - - result = NULL; - pGetIpForwardTable2 = (PGETIPFORWARDTABLE2) - GetProcAddress (hIpHelper, "GetIpForwardTable2"); - pFreeMibTable = (PFREEMIBTABLE) - GetProcAddress (hIpHelper, "FreeMibTable"); - - if (pGetIpForwardTable2) { - PMIB_IPFORWARD_TABLE2 table; - DWORD dwErr = pGetIpForwardTable2 (AF_UNSPEC, &table); - - if (dwErr == NO_ERROR) { - DWORD n; - ULONG lBestInetMetric = ~(ULONG)0, lBestInet6Metric = ~(ULONG)0; - - result = PyDict_New(); - defaults = PyDict_New(); - PyDict_SetItemString (result, "default", defaults); - Py_DECREF(defaults); - - /* This prevents a crash on PyPy */ - defaults = PyDict_GetItemString (result, "default"); - - for (n = 0; n < table->NumEntries; ++n) { - MIB_IFROW ifRow; - PyObject *ifname; - PyObject *gateway; - PyObject *isdefault; - PyObject *tuple, *deftuple = NULL; - WCHAR *pwcsName; - DWORD dwFamily = table->Table[n].NextHop.si_family; - BOOL bBest = FALSE; - - if (table->Table[n].DestinationPrefix.PrefixLength) - continue; - - switch (dwFamily) { - case AF_INET: - if (!table->Table[n].NextHop.Ipv4.sin_addr.s_addr) - continue; - break; - case AF_INET6: - if (memcmp (&table->Table[n].NextHop.Ipv6.sin6_addr, - &in6addr_any, - sizeof (struct in6_addr)) == 0) - continue; - break; - default: - continue; - } - - memset (&ifRow, 0, sizeof (ifRow)); - ifRow.dwIndex = table->Table[n].InterfaceIndex; - if (GetIfEntry (&ifRow) != NO_ERROR) - continue; - - gateway = string_from_address ((SOCKADDR *)&table->Table[n].NextHop, - sizeof (table->Table[n].NextHop)); - - if (!gateway) - continue; - - /* Strip the prefix from the interface name */ - pwcsName = ifRow.wszName; - if (_wcsnicmp (L"\\DEVICE\\TCPIP_", pwcsName, 14) == 0) - pwcsName += 14; - - switch (dwFamily) { - case AF_INET: - bBest = table->Table[n].Metric < lBestInetMetric; - lBestInetMetric = table->Table[n].Metric; - break; - case AF_INET6: - bBest = table->Table[n].Metric < lBestInet6Metric; - lBestInet6Metric = table->Table[n].Metric; - break; - } - - ifname = PyUnicode_FromUnicode (pwcsName, wcslen (pwcsName)); - isdefault = bBest ? Py_True : Py_False; - - tuple = PyTuple_Pack (3, gateway, ifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, gateway, ifname); - - Py_DECREF (gateway); - Py_DECREF (ifname); - - if (tuple && !add_to_family (result, dwFamily, tuple)) { - Py_DECREF (deftuple); - Py_DECREF (result); - free (table); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (dwFamily); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - - pFreeMibTable (table); - } - } - - if (!result) { - PMIB_IPFORWARDTABLE table = NULL; - DWORD dwRet; - DWORD dwSize = 0; - DWORD n; - DWORD dwBestMetric = ~(DWORD)0; - - do { - dwRet = GetIpForwardTable (table, &dwSize, FALSE); - - if (dwRet == ERROR_INSUFFICIENT_BUFFER) { - PMIB_IPFORWARDTABLE tbl = (PMIB_IPFORWARDTABLE)realloc (table, dwSize); - - if (!tbl) { - free (table); - PyErr_NoMemory(); - return NULL; - } - - table = tbl; - } - } while (dwRet == ERROR_INSUFFICIENT_BUFFER); - - if (dwRet != NO_ERROR) { - free (table); - PyErr_SetFromWindowsErr (dwRet); - return NULL; - } - - result = PyDict_New(); - defaults = PyDict_New(); - PyDict_SetItemString (result, "default", defaults); - Py_DECREF(defaults); - - /* This prevents a crash on PyPy */ - defaults = PyDict_GetItemString (result, "default"); - - for (n = 0; n < table->dwNumEntries; ++n) { - MIB_IFROW ifRow; - PyObject *ifname; - PyObject *gateway; - PyObject *isdefault; - PyObject *tuple, *deftuple = NULL; - DWORD dwGateway; - char gwbuf[16]; - WCHAR *pwcsName; - BOOL bBest; - - if (table->table[n].dwForwardDest - || !table->table[n].dwForwardNextHop - || table->table[n].dwForwardType != MIB_IPROUTE_TYPE_INDIRECT) - continue; - - memset (&ifRow, 0, sizeof (ifRow)); - ifRow.dwIndex = table->table[n].dwForwardIfIndex; - if (GetIfEntry (&ifRow) != NO_ERROR) - continue; - - dwGateway = ntohl (table->table[n].dwForwardNextHop); - - sprintf (gwbuf, "%u.%u.%u.%u", - (dwGateway >> 24) & 0xff, - (dwGateway >> 16) & 0xff, - (dwGateway >> 8) & 0xff, - dwGateway & 0xff); - - /* Strip the prefix from the interface name */ - pwcsName = ifRow.wszName; - 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 = PyUnicode_FromString (gwbuf); - isdefault = bBest ? Py_True : Py_False; - - tuple = PyTuple_Pack (3, gateway, ifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, gateway, ifname); - - Py_DECREF (gateway); - Py_DECREF (ifname); - - if (tuple && !add_to_family (result, AF_INET, tuple)) { - Py_DECREF (deftuple); - Py_DECREF (result); - free (table); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (AF_INET); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - } -#elif defined(HAVE_PF_NETLINK) - /* .. Linux (PF_NETLINK socket) ........................................... */ - - /* PF_NETLINK is pretty poorly documented and it looks to be quite easy to - get wrong. This *appears* to be the right way to do it, even though a - lot of the code out there on the 'Net is very different! */ - - struct routing_msg { - struct nlmsghdr hdr; - struct rtmsg rt; - char data[0]; - } *pmsg, *msgbuf; - int s; - int seq = 0; - ssize_t ret; - struct sockaddr_nl sanl; - static const struct sockaddr_nl sanl_kernel = { .nl_family = AF_NETLINK }; - socklen_t sanl_len; - int pagesize = getpagesize(); - 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(); - PyDict_SetItemString (result, "default", defaults); - Py_DECREF (defaults); - - /* This prevents a crash on PyPy */ - defaults = PyDict_GetItemString (result, "default"); - - msgbuf = (struct routing_msg *)malloc (bufsize); - - if (!msgbuf) { - PyErr_NoMemory (); - Py_DECREF (result); - return NULL; - } - - s = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - - if (s < 0) { - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - return NULL; - } - - sanl.nl_family = AF_NETLINK; - sanl.nl_groups = 0; - sanl.nl_pid = 0; - - if (bind (s, (struct sockaddr *)&sanl, sizeof (sanl)) < 0) { - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - sanl_len = sizeof (sanl); - if (getsockname (s, (struct sockaddr *)&sanl, &sanl_len) < 0) { - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - do { - interrupted = 0; - - pmsg = msgbuf; - memset (pmsg, 0, sizeof (struct routing_msg)); - pmsg->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - pmsg->hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; - pmsg->hdr.nlmsg_seq = ++seq; - pmsg->hdr.nlmsg_type = RTM_GETROUTE; - pmsg->hdr.nlmsg_pid = 0; - - pmsg->rt.rtm_family = 0; - - if (sendto (s, pmsg, pmsg->hdr.nlmsg_len, 0, - (struct sockaddr *)&sanl_kernel, sizeof(sanl_kernel)) < 0) { - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - do { - struct sockaddr_nl sanl_from; - struct iovec iov = { msgbuf, bufsize }; - struct msghdr msghdr = { - &sanl_from, - sizeof(sanl_from), - &iov, - 1, - NULL, - 0, - 0 - }; - int nllen; - - ret = recvmsg (s, &msghdr, 0); - - if (msghdr.msg_flags & MSG_TRUNC) { - PyErr_SetString (PyExc_OSError, "netlink message truncated"); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - if (ret < 0) { - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - nllen = ret; - pmsg = msgbuf; - while (NLMSG_OK (&pmsg->hdr, nllen)) { - void *dst = NULL; - void *gw = NULL; - 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) - goto next; - - /* This is only defined on Linux kernel versions 3.1 and higher */ -#ifdef NLM_F_DUMP_INTR - if (pmsg->hdr.nlmsg_flags & NLM_F_DUMP_INTR) { - /* The dump was interrupted by a signal; we need to go round again */ - interrupted = 1; - is_multi = 0; - break; - } -#endif - - is_multi = pmsg->hdr.nlmsg_flags & NLM_F_MULTI; - - if (pmsg->hdr.nlmsg_type == NLMSG_DONE) { - is_multi = interrupted = 0; - break; - } - - if (pmsg->hdr.nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *perr = (struct nlmsgerr *)&pmsg->rt; - errno = -perr->error; - PyErr_SetFromErrno (PyExc_OSError); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - 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: - gw = RTA_DATA(attr); - break; - case RTA_DST: - dst = RTA_DATA(attr); - break; - case RTA_OIF: - ifndx = *(int *)RTA_DATA(attr); - break; - case RTA_PRIORITY: - priority = *(int *)RTA_DATA(attr); - break; - default: - break; - } - - attr = RTA_NEXT(attr, len); - } - - /* We're looking for gateways with no destination */ - if (!dst && gw && ifndx >= 0) { - char buffer[256]; - char ifnamebuf[IF_NAMESIZE]; - char *ifname; - const char *addr; - PyObject *pyifname; - PyObject *pyaddr; - PyObject *isdefault; - PyObject *tuple = NULL, *deftuple = NULL; - - ifname = if_indextoname (ifndx, ifnamebuf); - - if (!ifname) - goto next; - - addr = inet_ntop (pmsg->rt.rtm_family, gw, buffer, sizeof (buffer)); - - if (!addr) - goto next; - - /* We set isdefault to True if this route came from the main table; - this should correspond with the way most people set up alternate - 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 = PyUnicode_FromString (ifname); - pyaddr = PyUnicode_FromString (buffer); - - tuple = PyTuple_Pack (3, pyaddr, pyifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, pyaddr, pyifname); - - Py_DECREF (pyaddr); - Py_DECREF (pyifname); - - if (tuple && !add_to_family (result, pmsg->rt.rtm_family, tuple)) { - Py_XDECREF (deftuple); - Py_DECREF (result); - free (msgbuf); - close (s); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (pmsg->rt.rtm_family); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - - next: - pmsg = (struct routing_msg *)NLMSG_NEXT(&pmsg->hdr, nllen); - } - } while (is_multi); - } while (interrupted); - - free (msgbuf); - close (s); -#elif defined(HAVE_SYSCTL_CTL_NET) - /* .. UNIX, via sysctl() .................................................. */ - - int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_FLAGS, - RTF_UP | RTF_GATEWAY }; - size_t len; - char *buffer = NULL, *ptr, *end; - int ret; - char ifnamebuf[IF_NAMESIZE]; - char *ifname; - - result = PyDict_New(); - defaults = PyDict_New(); - PyDict_SetItemString (result, "default", defaults); - Py_DECREF (defaults); - - /* This prevents a crash on PyPy */ - defaults = PyDict_GetItemString (result, "default"); - - /* Remembering that the routing table may change while we're reading it, - we need to do this in a loop until we succeed. */ - do { - if (sysctl (mib, 6, 0, &len, 0, 0) < 0) { - PyErr_SetFromErrno (PyExc_OSError); - free (buffer); - Py_DECREF (result); - return NULL; - } - - ptr = realloc(buffer, len); - if (!ptr) { - PyErr_NoMemory(); - free (buffer); - Py_DECREF (result); - return NULL; - } - - buffer = ptr; - - ret = sysctl (mib, 6, buffer, &len, 0, 0); - } while (ret != 0 || errno == ENOMEM || errno == EINTR); - - if (ret < 0) { - PyErr_SetFromErrno (PyExc_OSError); - free (buffer); - Py_DECREF (result); - return NULL; - } - - ptr = buffer; - end = buffer + len; - - while (ptr + sizeof (struct rt_msghdr) <= end) { - struct rt_msghdr *msg = (struct rt_msghdr *)ptr; - char *msgend = (char *)msg + msg->rtm_msglen; - int addrs = msg->rtm_addrs; - int addr = RTA_DST; - PyObject *pyifname; - - if (msgend > end) - break; - - ifname = if_indextoname (msg->rtm_index, ifnamebuf); - - if (!ifname) { - ptr = msgend; - continue; - } - - pyifname = PyUnicode_FromString (ifname); - - ptr = (char *)(msg + 1); - while (ptr + sizeof (struct sockaddr) <= msgend && addrs) { - struct sockaddr *sa = (struct sockaddr *)ptr; - int len = SA_LEN(sa); - - if (!len) - len = 4; - else - len = (len + 3) & ~3; - - if (ptr + len > msgend) - break; - - while (!(addrs & addr)) - addr <<= 1; - - addrs &= ~addr; - - if (addr == RTA_DST) { - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - if (sin->sin_addr.s_addr != INADDR_ANY) - break; -#ifdef AF_INET6 - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - if (memcmp (&sin6->sin6_addr, &in6addr_any, sizeof (in6addr_any)) != 0) - break; -#endif - } else { - break; - } - } - - if (addr == RTA_GATEWAY) { - char buffer[256]; - PyObject *tuple = NULL; - PyObject *deftuple = NULL; - - if (string_from_sockaddr (sa, buffer, sizeof(buffer)) == 0) { - PyObject *pyaddr = PyUnicode_FromString (buffer); -#ifdef RTF_IFSCOPE - PyObject *isdefault = PyBool_FromLong (!(msg->rtm_flags & RTF_IFSCOPE)); -#else - Py_INCREF(Py_True); - PyObject *isdefault = Py_True; -#endif - tuple = PyTuple_Pack (3, pyaddr, pyifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, pyaddr, pyifname); - - Py_DECREF (pyaddr); - Py_DECREF (isdefault); - } - - if (tuple && !add_to_family (result, sa->sa_family, tuple)) { - Py_DECREF (deftuple); - Py_DECREF (result); - Py_DECREF (pyifname); - free (buffer); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (sa->sa_family); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - - /* These are aligned on a 4-byte boundary */ - ptr += len; - } - - Py_DECREF (pyifname); - ptr = msgend; - } - - free (buffer); -#elif defined(HAVE_PF_ROUTE) - /* .. UNIX, via PF_ROUTE socket ........................................... */ - - /* The PF_ROUTE code will only retrieve gateway information for AF_INET and - AF_INET6. This is because it would need to loop through all possible - values, and the messages it needs to send in each case are potentially - different. It is also very likely to return a maximum of one gateway - in each case (since we can't read the entire routing table this way, we - can only ask about routes). */ - - int pagesize = getpagesize(); - int bufsize = pagesize < 8192 ? 8192 : pagesize; - struct rt_msghdr *pmsg; - int s; - int seq = 0; - int pid = getpid(); - ssize_t ret; - struct sockaddr_in *sin_dst, *sin_netmask; - struct sockaddr_dl *sdl_ifp; - struct sockaddr_in6 *sin6_dst; - size_t msglen; - char ifnamebuf[IF_NAMESIZE]; - char *ifname; - int skip; - - result = PyDict_New(); - defaults = PyDict_New(); - PyDict_SetItemString (result, "default", defaults); - Py_DECREF(defaults); - - pmsg = (struct rt_msghdr *)malloc (bufsize); - - if (!pmsg) { - PyErr_NoMemory(); - return NULL; - } - - s = socket (PF_ROUTE, SOCK_RAW, 0); - - if (s < 0) { - PyErr_SetFromErrno (PyExc_OSError); - free (pmsg); - return NULL; - } - - msglen = (sizeof (struct rt_msghdr) - + 2 * sizeof (struct sockaddr_in) - + sizeof (struct sockaddr_dl)); - memset (pmsg, 0, msglen); - - /* AF_INET first */ - pmsg->rtm_msglen = msglen; - pmsg->rtm_type = RTM_GET; - pmsg->rtm_index = 0; - pmsg->rtm_flags = RTF_UP | RTF_GATEWAY; - pmsg->rtm_version = RTM_VERSION; - pmsg->rtm_seq = ++seq; - pmsg->rtm_pid = 0; - pmsg->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP; - - sin_dst = (struct sockaddr_in *)(pmsg + 1); - sin_netmask = (struct sockaddr_in *)(sin_dst + 1); - sdl_ifp = (struct sockaddr_dl *)(sin_netmask + 1); - - sin_dst->sin_family = AF_INET; - sin_netmask->sin_family = AF_INET; - sdl_ifp->sdl_family = AF_LINK; - -#if HAVE_SOCKADDR_SA_LEN - sin_dst->sin_len = sizeof (struct sockaddr_in); - sin_netmask->sin_len = sizeof (struct sockaddr_in); - sdl_ifp->sdl_len = sizeof (struct sockaddr_dl); -#endif - - skip = 0; - if (send (s, pmsg, msglen, 0) < 0) { - if (errno == ESRCH) - skip = 1; - else { - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - } - - while (!skip && !(pmsg->rtm_flags & RTF_DONE)) { - char *ptr; - char *msgend; - int addrs; - int addr; - struct sockaddr_in *dst = NULL; - struct sockaddr_in *gw = NULL; - struct sockaddr_dl *ifp = NULL; - PyObject *tuple = NULL; - PyObject *deftuple = NULL; - - do { - ret = recv (s, pmsg, bufsize, 0); - } while ((ret < 0 && errno == EINTR) - || (ret > 0 && (pmsg->rtm_seq != seq || pmsg->rtm_pid != pid))); - - if (ret < 0) { - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - - if (pmsg->rtm_errno != 0) { - if (pmsg->rtm_errno == ESRCH) - skip = 1; - else { - errno = pmsg->rtm_errno; - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - } - - if (skip) - break; - - ptr = (char *)(pmsg + 1); - msgend = (char *)pmsg + pmsg->rtm_msglen; - addrs = pmsg->rtm_addrs; - addr = RTA_DST; - while (ptr + sizeof (struct sockaddr) <= msgend && addrs) { - struct sockaddr *sa = (struct sockaddr *)ptr; - int len = SA_LEN(sa); - - if (!len) - len = 4; - else - len = (len + 3) & ~3; - - if (ptr + len > msgend) - break; - - while (!(addrs & addr)) - addr <<= 1; - - addrs &= ~addr; - - switch (addr) { - case RTA_DST: - dst = (struct sockaddr_in *)sa; - break; - case RTA_GATEWAY: - gw = (struct sockaddr_in *)sa; - break; - case RTA_IFP: - ifp = (struct sockaddr_dl *)sa; - break; - } - - ptr += len; - } - - if ((dst && dst->sin_family != AF_INET) - || (gw && gw->sin_family != AF_INET) - || (ifp && ifp->sdl_family != AF_LINK)) { - dst = gw = NULL; - ifp = NULL; - } - - if (dst && dst->sin_addr.s_addr == INADDR_ANY) - dst = NULL; - - if (!dst && gw && ifp) { - char buffer[256]; - - if (ifp->sdl_index) - ifname = if_indextoname (ifp->sdl_index, ifnamebuf); - else { - memcpy (ifnamebuf, ifp->sdl_data, ifp->sdl_nlen); - ifnamebuf[ifp->sdl_nlen] = '\0'; - ifname = ifnamebuf; - } - - if (string_from_sockaddr ((struct sockaddr *)gw, - buffer, sizeof(buffer)) == 0) { - PyObject *pyifname = PyUnicode_FromString (ifname); - PyObject *pyaddr = PyUnicode_FromString (buffer); -#ifdef RTF_IFSCOPE - PyObject *isdefault = PyBool_FromLong (!(pmsg->rtm_flags & RTF_IFSCOPE)); -#else - PyObject *isdefault = Py_True; - Py_INCREF(isdefault); -#endif - - tuple = PyTuple_Pack (3, pyaddr, pyifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, pyaddr, pyifname); - - Py_DECREF (pyaddr); - Py_DECREF (pyifname); - Py_DECREF (isdefault); - } - - if (tuple && !add_to_family (result, AF_INET, tuple)) { - Py_DECREF (deftuple); - Py_DECREF (result); - free (pmsg); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (AF_INET); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - } - - /* The code below is very similar to, but not identical to, the code above. - We could probably refactor some of it, but take care---there are subtle - differences! */ - -#ifdef AF_INET6 - /* AF_INET6 now */ - msglen = (sizeof (struct rt_msghdr) - + sizeof (struct sockaddr_in6) - + sizeof (struct sockaddr_dl)); - memset (pmsg, 0, msglen); - - pmsg->rtm_msglen = msglen; - pmsg->rtm_type = RTM_GET; - pmsg->rtm_index = 0; - pmsg->rtm_flags = RTF_UP | RTF_GATEWAY; - pmsg->rtm_version = RTM_VERSION; - pmsg->rtm_seq = ++seq; - pmsg->rtm_pid = 0; - pmsg->rtm_addrs = RTA_DST | RTA_IFP; - - sin6_dst = (struct sockaddr_in6 *)(pmsg + 1); - sdl_ifp = (struct sockaddr_dl *)(sin6_dst + 1); - - sin6_dst->sin6_family = AF_INET6; - sin6_dst->sin6_addr = in6addr_any; - sdl_ifp->sdl_family = AF_LINK; - -#if HAVE_SOCKADDR_SA_LEN - sin6_dst->sin6_len = sizeof (struct sockaddr_in6); - sdl_ifp->sdl_len = sizeof (struct sockaddr_dl); -#endif - - skip = 0; - if (send (s, pmsg, msglen, 0) < 0) { - if (errno == ESRCH) - skip = 1; - else { - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - } - - while (!skip && !(pmsg->rtm_flags & RTF_DONE)) { - char *ptr; - char *msgend; - int addrs; - int addr; - struct sockaddr_in6 *dst = NULL; - struct sockaddr_in6 *gw = NULL; - struct sockaddr_dl *ifp = NULL; - PyObject *tuple = NULL; - PyObject *deftuple = NULL; - - do { - ret = recv (s, pmsg, bufsize, 0); - } while ((ret < 0 && errno == EINTR) - || (ret > 0 && (pmsg->rtm_seq != seq || pmsg->rtm_pid != pid))); - - if (ret < 0) { - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - - if (pmsg->rtm_errno != 0) { - if (pmsg->rtm_errno == ESRCH) - skip = 1; - else { - errno = pmsg->rtm_errno; - PyErr_SetFromErrno (PyExc_OSError); - close (s); - free (pmsg); - return NULL; - } - } - - if (skip) - break; - - ptr = (char *)(pmsg + 1); - msgend = (char *)pmsg + pmsg->rtm_msglen; - addrs = pmsg->rtm_addrs; - addr = RTA_DST; - while (ptr + sizeof (struct sockaddr) <= msgend && addrs) { - struct sockaddr *sa = (struct sockaddr *)ptr; - int len = SA_LEN(sa); - - if (!len) - len = 4; - else - len = (len + 3) & ~3; - - if (ptr + len > msgend) - break; - - while (!(addrs & addr)) - addr <<= 1; - - addrs &= ~addr; - - switch (addr) { - case RTA_DST: - dst = (struct sockaddr_in6 *)sa; - break; - case RTA_GATEWAY: - gw = (struct sockaddr_in6 *)sa; - break; - case RTA_IFP: - ifp = (struct sockaddr_dl *)sa; - break; - } - - ptr += len; - } - - if ((dst && dst->sin6_family != AF_INET6) - || (gw && gw->sin6_family != AF_INET6) - || (ifp && ifp->sdl_family != AF_LINK)) { - dst = gw = NULL; - ifp = NULL; - } - - if (dst && memcmp (&dst->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) - dst = NULL; - - if (!dst && gw && ifp) { - char buffer[256]; - - if (ifp->sdl_index) - ifname = if_indextoname (ifp->sdl_index, ifnamebuf); - else { - memcpy (ifnamebuf, ifp->sdl_data, ifp->sdl_nlen); - ifnamebuf[ifp->sdl_nlen] = '\0'; - ifname = ifnamebuf; - } - - if (string_from_sockaddr ((struct sockaddr *)gw, - buffer, sizeof(buffer)) == 0) { - PyObject *pyifname = PyUnicode_FromString (ifname); - PyObject *pyaddr = PyUnicode_FromString (buffer); -#ifdef RTF_IFSCOPE - PyObject *isdefault = PyBool_FromLong (!(pmsg->rtm_flags & RTF_IFSCOPE)); -#else - PyObject *isdefault = Py_True; - Py_INCREF (isdefault); -#endif - - tuple = PyTuple_Pack (3, pyaddr, pyifname, isdefault); - - if (PyObject_IsTrue (isdefault)) - deftuple = PyTuple_Pack (2, pyaddr, pyifname); - - Py_DECREF (pyaddr); - Py_DECREF (pyifname); - Py_DECREF (isdefault); - } - - if (tuple && !add_to_family (result, AF_INET6, tuple)) { - Py_DECREF (deftuple); - Py_DECREF (result); - free (pmsg); - return NULL; - } - - if (deftuple) { - PyObject *pyfamily = PyInt_FromLong (AF_INET6); - - PyDict_SetItem (defaults, pyfamily, deftuple); - - Py_DECREF (pyfamily); - Py_DECREF (deftuple); - } - } - } -#endif /* AF_INET6 */ - - free (pmsg); -#else - /* If we don't know how to implement this on your platform, we raise an - exception. */ - PyErr_SetString (PyExc_OSError, - "Unable to obtain gateway information on your platform."); -#endif - - return result; -} - -/* -- Python Module --------------------------------------------------------- */ - -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." }, - { "gateways", (PyCFunction)gateways, METH_NOARGS, - "Obtain a list of the gateways on this machine.\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 tuples of the\n" -"format (<address>, <interface>, <is_default>).\n" -"\n" -"There is also a special entry with the key 'default', which you can use\n" -"to quickly obtain the default gateway for a particular address family.\n" -"\n" -"There may in general be multiple gateways; different address\n" -"families may have different gateway settings (e.g. AF_INET vs AF_INET6)\n" -"and on some systems it's also possible to have interface-specific\n" -"default gateways.\n" }, - { NULL, NULL, 0, NULL } -}; - -MODULE_DEF("netifaces", NULL, methods); - -MODULE_INIT(netifaces) -{ - PyObject *address_family_dict; - PyObject *m; - -#ifdef WIN32 - WSADATA wsad; - - WSAStartup(MAKEWORD (2, 2), &wsad); -#endif - - MODULE_CREATE(m, "netifaces", NULL, methods); - if (!m) - return MODULE_ERROR; - - /* Address families (auto-detect using #ifdef) */ - address_family_dict = PyDict_New(); -#ifdef AF_UNSPEC - PyModule_AddIntConstant (m, "AF_UNSPEC", AF_UNSPEC); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNSPEC), - PyUnicode_FromString("AF_UNSPEC")); -#endif -#ifdef AF_UNIX - PyModule_AddIntConstant (m, "AF_UNIX", AF_UNIX); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNIX), - PyUnicode_FromString("AF_UNIX")); -#endif -#ifdef AF_FILE - PyModule_AddIntConstant (m, "AF_FILE", AF_FILE); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FILE), - PyUnicode_FromString("AF_FILE")); -#endif -#ifdef AF_INET - PyModule_AddIntConstant (m, "AF_INET", AF_INET); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET), - PyUnicode_FromString("AF_INET")); -#endif -#ifdef AF_AX25 - PyModule_AddIntConstant (m, "AF_AX25", AF_AX25); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_AX25), - PyUnicode_FromString("AF_AX25")); -#endif -#ifdef AF_IMPLINK - PyModule_AddIntConstant (m, "AF_IMPLINK", AF_IMPLINK); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IMPLINK), - PyUnicode_FromString("AF_IMPLINK")); -#endif -#ifdef AF_PUP - PyModule_AddIntConstant (m, "AF_PUP", AF_PUP); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PUP), - PyUnicode_FromString("AF_PUP")); -#endif -#ifdef AF_CHAOS - PyModule_AddIntConstant (m, "AF_CHAOS", AF_CHAOS); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CHAOS), - PyUnicode_FromString("AF_CHAOS")); -#endif -#ifdef AF_NS - PyModule_AddIntConstant (m, "AF_NS", AF_NS); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NS), - PyUnicode_FromString("AF_NS")); -#endif -#ifdef AF_ISO - PyModule_AddIntConstant (m, "AF_ISO", AF_ISO); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISO), - PyUnicode_FromString("AF_ISO")); -#endif -#ifdef AF_ECMA - PyModule_AddIntConstant (m, "AF_ECMA", AF_ECMA); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECMA), - PyUnicode_FromString("AF_ECMA")); -#endif -#ifdef AF_DATAKIT - PyModule_AddIntConstant (m, "AF_DATAKIT", AF_DATAKIT); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DATAKIT), - PyUnicode_FromString("AF_DATAKIT")); -#endif -#ifdef AF_CCITT - PyModule_AddIntConstant (m, "AF_CCITT", AF_CCITT); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CCITT), - PyUnicode_FromString("AF_CCITT")); -#endif -#ifdef AF_SNA - PyModule_AddIntConstant (m, "AF_SNA", AF_SNA); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA), - PyUnicode_FromString("AF_SNA")); -#endif -#ifdef AF_DECnet - PyModule_AddIntConstant (m, "AF_DECnet", AF_DECnet); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DECnet), - PyUnicode_FromString("AF_DECnet")); -#endif -#ifdef AF_DLI - PyModule_AddIntConstant (m, "AF_DLI", AF_DLI); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DLI), - PyUnicode_FromString("AF_DLI")); -#endif -#ifdef AF_LAT - PyModule_AddIntConstant (m, "AF_LAT", AF_LAT); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LAT), - PyUnicode_FromString("AF_LAT")); -#endif -#ifdef AF_HYLINK - PyModule_AddIntConstant (m, "AF_HYLINK", AF_HYLINK); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_HYLINK), - PyUnicode_FromString("AF_HYLINK")); -#endif -#ifdef AF_APPLETALK - PyModule_AddIntConstant (m, "AF_APPLETALK", AF_APPLETALK); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_APPLETALK), - PyUnicode_FromString("AF_APPLETALK")); -#endif -#ifdef AF_ROUTE - PyModule_AddIntConstant (m, "AF_ROUTE", AF_ROUTE); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROUTE), - PyUnicode_FromString("AF_ROUTE")); -#endif -#ifdef AF_LINK - PyModule_AddIntConstant (m, "AF_LINK", AF_LINK); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LINK), - PyUnicode_FromString("AF_LINK")); -#endif -#ifdef AF_PACKET - PyModule_AddIntConstant (m, "AF_PACKET", AF_PACKET); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PACKET), - PyUnicode_FromString("AF_PACKET")); -#endif -#ifdef AF_COIP - PyModule_AddIntConstant (m, "AF_COIP", AF_COIP); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_COIP), - PyUnicode_FromString("AF_COIP")); -#endif -#ifdef AF_CNT - PyModule_AddIntConstant (m, "AF_CNT", AF_CNT); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CNT), - PyUnicode_FromString("AF_CNT")); -#endif -#ifdef AF_IPX - PyModule_AddIntConstant (m, "AF_IPX", AF_IPX); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IPX), - PyUnicode_FromString("AF_IPX")); -#endif -#ifdef AF_SIP - PyModule_AddIntConstant (m, "AF_SIP", AF_SIP); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SIP), - PyUnicode_FromString("AF_SIP")); -#endif -#ifdef AF_NDRV - PyModule_AddIntConstant (m, "AF_NDRV", AF_NDRV); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NDRV), - PyUnicode_FromString("AF_NDRV")); -#endif -#ifdef AF_ISDN - PyModule_AddIntConstant (m, "AF_ISDN", AF_ISDN); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISDN), - PyUnicode_FromString("AF_ISDN")); -#endif -#ifdef AF_INET6 - PyModule_AddIntConstant (m, "AF_INET6", AF_INET6); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET6), - PyUnicode_FromString("AF_INET6")); -#endif -#ifdef AF_NATM - PyModule_AddIntConstant (m, "AF_NATM", AF_NATM); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NATM), - PyUnicode_FromString("AF_NATM")); -#endif -#ifdef AF_SYSTEM - PyModule_AddIntConstant (m, "AF_SYSTEM", AF_SYSTEM); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SYSTEM), - PyUnicode_FromString("AF_SYSTEM")); -#endif -#ifdef AF_NETBIOS - PyModule_AddIntConstant (m, "AF_NETBIOS", AF_NETBIOS); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBIOS), - PyUnicode_FromString("AF_NETBIOS")); -#endif -#ifdef AF_NETBEUI - PyModule_AddIntConstant (m, "AF_NETBEUI", AF_NETBEUI); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBEUI), - PyUnicode_FromString("AF_NETBEUI")); -#endif -#ifdef AF_PPP - PyModule_AddIntConstant (m, "AF_PPP", AF_PPP); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPP), - PyUnicode_FromString("AF_PPP")); -#endif -#ifdef AF_ATM - PyModule_AddIntConstant (m, "AF_ATM", AF_ATM); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATM), - PyUnicode_FromString("AF_ATM")); -#endif -#ifdef AF_ATMPVC - PyModule_AddIntConstant (m, "AF_ATMPVC", AF_ATMPVC); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMPVC), - PyUnicode_FromString("AF_ATMPVC")); -#endif -#ifdef AF_ATMSVC - PyModule_AddIntConstant (m, "AF_ATMSVC", AF_ATMSVC); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMSVC), - PyUnicode_FromString("AF_ATMSVC")); -#endif -#ifdef AF_NETGRAPH - PyModule_AddIntConstant (m, "AF_NETGRAPH", AF_NETGRAPH); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETGRAPH), - PyUnicode_FromString("AF_NETGRAPH")); -#endif -#ifdef AF_VOICEVIEW - PyModule_AddIntConstant (m, "AF_VOICEVIEW", AF_VOICEVIEW); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_VOICEVIEW), - PyUnicode_FromString("AF_VOICEVIEW")); -#endif -#ifdef AF_FIREFOX - PyModule_AddIntConstant (m, "AF_FIREFOX", AF_FIREFOX); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FIREFOX), - PyUnicode_FromString("AF_FIREFOX")); -#endif -#ifdef AF_UNKNOWN1 - PyModule_AddIntConstant (m, "AF_UNKNOWN1", AF_UNKNOWN1); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNKNOWN1), - PyUnicode_FromString("AF_UNKNOWN1")); -#endif -#ifdef AF_BAN - PyModule_AddIntConstant (m, "AF_BAN", AF_BAN); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BAN), - PyUnicode_FromString("AF_BAN")); -#endif -#ifdef AF_CLUSTER - PyModule_AddIntConstant (m, "AF_CLUSTER", AF_CLUSTER); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CLUSTER), - PyUnicode_FromString("AF_CLUSTER")); -#endif -#ifdef AF_12844 - PyModule_AddIntConstant (m, "AF_12844", AF_12844); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_12844), - PyUnicode_FromString("AF_12844")); -#endif -#ifdef AF_IRDA - PyModule_AddIntConstant (m, "AF_IRDA", AF_IRDA); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IRDA), - PyUnicode_FromString("AF_IRDA")); -#endif -#ifdef AF_NETDES - PyModule_AddIntConstant (m, "AF_NETDES", AF_NETDES); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETDES), - PyUnicode_FromString("AF_NETDES")); -#endif -#ifdef AF_NETROM - PyModule_AddIntConstant (m, "AF_NETROM", AF_NETROM); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETROM), - PyUnicode_FromString("AF_NETROM")); -#endif -#ifdef AF_BRIDGE - PyModule_AddIntConstant (m, "AF_BRIDGE", AF_BRIDGE); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BRIDGE), - PyUnicode_FromString("AF_BRIDGE")); -#endif -#ifdef AF_X25 - PyModule_AddIntConstant (m, "AF_X25", AF_X25); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_X25), - PyUnicode_FromString("AF_X25")); -#endif -#ifdef AF_ROSE - PyModule_AddIntConstant (m, "AF_ROSE", AF_ROSE); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROSE), - PyUnicode_FromString("AF_ROSE")); -#endif -#ifdef AF_SECURITY - PyModule_AddIntConstant (m, "AF_SECURITY", AF_SECURITY); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SECURITY), - PyUnicode_FromString("AF_SECURITY")); -#endif -#ifdef AF_KEY - PyModule_AddIntConstant (m, "AF_KEY", AF_KEY); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_KEY), - PyUnicode_FromString("AF_KEY")); -#endif -#ifdef AF_NETLINK - PyModule_AddIntConstant (m, "AF_NETLINK", AF_NETLINK); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETLINK), - PyUnicode_FromString("AF_NETLINK")); -#endif -#ifdef AF_ASH - PyModule_AddIntConstant (m, "AF_ASH", AF_ASH); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ASH), - PyUnicode_FromString("AF_ASH")); -#endif -#ifdef AF_ECONET - PyModule_AddIntConstant (m, "AF_ECONET", AF_ECONET); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECONET), - PyUnicode_FromString("AF_ECONET")); -#endif -#ifdef AF_SNA - PyModule_AddIntConstant (m, "AF_SNA", AF_SNA); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA), - PyUnicode_FromString("AF_SNA")); -#endif -#ifdef AF_PPPOX - PyModule_AddIntConstant (m, "AF_PPPOX", AF_PPPOX); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPPOX), - PyUnicode_FromString("AF_PPPOX")); -#endif -#ifdef AF_WANPIPE - PyModule_AddIntConstant (m, "AF_WANPIPE", AF_WANPIPE); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_WANPIPE), - PyUnicode_FromString("AF_WANPIPE")); -#endif -#ifdef AF_BLUETOOTH - PyModule_AddIntConstant (m, "AF_BLUETOOTH", AF_BLUETOOTH); - PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BLUETOOTH), - PyUnicode_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 -#undef STR -#undef _STR -#define _STR(x) #x -#define STR(x) _STR(x) - - PyModule_AddStringConstant(m, "version", STR(NETIFACES_VERSION)); - - MODULE_RETURN(m); -} diff --git a/pypi_windows_packages.bat b/pypi_windows_packages.bat deleted file mode 100644 index 50cf652..0000000 --- a/pypi_windows_packages.bat +++ /dev/null @@ -1,6 +0,0 @@ -C:\Python27\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
-C:\Python34\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
-C:\Python35\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
-C:\Python27_32\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
-C:\Python34_32\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
-C:\Python35_32\python.exe setup.py clean bdist_egg bdist_wininst bdist_wheel %*
diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 861a9f5..0000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[egg_info] -tag_build = -tag_date = 0 -tag_svn_revision = 0 - diff --git a/setup.py b/setup.py deleted file mode 100644 index 80ae7ae..0000000 --- a/setup.py +++ /dev/null @@ -1,596 +0,0 @@ -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 - -if sys.version_info[0] == 2: - def output(*args, **kwargs): - end = kwargs.get('end', '\n') - f = kwargs.get('file', sys.stdout) - f.write(' '.join(str(a) for a in args)) - f.write(end) -else: - try: - import builtins - except ImportError: - import __builtin__ - builtins = __builtin__ - - output = getattr(builtins, 'print', lambda x: True) - -__version__ = "0.10.6" - -# Disable hard links, otherwise building distributions fails on OS X -try: - del os.link -except: - pass - -# 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 = [] - -def_macros.append(("NETIFACES_VERSION", __version__)) - -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=False, 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') - thefile.write(contents) - thefile.close() - - 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 LinkError: - 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, 'rb') - try: - results = pickle.load(myfile) - finally: - myfile.close() - else: - results = {} - - self.conftestidx = 0 - - output("checking for getifaddrs...", end='') - - 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: - output("found. %s" % cached) - self.compiler.define_macro('HAVE_GETIFADDRS', 1) - else: - output("not found. %s" % cached) - - results['have_getifaddrs'] = result - - output("checking for getnameinfo...", end='') - - 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: - output("found. %s" % cached) - self.compiler.define_macro('HAVE_GETNAMEINFO', 1) - else: - output("not found. %s" % cached) - - 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='') - - result = results.get('have_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, 'conftest3.out') - self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC) - - 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: - output("%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: - output("not found. %s" % cached) - - results['have_socket_ioctls'] = result - - output("checking for optional header files...", end='') - - 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): - result.append(header) - - if result: - output("%s. %s" % (' '.join(result), cached)) - for header in result: - macro = header.upper().replace('.', '_').replace('/', '_') - self.compiler.define_macro('HAVE_%s' % macro, 1) - else: - output("none found. %s" % cached) - - optional_headers = result - results['have_headers'] = result - - output("checking whether struct sockaddr has a length field...", end='') - - 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) - - if result: - output('yes. %s' % cached) - self.compiler.define_macro('HAVE_SOCKADDR_SA_LEN', 1) - else: - output('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. - output("checking which sockaddr_xxx structs are defined...", end='') - - result = results.get('have_sockaddrs', 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, 'conftest5.out') - self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC) - - 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): - result.append(sockaddr) - - if result: - output('%s. %s' % (' '.join(result), cached)) - for sockaddr in result: - self.compiler.define_macro('HAVE_SOCKADDR_%s' \ - % sockaddr.upper(), 1) - else: - output('none! %s' % cached) - - results['have_sockaddrs'] = result - - # Reading routing tables is very OS dependent; check for a few - # different approaches. - output("checking for routing socket support...", end='') - - result = results.get('have_pf_route', None) - if result is not None: - cached = '(cached)' - else: - cached = '' - - testrig = """ - #include <sys/types.h> - #include <sys/socket.h> - #include <net/route.h> - - int main (void) { - struct rt_msghdr msg; - int s = socket (PF_ROUTE, SOCK_RAW, 0); - return 0; - } - """ - - result = self.test_build(testrig) - - if result: - output('yes. %s' % cached) - self.compiler.define_macro('HAVE_PF_ROUTE', 1) - else: - output('no. %s' % cached) - - results['have_pf_route'] = result - - output("checking for sysctl(CTL_NET...) support...", end='') - - result = results.get('have_sysctl_ctl_net', None) - if result is not None: - cached = '(cached)' - else: - cached = '' - - testrig = """ - #include <sys/types.h> - #include <sys/socket.h> - #include <sys/sysctl.h> - #include <net/route.h> - - int main (void) { - int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, - RTF_UP | RTF_GATEWAY }; - return 0; - } - """ - - result = self.test_build(testrig) - - if result: - output('yes. %s' % cached) - self.compiler.define_macro('HAVE_SYSCTL_CTL_NET', 1) - else: - output('no. %s' % cached) - - results['have_sysctl_ctl_net'] = result - - output("checking for netlink support...", end='') - - result = results.get('have_pf_netlink', None) - if result is not None: - cached = '(cached)' - else: - cached = '' - - testrig = """ - #include <asm/types.h> - #include <sys/socket.h> - #include <linux/netlink.h> - #include <linux/rtnetlink.h> - - int main (void) { - int s = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - return 0; - } - """ - - result = self.test_build(testrig) - - if result: - output('yes. %s' % cached) - self.compiler.define_macro('HAVE_PF_NETLINK', 1) - else: - output('no. %s' % cached) - - results['have_pf_netlink'] = result - - if results['have_pf_netlink']: - output('will use netlink to read routing table') - elif results['have_sysctl_ctl_net']: - output('will use sysctl() to read routing table') - elif results['have_pf_route']: - output('will use routing socket to read routing table') - - # Save the results to our config.cache file - myfile = open(cache_file, 'wb') - 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 - -readme_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), - 'README.rst') -long_desc = open(readme_path, 'r').read() - -setup (name='netifaces', - version=__version__, - zip_safe=True, - description="Portable network interface information.", - license="MIT License", - long_description=long_desc, - author='Alastair Houghton', - author_email='alastair@alastairs-place.net', - url='https://bitbucket.org/al45tair/netifaces', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Topic :: System :: Networking', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.5', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - ], - ext_modules=[iface_mod]) diff --git a/test.py b/test.py deleted file mode 100644 index ccaba0e..0000000 --- a/test.py +++ /dev/null @@ -1,50 +0,0 @@ -import netifaces - -print('Found interfaces:') -for iface in netifaces.interfaces(): - print(' %s' % iface) - -print('') - -for iface in netifaces.interfaces(): - allAddrs = netifaces.ifaddresses(iface) - - print('Interface %s:' % iface) - - for family in allAddrs: - addrs = allAddrs[family] - fam_name = netifaces.address_families[family] - print(' Address family: %s' % fam_name) - for addr in addrs: - print(' Address : %s' % addr['addr']) - nmask = addr.get('netmask', None) - if nmask: - print(' Netmask : %s' % nmask) - bcast = addr.get('broadcast', None) - if bcast: - print(' Broadcast: %s' % bcast) - - print('') - -print('Found gateways:') -gateway_info = netifaces.gateways() -for family in gateway_info: - if family == 'default': - continue - - fam_name = netifaces.address_families[family] - print(' Family: %s' % fam_name) - for gateway,interface,default in gateway_info[family]: - if default: - def_text = ', default' - else: - def_text = '' - print(' %s (via %s%s)' % (gateway, interface, def_text)) - print('') - -print('Default gateways:') -default_gateways = gateway_info['default'] -for family in default_gateways: - fam_name = netifaces.address_families[family] - gateway, interface = default_gateways[family] - print(' %s: %s (via %s)' % (fam_name, gateway, interface)) |