|
#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) |
|
/* Python API for getting interface indices and names */ |
|
|
|
/*[clinic input] |
|
_socket.if_nameindex |
|
|
|
Return a list of network interface information (index, name) tuples. |
|
[clinic start generated code]*/ |
|
|
|
static PyObject * |
|
_socket_if_nameindex_impl(PyObject *module) |
|
/*[clinic end generated code: output=93c863a6262059c4 input=d6438bb556de2100]*/ |
|
{ |
|
PyObject *list = PyList_New(0); |
|
if (list == NULL) { |
|
return NULL; |
|
} |
|
#ifdef MS_WINDOWS |
|
PMIB_IF_TABLE2 tbl; |
|
int ret; |
|
if ((ret = GetIfTable2Ex(MibIfTableRaw, &tbl)) != NO_ERROR) { |
|
Py_DECREF(list); |
|
// ret is used instead of GetLastError() |
|
return PyErr_SetFromWindowsErr(ret); |
|
} |
|
for (ULONG i = 0; i < tbl->NumEntries; ++i) { |
|
MIB_IF_ROW2 r = tbl->Table[i]; |
|
WCHAR buf[NDIS_IF_MAX_STRING_SIZE + 1]; |
|
if ((ret = ConvertInterfaceLuidToNameW(&r.InterfaceLuid, buf, |
|
Py_ARRAY_LENGTH(buf)))) { |
|
Py_DECREF(list); |
|
FreeMibTable(tbl); |
|
// ret is used instead of GetLastError() |
|
return PyErr_SetFromWindowsErr(ret); |
|
} |
|
PyObject *tuple = Py_BuildValue("Iu", r.InterfaceIndex, buf); |
|
if (tuple == NULL || PyList_Append(list, tuple) == -1) { |
|
Py_XDECREF(tuple); |
|
Py_DECREF(list); |
|
FreeMibTable(tbl); |
|
return NULL; |
|
} |
|
Py_DECREF(tuple); |
|
} |
|
FreeMibTable(tbl); |
|
return list; |
|
#else |
|
int i; |
|
struct if_nameindex *ni; |
|
|
|
ni = if_nameindex(); |
|
if (ni == NULL) { |
|
PyErr_SetFromErrno(PyExc_OSError); |
|
Py_DECREF(list); |
|
return NULL; |
|
} |
|
|
|
#ifdef _Py_MEMORY_SANITIZER |
|
__msan_unpoison(ni, sizeof(ni)); |
|
__msan_unpoison(&ni[0], sizeof(ni[0])); |
|
#endif |
|
for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) { |
|
#ifdef _Py_MEMORY_SANITIZER |
|
/* This one isn't the end sentinel, the next one must exist. */ |
|
__msan_unpoison(&ni[i+1], sizeof(ni[0])); |
|
/* Otherwise Py_BuildValue internals are flagged by MSan when |
|
they access the not-msan-tracked if_name string data. */ |
|
{ |
|
char *to_sanitize = ni[i].if_name; |
|
do { |
|
__msan_unpoison(to_sanitize, 1); |
|
} while (*to_sanitize++ != '\0'); |
|
} |
|
#endif |
|
PyObject *ni_tuple = Py_BuildValue("IO&", |
|
ni[i].if_index, unicode_fsdecode, ni[i].if_name); |
|
|
|
if (ni_tuple == NULL || PyList_Append(list, ni_tuple) == -1) { |
|
Py_XDECREF(ni_tuple); |
|
Py_DECREF(list); |
|
if_freenameindex(ni); |
|
return NULL; |
|
} |
|
Py_DECREF(ni_tuple); |
|
} |
|
|
|
if_freenameindex(ni); |
|
return list; |
|
#endif |
|
} |
|
|
|
|
|
/*[clinic input] |
|
_socket.if_nametoindex |
|
oname: unicode_fs_encoded |
|
/ |
|
|
|
Returns the interface index corresponding to the interface name if_name. |
|
[clinic start generated code]*/ |
|
|
|
static PyObject * |
|
_socket_if_nametoindex_impl(PyObject *module, PyObject *oname) |
|
/*[clinic end generated code: output=289a411614f30244 input=6125dc20683560cf]*/ |
|
{ |
|
#ifdef MS_WINDOWS |
|
NET_IFINDEX index; |
|
#else |
|
unsigned long index; |
|
#endif |
|
|
|
errno = ENODEV; // in case 'if_nametoindex' does not set errno |
|
index = if_nametoindex(PyBytes_AS_STRING(oname)); |
|
if (index == 0) { |
|
PyErr_SetFromErrno(PyExc_OSError); |
|
return NULL; |
|
} |
|
|
|
return PyLong_FromUnsignedLong(index); |
|
} |
|
|
|
|
|
/*[clinic input] |
|
@permit_long_summary |
|
_socket.if_indextoname |
|
if_index as index: NET_IFINDEX |
|
/ |
|
|
|
Returns the interface name corresponding to the interface index if_index. |
|
[clinic start generated code]*/ |
|
|
|
static PyObject * |
|
_socket_if_indextoname_impl(PyObject *module, NET_IFINDEX index) |
|
/*[clinic end generated code: output=e48bc324993052e0 input=2a0026b271cd43ae]*/ |
|
{ |
|
errno = ENXIO; // in case 'if_indextoname' does not set errno |
|
char name[IF_NAMESIZE + 1]; |
|
if (if_indextoname(index, name) == NULL) { |
|
PyErr_SetFromErrno(PyExc_OSError); |
|
return NULL; |
|
} |
|
|
|
return PyUnicode_DecodeFSDefault(name); |
|
} |
|
|
|
#endif // defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) |
Bug report
Bug description:
I may be misreading the code, but it seems like
if_indextonameis conditionally defined only ifif_nameindexis (cpython/Modules/socketmodule.c
Lines 7315 to 7459 in fe3a26f
if_indextonameis available on many API versions butif_nameindexis only available on API 24+.I haven't actually tested anything since I don't have access to an Android emulator, but based on some source code reading I think I'm right?
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response