Skip to content

Commit c61363e

Browse files
Bohuslav KabrdaDavid Sommerseth
authored andcommitted
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>
1 parent 22b8d25 commit c61363e

File tree

1 file changed

+11
-41
lines changed

1 file changed

+11
-41
lines changed

python-ethtool/ethtool.c

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <sys/socket.h>
2727
#include <sys/ioctl.h>
2828
#include <sys/types.h>
29+
#include <ifaddrs.h>
2930

3031
#include "etherinfo_struct.h"
3132
#include "etherinfo_obj.h"
@@ -55,55 +56,24 @@ typedef __uint8_t u8;
5556
static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __unused)
5657
{
5758
PyObject *list;
58-
int numreqs = 30;
59-
struct ifconf ifc;
60-
struct ifreq *ifr;
61-
int n;
59+
struct ifaddrs *ifaddr, *ifa;
6260

63-
/* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
64-
(as of 2.1.128) */
65-
/* Open control socket. */
66-
int skfd = socket(AF_INET, SOCK_DGRAM, 0);
67-
68-
if (skfd < 0) {
61+
if (getifaddrs(&ifaddr) == -1) {
6962
PyErr_SetString(PyExc_OSError, strerror(errno));
7063
return NULL;
7164
}
7265

73-
ifc.ifc_buf = NULL;
74-
for (;;) {
75-
ifc.ifc_len = sizeof(struct ifreq) * numreqs;
76-
ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
77-
78-
if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
79-
PyErr_SetString(PyExc_OSError, strerror(errno));
80-
free(ifc.ifc_buf);
81-
close(skfd);
82-
return NULL;
83-
}
84-
85-
if (ifc.ifc_len == (int)sizeof(struct ifreq) * numreqs) {
86-
/* assume it overflowed and try again */
87-
numreqs += 10;
88-
continue;
89-
}
90-
break;
91-
}
92-
9366
list = PyList_New(0);
94-
ifr = ifc.ifc_req;
95-
for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
96-
if (!(ioctl(skfd, SIOCGIFFLAGS, ifr) < 0))
97-
if (ifr->ifr_flags & IFF_UP) {
98-
PyObject *str = PyString_FromString(ifr->ifr_name);
99-
PyList_Append(list, str);
100-
Py_DECREF(str);
101-
}
102-
ifr++;
67+
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
68+
PyObject *str = PyString_FromString(ifa->ifa_name);
69+
/* names are not unique (listed for both ipv4 and ipv6) */
70+
if (!PySequence_Contains(list, str) && (ifa->ifa_flags & (IFF_UP))) {
71+
PyList_Append(list, str);
72+
}
73+
Py_DECREF(str);
10374
}
10475

105-
free(ifc.ifc_buf);
106-
close(skfd);
76+
freeifaddrs(ifaddr);
10777

10878
return list;
10979
}

0 commit comments

Comments
 (0)