Welcome, guest | Sign In | My Account | Store | Cart

Uses the Linux SIOCGIFADDR ioctl to find the IP address associated with a network interface, given the name of that interface, e.g. "eth0". The address is returned as a string containing a dotted quad.

Python, 17 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import socket
import fcntl
import struct

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

>>> get_ip_address('lo')
'127.0.0.1'

>>> get_ip_address('eth0')
'38.113.228.130'

People often ask how to get the "IP address of a computer". The question is misguided; computers don't usually have IP addresses themselves, but they often have one or more network interfaces which do. This recipe is a suitable answer in some cases, but of course, the best solution depends on what the programmer is trying to accomplish. Sometimes what they want is to find out their system's address from the point of view of a peer host elsewhere on a network, in which case they should just make a socket connection to that host and call getsockname() on the socket.

This may be the fastest way to find out what ifconfig would report as the IP address for an interface, though. It should certainly be faster than actually running ifconfig and parsing the output.

Users asking which interface names to check may want to see my all_interfaces() recipe, just posted.

This solution will probably only work on Linux, due to its dependence on certain C structures being of a certain size and layout, and on SIOCGIFADDR being 0x8915. It will possibly not even work on all versions of Linux, although it does on 2.4 and 2.6. If it doesn't work on other Unixes, it could probably be adjusted to work. Comments or suggestions on better portability are welcomed.

6 comments

vishnubob 17 years, 3 months ago  # | flag

MAC Address. Here is similar code to get the hardware address. Same platform caveat's apply:

def get_hw_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
    hwaddr = []
    for char in info[18:24]:
        hdigit = hex(ord(char))[2:]
        if len(hdigit) Here is similar code to get the hardware address.  Same platform caveat's apply:

<pre>
def get_hw_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
    hwaddr = []
    for char in info[18:24]:
        hdigit = hex(ord(char))[2:]
        if len(hdigit)

</pre>

Alastair Houghton 17 years, 1 month ago  # | flag

netifaces. I just thought I'd mention my new netifaces package, which you can download from the Cheese Shop with

easy_install netifaces

It should be able to find IP addresses and MAC addresses on machines that implement getaddrinfo() or the SIOCGIFxxx ioctl()s. It definitely works on Mac OS X, and I think it should work (possibly with a small amount of tweaking) on other UNIX-like systems too.

Presently it doesn't work on Windows, but if someone wanted to write the code and contribute it, I'm happy to merge it in. When I have time, I might have a go myself, but Windows isn't my primary development platform at the moment, and I'm pretty busy.

Alastair Houghton 17 years, 1 month ago  # | flag

netifaces now works on Windows too. OK, I've added some code to make my netifaces package work on Windows. It checks out on Win2K, and should work back to Windows 98 and forward to Windows Vista (in theory…)

Russell Yanofsky 16 years, 11 months ago  # | flag

Platform independent fallback. A common way of the determining the "IP address of the computer" is just to use:

socket.gethostbyname(socket.gethostname())

This works well on Windows, and on unix hosts configured in the traditional way with their main ip address set in /etc/hosts. It won't return useful results on unix systems that have their hostnames mapped to the loopback address in /etc/hosts, which is pretty common, but it's a good platform independent fallback to use when no specific interface or address information has been provided.

Ben Mackey 14 years, 9 months ago  # | flag

A finished (and simplified) version of the code that vishnubob posted above for getting the hardware/MAC address of the interface

def getHwAddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
    return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
Dave Long 9 years, 8 months ago  # | flag

Been looking for a solution to this problem for a Raspberry Pi for a long time. Tried the first solution and it worked brilliantly! Thanks, guys!

Created by paul cannon on Thu, 11 Aug 2005 (PSF)
Python recipes (4591)
paul cannon's recipes (5)

Required Modules

  • (none specified)

Other Information and Tasks