summaryrefslogtreecommitdiff
path: root/Modules/socketmodule.c
diff options
context:
space:
mode:
authorZackery Spytz <zspytz@gmail.com>2019-05-29 15:02:37 -0600
committerSteve Dower <steve.dower@python.org>2019-05-29 14:02:37 -0700
commit8f96c9f8ed2a4795e34b333411451e24f28f74d2 (patch)
tree0f87bcc9b18f6d6c907bd040e0bc9af794a155ba /Modules/socketmodule.c
parentfecb75c1bb46c818e6579ba422cfa5d0d9d104d1 (diff)
downloadcpython-git-8f96c9f8ed2a4795e34b333411451e24f28f74d2.tar.gz
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.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index ca4d760f8c..ac1698c6c7 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,