Alastair’s Place

Software development, Cocoa, Objective-C, life. Stuff like that.


Portable access to network interfaces from Python

Historically it has been difficult to straightforwardly get the network address(es) of the machine on which your Python scripts are running without compromising the portability of your script.

As a result, when I needed to do this for the first time, I thought it would be best to write a Python module that would work on (at least) Mac OS X and Linux, and maybe other UNIX-like systems too. netifaces is the result.

Here’s a quick example:

List the network interfaces on a machine, using netifaces.
>>> import netifaces
>>> netifaces.interfaces()
['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']

You can also inspect a particular interface to determine its addresses:

Find the address of interface `en0`.
>>> netifaces.ifaddresses('en0')
{18: [{'addr': '00:12:34:56:78:9a'}], 2: [{'broadcast':
 '', 'netmask': '', 'addr': ''}],
 30: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr':

Additionally, netifaces sets up constants for all of the address families, so e.g.:

Using address family constants
>>> netifaces.ifaddresses('en0')[netifaces.AF_LINK]
[{'addr': '00:12:34:56:78:9a'}]
>>> netifaces.AF_LINK
>>> netifaces.address_families[18]

Importantly, the numeric values of address family constants, as well as the precise set available, may change from system to system. AF_LINK will always exist; on platforms where it does not actually exist in the system, it will take the value -1. You can also rely on the existence of AF_INET, but otherwise you should not assume that the system on which you are running supports a particular address family.

The netifaces package works on Windows as well as many UNIX-like platforms; various people have contributed patches for systems I don’t have access to myself. The fastest way to install it is to use easy_install, which you can get from the PEAK Developers’ Center if you don’t already have it. It may also be available as a package on some Linux or BSD distributions.

You can get the source code from the mercurial repository, or, for Windows users, there are pre-built binaries for Python 2.4 (version 0.4), Python 2.5 (version 0.5), Python 2.6 (version 0.5), and Python 2.7 (version 0.7).

There is also a source archive of version 0.8.


Version 0.8 – 2012-01-31

All the changes in this version relate to the fallback 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 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 results from SIOCG[L]IFCONF; Mac OS X does this, for instance.

Version 0.7 – 2012-01-30

  • 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 version property to the module that you can test at runtime.

Version 0.6 – 2011-11-04

  • 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 numeric address family code.

Version 0.5 – 2011-10-14

  • Historic version.