How do I determine all of my IP addresses when I have multiple NICs? How do I determine all of my IP addresses when I have multiple NICs? python python

How do I determine all of my IP addresses when I have multiple NICs?


Use the netifaces module. Because networking is complex, using netifaces can be a little tricky, but here's how to do what you want:

>>> import netifaces>>> netifaces.interfaces()['lo', 'eth0']>>> netifaces.ifaddresses('eth0'){17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:11:2f:32:63:45'}], 2: [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::211:2fff:fe32:6345%eth0'}]}>>> for interface in netifaces.interfaces():...   print netifaces.ifaddresses(interface)[netifaces.AF_INET]...[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}][{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}]>>> for interface in netifaces.interfaces():...   for link in netifaces.ifaddresses(interface)[netifaces.AF_INET]:...     print link['addr']...127.0.0.110.0.0.2

This can be made a little more readable like this:

from netifaces import interfaces, ifaddresses, AF_INETdef ip4_addresses():    ip_list = []    for interface in interfaces():        for link in ifaddresses(interface)[AF_INET]:            ip_list.append(link['addr'])    return ip_list

If you want IPv6 addresses, use AF_INET6 instead of AF_INET. If you're wondering why netifaces uses lists and dictionaries all over the place, it's because a single computer can have multiple NICs, and each NIC can have multiple addresses, and each address has its own set of options.


import socket[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]


Just for completeness, another option would be to use psutil.

tldr;

import socketimport psutildef get_ip_addresses(family):    for interface, snics in psutil.net_if_addrs().items():        for snic in snics:            if snic.family == family:                yield (interface, snic.address)ipv4s = list(get_ip_addresses(socket.AF_INET))ipv6s = list(get_ip_addresses(socket.AF_INET6))

Explanation

The function you need is net_if_addrs. I.e.:

import psutilpsutil.net_if_addrs()

Which results in something like this (Python 3):

{'br-ae4880aa80cf': [snic(family=<AddressFamily.AF_INET: 2>, address='172.18.0.1', netmask='255.255.0.0', broadcast='172.18.0.1', ptp=None),                     snic(family=<AddressFamily.AF_PACKET: 17>, address='02:42:e5:ae:39:94', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'docker0': [snic(family=<AddressFamily.AF_INET: 2>, address='172.17.0.1', netmask='255.255.0.0', broadcast='172.17.0.1', ptp=None),             snic(family=<AddressFamily.AF_PACKET: 17>, address='02:42:38:d2:4d:77', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'eno1': [snic(family=<AddressFamily.AF_PACKET: 17>, address='54:be:f7:0b:cf:a9', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),        snic(family=<AddressFamily.AF_PACKET: 17>, address='00:00:00:00:00:00', netmask=None, broadcast=None, ptp=None)], 'wlp2s0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.4', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),            snic(family=<AddressFamily.AF_PACKET: 17>, address='00:21:27:ee:d6:03', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}

(Python 2):

{'br-ae4880aa80cf': [snic(family=2, address='172.18.0.1', netmask='255.255.0.0', broadcast='172.18.0.1', ptp=None),                     snic(family=17, address='02:42:e5:ae:39:94', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'docker0': [snic(family=2, address='172.17.0.1', netmask='255.255.0.0', broadcast='172.17.0.1', ptp=None),             snic(family=17, address='02:42:38:d2:4d:77', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'eno1': [snic(family=17, address='54:be:f7:0b:cf:a9', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], 'lo': [snic(family=2, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),        snic(family=17, address='00:00:00:00:00:00', netmask=None, broadcast=None, ptp=None)], 'wlp2s0': [snic(family=2, address='192.168.1.4', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),            snic(family=17, address='00:21:27:ee:d6:03', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}

Note: Since you can have more than one address of the same family associated with each interface, the dict values are lists.

Each snic is a namedtuple which includes 5 fields:

  • family: the address family, either AF_INET, AF_INET6 or psutil.AF_LINK, which refers to a MAC address.
  • address: the primary NIC address (always set).
  • netmask: the netmask address (may be None).
  • broadcast: the broadcast address (may be None).
  • ptp: stands for “point to point”; it’s the destination address on a point to point interface (typically a VPN). broadcast and ptp are mutually exclusive (may be None).