Retrieving network mask in Python

How would one go about retrieving a network device's netmask (In Linux preferably, but if it's cross-platform then cool)? I know how in C on Linux but I can't find a way in Python -- minus ctypes perhaps. That or parsing ifconfig. Any other way?

ioctl(socknr, SIOCGIFNETMASK, &ifreq) // C version

Solution 1:

This works for me in Python 2.2 on Linux:

iface = "eth0"
socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 35099, struct.pack('256s', iface))[20:24])

Solution 2:

The netifaces module deserves a mention here. Straight from the docs:

>>> netifaces.interfaces()
['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']

>>> 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'}]

Works on Windows, Linux, OS X, and probably other UNIXes.

Solution 3:

Did you look here?

http://docs.python.org/library/fcntl.html

This works for me in python 2.5.2 on Linux. Was finishing it when Ben got ahead, but still here it goes (sad to waste the effort :-) ):

vinko@parrot:~$ more get_netmask.py
# get_netmask.py by Vinko Vrsalovic 2009
# Inspired by http://code.activestate.com/recipes/439093/
# and http://code.activestate.com/recipes/439094/
# Code: 0x891b SIOCGIFNETMASK

import socket
import fcntl
import struct
import sys

def get_netmask(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x891b, struct.pack('256
s',ifname))[20:24])

if len(sys.argv) == 2:
        print get_netmask(sys.argv[1])
vinko@parrot:~$ python get_netmask.py lo
255.0.0.0
vinko@parrot:~$ python get_netmask.py eth0
255.255.255.0

Solution 4:

You can use this library: http://github.com/rlisagor/pynetlinux. Note: I'm the author of the library.

Solution 5:

I had the idea to rely on subprocess to use a simple ifconfig (Linux) or ipconfig (windows) request to retrieve the info (if the ip is known). Comments welcome :

WINDOWS

ip = '192.168.1.10' #Example
proc = subprocess.Popen('ipconfig',stdout=subprocess.PIPE)
while True:
    line = proc.stdout.readline()
    if ip.encode() in line:
        break
mask = proc.stdout.readline().rstrip().split(b':')[-1].replace(b' ',b'').decode()

UNIX-Like

ip = '192.168.1.10' #Example
proc = subprocess.Popen('ifconfig',stdout=subprocess.PIPE)
while True:
    line = proc.stdout.readline()
    if ip.encode() in line:
        break
mask = line.rstrip().split(b':')[-1].replace(b' ',b'').decode()

IP is retrieved using a socket connection to the web and using getsockname()[0]