Finding active IPv6 interfaces under Mac OS (using Python)

481 Views Asked by At

My objective is to write a Python script that provides the user with a series of link-local IPv6 addresses of specific devices. My technique is to send out a multicast ping and then use neighbor discovery to get a list of addresses which I can then filter down.

The first step is this:

output = subprocess.check_output(['ping6', '-c', '2', 'ff02::1%en0'])

The problem is the term en0 at the end. It is not a constant. On MacOS it is en0 but on Linux it will be eth0 or possibly br0. Windows has a different command but the same problem. Without the interface qualifier the ping6 command does not work.

Also, some systems may have multiple interfaces.

So how would a Python script get a list of those interfaces?

Alternatively, can this be done by using the socket package and not subprocess? (I don't want my script to require privileged mode and using ping gets around that.)

1

There are 1 best solutions below

2
On BEST ANSWER

Under Linux there's no guarantee that your first Ethernet interface will be named eth0. It might be named p1s3 or em1 or even internal. Or bob.

Under both Linux and OS X you can use the netifaces python module to get a list of available interfaces and addresses associated with those interfaces. For example, consider the following code:

import netifaces

for iface in netifaces.interfaces():
    addrs = netifaces.ifaddresses(iface)
    for addr in addrs.get(netifaces.AF_INET6, []):
        print '%-8s %s' % (iface, addr['addr'])

Which on my Linux system produces:

lo       ::1
enp0s25  fe80::3e97:eff:febf:6dce%enp0s25
docker0  fe80::d8d1:31ff:feb2:b6c6%docker0
br-ext   fe80::f879:f3ff:fe6b:f445%br-ext
lxcbr0   fe80::fc45:6bff:fefd:543%lxcbr0
vethf8c98b2 fe80::a0a7:3bff:feff:4f9b%vethf8c98b2
vnet0    fe80::fc54:ff:fee5:2818%vnet0

And on my OS X system produces:

lo0      ::1
lo0      fe80::1%lo0
en3      fe80::e2f8:47ff:fe41:866a%en3

I have no idea if this works under Windows or not.