diff options
author | Bohuslav Kabrda <bkabrda@redhat.com> | 2013-08-07 17:12:00 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2013-09-11 20:56:27 +0200 |
commit | c61363e517154548f0b85772e1f83186dff898bc (patch) | |
tree | 6e1cdbdcfcd069a1d6282bd49c053e730daaa03c | |
parent | 22b8d25d41743de54b4ea38b81689d1c3d251215 (diff) | |
download | python-ethtool-c61363e517154548f0b85772e1f83186dff898bc.tar.gz python-ethtool-c61363e517154548f0b85772e1f83186dff898bc.tar.xz python-ethtool-c61363e517154548f0b85772e1f83186dff898bc.zip |
Fix get_active_devices() for IPv6 only interfaces
The old ioctl() calls will only return active interaces which is
configured with IPv4 addresses. Thus an interface with only IPv6
configured will not be returned.
This modifies get_active_devices() to use a newer API to retrieve
the needed information.
Bugzilla: RH#855920
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | python-ethtool/ethtool.c | 52 |
1 files changed, 11 insertions, 41 deletions
diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c index a79c438..afa14dc 100644 --- a/python-ethtool/ethtool.c +++ b/python-ethtool/ethtool.c @@ -26,6 +26,7 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/types.h> +#include <ifaddrs.h> #include "etherinfo_struct.h" #include "etherinfo_obj.h" @@ -55,55 +56,24 @@ typedef __uint8_t u8; static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __unused) { PyObject *list; - int numreqs = 30; - struct ifconf ifc; - struct ifreq *ifr; - int n; + struct ifaddrs *ifaddr, *ifa; - /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets - (as of 2.1.128) */ - /* Open control socket. */ - int skfd = socket(AF_INET, SOCK_DGRAM, 0); - - if (skfd < 0) { + if (getifaddrs(&ifaddr) == -1) { PyErr_SetString(PyExc_OSError, strerror(errno)); return NULL; } - ifc.ifc_buf = NULL; - for (;;) { - ifc.ifc_len = sizeof(struct ifreq) * numreqs; - ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len); - - if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { - PyErr_SetString(PyExc_OSError, strerror(errno)); - free(ifc.ifc_buf); - close(skfd); - return NULL; - } - - if (ifc.ifc_len == (int)sizeof(struct ifreq) * numreqs) { - /* assume it overflowed and try again */ - numreqs += 10; - continue; - } - break; - } - list = PyList_New(0); - ifr = ifc.ifc_req; - for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { - if (!(ioctl(skfd, SIOCGIFFLAGS, ifr) < 0)) - if (ifr->ifr_flags & IFF_UP) { - PyObject *str = PyString_FromString(ifr->ifr_name); - PyList_Append(list, str); - Py_DECREF(str); - } - ifr++; + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + PyObject *str = PyString_FromString(ifa->ifa_name); + /* names are not unique (listed for both ipv4 and ipv6) */ + if (!PySequence_Contains(list, str) && (ifa->ifa_flags & (IFF_UP))) { + PyList_Append(list, str); + } + Py_DECREF(str); } - free(ifc.ifc_buf); - close(skfd); + freeifaddrs(ifaddr); return list; } |