Uses the SIOCGIFCONF ioctl to obtain a list of interfaces and extracts those names, returning them in a list of strings.
| Python |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import socket
import fcntl
import struct
import array
def all_interfaces():
max_possible = 128 # arbitrary. raise if needed.
bytes = max_possible * 32
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', bytes, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return [namestr[i:i+32].split('\0', 1)[0] for i in range(0, outbytes, 32)]
|
Discussion
This solution should be faster than running ifconfig and parsing its output, and simpler than reading and parsing /proc/net/dev, since that will list all existing interfaces, whether active (up) or not.
This solution probably only works on Linux-- and possibly not all versions of even that-- since it depends on some C structures having a particular size and layout, as well as having the SIOCGIFCONF ioctl number (0x8912) hardcoded. I believe it could be adjusted, though, to work on other Unix systems.


Comments
struct ifconf has changed... I wish we didn't have to use constants for the structure offsets... For a 2.6.17 kernel the above offsets are incorrect. I've replaced the last line with:
The above is for a 64 bit kernel... Ah, structure offsets have not changed over the years for 32 bit kernels, my patch is for a 64 bit 2.6.17 kernel.
no need for format_ip. You could have done: socket.inet_ntoa(ip)
Sign in to comment