diff options
author | Zackery Spytz <zspytz@gmail.com> | 2019-05-29 21:02:37 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@python.org> | 2019-05-29 21:02:37 (GMT) |
commit | 8f96c9f8ed2a4795e34b333411451e24f28f74d2 (patch) | |
tree | 0f87bcc9b18f6d6c907bd040e0bc9af794a155ba /Modules/socketmodule.c | |
parent | fecb75c1bb46c818e6579ba422cfa5d0d9d104d1 (diff) | |
download | cpython-8f96c9f8ed2a4795e34b333411451e24f28f74d2.zip cpython-8f96c9f8ed2a4795e34b333411451e24f28f74d2.tar.gz cpython-8f96c9f8ed2a4795e34b333411451e24f28f74d2.tar.bz2 |
bpo-37007: Implement socket.if_nametoindex(), if_indextoname() and if_nameindex() on Windows (GH-13522)
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ca4d760..ac1698c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -345,6 +345,8 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82& /* Provides the IsWindows7SP1OrGreater() function */ #include <versionhelpers.h> +// For if_nametoindex() and if_indextoname() +#include <iphlpapi.h> /* remove some flags on older version Windows during run-time. https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */ @@ -6667,28 +6669,56 @@ Set the default timeout in seconds (float) for new socket objects.\n\ A value of None indicates that new socket objects have no timeout.\n\ When the socket module is first imported, the default is None."); -#ifdef HAVE_IF_NAMEINDEX +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) /* Python API for getting interface indices and names */ static PyObject * socket_if_nameindex(PyObject *self, PyObject *arg) { - PyObject *list; + 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) { + Py_DECREF(list); PyErr_SetFromErrno(PyExc_OSError); return NULL; } - list = PyList_New(0); - if (list == NULL) { - if_freenameindex(ni); - return NULL; - } - #ifdef _Py_MEMORY_SANITIZER __msan_unpoison(ni, sizeof(ni)); __msan_unpoison(&ni[0], sizeof(ni[0])); @@ -6720,6 +6750,7 @@ socket_if_nameindex(PyObject *self, PyObject *arg) if_freenameindex(ni); return list; +#endif } PyDoc_STRVAR(if_nameindex_doc, @@ -6731,8 +6762,11 @@ static PyObject * socket_if_nametoindex(PyObject *self, PyObject *args) { PyObject *oname; +#ifdef MS_WINDOWS + NET_IFINDEX index; +#else unsigned long index; - +#endif if (!PyArg_ParseTuple(args, "O&:if_nametoindex", PyUnicode_FSConverter, &oname)) return NULL; @@ -6756,7 +6790,11 @@ Returns the interface index corresponding to the interface name if_name."); static PyObject * socket_if_indextoname(PyObject *self, PyObject *arg) { +#ifdef MS_WINDOWS + NET_IFINDEX index; +#else unsigned long index; +#endif char name[IF_NAMESIZE + 1]; index = PyLong_AsUnsignedLong(arg); @@ -6776,7 +6814,7 @@ PyDoc_STRVAR(if_indextoname_doc, \n\ Returns the interface name corresponding to the interface index if_index."); -#endif /* HAVE_IF_NAMEINDEX */ +#endif // defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) #ifdef CMSG_LEN @@ -6898,7 +6936,7 @@ static PyMethodDef socket_methods[] = { METH_NOARGS, getdefaulttimeout_doc}, {"setdefaulttimeout", socket_setdefaulttimeout, METH_O, setdefaulttimeout_doc}, -#ifdef HAVE_IF_NAMEINDEX +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) {"if_nameindex", socket_if_nameindex, METH_NOARGS, if_nameindex_doc}, {"if_nametoindex", socket_if_nametoindex, |