|
26 | 26 | #include <sys/socket.h> |
27 | 27 | #include <sys/ioctl.h> |
28 | 28 | #include <sys/types.h> |
| 29 | +#include <ifaddrs.h> |
29 | 30 |
|
30 | 31 | #include "etherinfo_struct.h" |
31 | 32 | #include "etherinfo_obj.h" |
@@ -55,55 +56,24 @@ typedef __uint8_t u8; |
55 | 56 | static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __unused) |
56 | 57 | { |
57 | 58 | PyObject *list; |
58 | | - int numreqs = 30; |
59 | | - struct ifconf ifc; |
60 | | - struct ifreq *ifr; |
61 | | - int n; |
| 59 | + struct ifaddrs *ifaddr, *ifa; |
62 | 60 |
|
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) { |
69 | 62 | PyErr_SetString(PyExc_OSError, strerror(errno)); |
70 | 63 | return NULL; |
71 | 64 | } |
72 | 65 |
|
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 | | - |
93 | 66 | 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); |
103 | 74 | } |
104 | 75 |
|
105 | | - free(ifc.ifc_buf); |
106 | | - close(skfd); |
| 76 | + freeifaddrs(ifaddr); |
107 | 77 |
|
108 | 78 | return list; |
109 | 79 | } |
|
0 commit comments