diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-09-24 16:00:55 +0200 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2020-09-24 16:00:55 +0200 |
commit | 271ff58460bd488bb9f538e20d44187ab63a15da (patch) | |
tree | 445d3e7bcafdb0779128fe113e8ac23a03b4e2fa | |
parent | f9b1b5e431ecbecf76b255737d5738ba2c69c1ba (diff) | |
download | psutil-ipv6-zone-id.tar.gz |
remove zone_id portion from IPv6 addressesipv6-zone-id
-rw-r--r-- | psutil/_psutil_posix.c | 14 | ||||
-rwxr-xr-x | psutil/tests/test_linux.py | 20 |
2 files changed, 33 insertions, 1 deletions
diff --git a/psutil/_psutil_posix.c b/psutil/_psutil_posix.c index 1182765d..fefee855 100644 --- a/psutil/_psutil_posix.c +++ b/psutil/_psutil_posix.c @@ -15,6 +15,7 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> +#include <string.h> #ifdef PSUTIL_SUNOS10 #include "arch/solaris/v10/ifaddrs.h" @@ -176,6 +177,7 @@ psutil_convert_ipaddr(struct sockaddr *addr, int family) { size_t len; const char *data; char *ptr; + char *percentp; if (addr == NULL) { Py_INCREF(Py_None); @@ -198,6 +200,18 @@ psutil_convert_ipaddr(struct sockaddr *addr, int family) { return Py_None; } else { + // IPv6 addresses can have a percent symbol at the end. + // E.g. these 2 are equivalent: + // "fe80::1ff:fe23:4567:890a" + // "fe80::1ff:fe23:4567:890a%eth0" + // That is the "zone id" portion, which usually is the name + // of the network interface. Let's remove it (ifconfig cmd + // does the same). + if (family == AF_INET6) { + percentp = strchr(buf, '%'); + if (percentp != NULL) + buf[percentp - buf] = '\0'; + } return Py_BuildValue("s", buf); } } diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 09461ec5..583af837 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -75,6 +75,23 @@ def get_ipv4_address(ifname): struct.pack('256s', ifname))[20:24]) +def get_ipv6_address(ifname): + with open("/proc/net/if_inet6", 'rt') as f: + for line in f.readlines(): + fields = line.split() + if fields[-1] == ifname: + break + else: + raise ValueError("could not find interface %r" % ifname) + unformatted = fields[0] + groups = [] + for i in range(0, len(unformatted), 4): + groups.append(unformatted[i:i + 4]) + formatted = ":".join(groups) + packed = socket.inet_pton(socket.AF_INET6, formatted) + return socket.inet_ntop(socket.AF_INET6, packed) + + def get_mac_address(ifname): import fcntl ifname = ifname[:15] @@ -890,7 +907,8 @@ class TestSystemNetIfAddrs(PsutilTestCase): self.assertEqual(addr.address, get_mac_address(name)) elif addr.family == socket.AF_INET: self.assertEqual(addr.address, get_ipv4_address(name)) - # TODO: test for AF_INET6 family + elif addr.family == socket.AF_INET6: + self.assertEqual(addr.address, get_ipv6_address(name)) # XXX - not reliable when having virtual NICs installed by Docker. # @unittest.skipIf(not which('ip'), "'ip' utility not available") |