From c61363e517154548f0b85772e1f83186dff898bc Mon Sep 17 00:00:00 2001 From: Bohuslav Kabrda Date: Wed, 7 Aug 2013 17:12:00 +0200 Subject: 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 --- python-ethtool/ethtool.c | 52 ++++++++++-------------------------------------- 1 file 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 #include #include +#include #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; } -- cgit