Issue #1746656: Add if_nameindex, if_nametoindex, if_indextoname
methods to the socket module.
This commit is contained in:
parent
1a4de20d95
commit
5ed2e779f1
|
@ -536,6 +536,39 @@ The module :mod:`socket` exports the following constants and functions:
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: if_nameindex()
|
||||||
|
|
||||||
|
Returns a list of network interface information
|
||||||
|
(index, name as a byte string) tuples.
|
||||||
|
:exc:`socket.error` if the system call fails for any reason.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: if_nametoindex(if_name)
|
||||||
|
|
||||||
|
Returns a network interface index number corresponding to an
|
||||||
|
interface name byte string.
|
||||||
|
:exc:`socket.error` if no interface with the given name exists.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: if_indextoname(if_index)
|
||||||
|
|
||||||
|
Returns a network interface name byte string corresponding to a
|
||||||
|
interface index.
|
||||||
|
:exc:`socket.error` if no interface with the given index exists.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. data:: SocketType
|
.. data:: SocketType
|
||||||
|
|
||||||
This is a Python type object that represents the socket object type. It is the
|
This is a Python type object that represents the socket object type. It is the
|
||||||
|
|
|
@ -372,6 +372,16 @@ class GeneralModuleTests(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
socket.sethostname(oldhn)
|
socket.sethostname(oldhn)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(socket, 'if_nameindex'),
|
||||||
|
'socket.if_nameindex() not available.')
|
||||||
|
def testInterfaceNameIndex(self):
|
||||||
|
interfaces = socket.if_nameindex()
|
||||||
|
for index, name in interfaces:
|
||||||
|
# interface indices are non-zero integers
|
||||||
|
self.assertGreater(index, 0)
|
||||||
|
self.assertEqual(index, socket.if_nametoindex(name))
|
||||||
|
self.assertEqual(name, socket.if_indextoname(index))
|
||||||
|
|
||||||
def testRefCountGetNameInfo(self):
|
def testRefCountGetNameInfo(self):
|
||||||
# Testing reference count for getnameinfo
|
# Testing reference count for getnameinfo
|
||||||
if hasattr(sys, "getrefcount"):
|
if hasattr(sys, "getrefcount"):
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Added the if_nameindex, if_indextoname, if_nametoindex methods to
|
||||||
|
the socket module as requested in issue #1746656.
|
||||||
|
|
||||||
- Issue #12044: Fixed subprocess.Popen when used as a context manager to
|
- Issue #12044: Fixed subprocess.Popen when used as a context manager to
|
||||||
wait for the process to end when exiting the context to avoid unintentionally
|
wait for the process to end when exiting the context to avoid unintentionally
|
||||||
leaving zombie processes around.
|
leaving zombie processes around.
|
||||||
|
|
|
@ -42,6 +42,9 @@ Module interface:
|
||||||
- socket.inet_ntoa(packed IP) -> IP address string
|
- socket.inet_ntoa(packed IP) -> IP address string
|
||||||
- socket.getdefaulttimeout() -> None | float
|
- socket.getdefaulttimeout() -> None | float
|
||||||
- socket.setdefaulttimeout(None | float)
|
- socket.setdefaulttimeout(None | float)
|
||||||
|
- socket.if_nameindex() -> list of tuples (if_index, if_name)
|
||||||
|
- socket.if_nametoindex(name) -> corresponding interface index
|
||||||
|
- socket.if_indextoname(index) -> corresponding interface name
|
||||||
- an Internet socket address is a pair (hostname, port)
|
- an Internet socket address is a pair (hostname, port)
|
||||||
where hostname can be anything recognized by gethostbyname()
|
where hostname can be anything recognized by gethostbyname()
|
||||||
(including the dd.dd.dd.dd notation) and port is in host byte order
|
(including the dd.dd.dd.dd notation) and port is in host byte order
|
||||||
|
@ -133,6 +136,9 @@ setblocking(0 | 1) -- set or clear the blocking I/O flag\n\
|
||||||
setsockopt(level, optname, value) -- set socket options\n\
|
setsockopt(level, optname, value) -- set socket options\n\
|
||||||
settimeout(None | float) -- set or clear the timeout\n\
|
settimeout(None | float) -- set or clear the timeout\n\
|
||||||
shutdown(how) -- shut down traffic in one or both directions\n\
|
shutdown(how) -- shut down traffic in one or both directions\n\
|
||||||
|
if_nameindex() -- return all network interface indices and names\n\
|
||||||
|
if_nametoindex(name) -- returns the corresponding interface index\n\
|
||||||
|
if_indextoname(index) -- returns the corresponding interface name\n\
|
||||||
\n\
|
\n\
|
||||||
[*] not available on all platforms!");
|
[*] not available on all platforms!");
|
||||||
|
|
||||||
|
@ -4267,6 +4273,102 @@ A value of None indicates that new socket objects have no timeout.\n\
|
||||||
When the socket module is first imported, the default is None.");
|
When the socket module is first imported, the default is None.");
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_IF_NAMEINDEX
|
||||||
|
/* Python API for getting interface indices and names */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
socket_if_nameindex(PyObject *self, PyObject *arg)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
PyObject *list;
|
||||||
|
struct if_nameindex *ni = if_nameindex();
|
||||||
|
|
||||||
|
if (ni == NULL) {
|
||||||
|
PyErr_SetString(socket_error, "if_nameindex() returned NULL.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = PyList_New(0);
|
||||||
|
if (list == NULL) {
|
||||||
|
if_freenameindex(ni);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ni[i].if_index != 0 && i < INT_MAX) {
|
||||||
|
PyObject *ni_tuple = Py_BuildValue(
|
||||||
|
"Iy", ni[i].if_index, ni[i].if_name);
|
||||||
|
|
||||||
|
if (ni_tuple == NULL || PyList_Append(list, ni_tuple) == -1) {
|
||||||
|
Py_XDECREF(ni_tuple);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
Py_DECREF(ni_tuple);
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if_freenameindex(ni);
|
||||||
|
return list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
Py_DECREF(list);
|
||||||
|
if_freenameindex(ni);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(if_nameindex_doc,
|
||||||
|
"if_nameindex()\n\
|
||||||
|
\n\
|
||||||
|
Returns a list of network interface information (index, name) tuples.");
|
||||||
|
|
||||||
|
|
||||||
|
PyObject*
|
||||||
|
socket_if_nametoindex(PyObject *self, PyObject *arg)
|
||||||
|
{
|
||||||
|
char* ifname = PyBytes_AsString(arg);
|
||||||
|
unsigned long index;
|
||||||
|
|
||||||
|
if (ifname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
index = if_nametoindex(ifname);
|
||||||
|
if (index == 0) {
|
||||||
|
PyErr_SetString(socket_error, "no interface with this name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(if_nametoindex_doc,
|
||||||
|
"if_nametoindex(if_name)\n\
|
||||||
|
\n\
|
||||||
|
Returns the interface index corresponding to the interface name if_name.");
|
||||||
|
|
||||||
|
|
||||||
|
PyObject*
|
||||||
|
socket_if_indextoname(PyObject *self, PyObject *arg)
|
||||||
|
{
|
||||||
|
unsigned long index = PyLong_AsUnsignedLongMask(arg);
|
||||||
|
char name[IF_NAMESIZE + 1]; /* or use IFNAMSIZ ?*/
|
||||||
|
char *ret = if_indextoname(index, &name[0]);
|
||||||
|
|
||||||
|
if (ret == NULL) {
|
||||||
|
PyErr_SetString(socket_error, "no interface with this index");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyBytes_FromString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(if_indextoname_doc,
|
||||||
|
"if_indextoname(if_index)\n\
|
||||||
|
\n\
|
||||||
|
Returns the interface name corresponding to the interface index if_index.");
|
||||||
|
|
||||||
|
#endif /* HAVE_IF_NAMEINDEX */
|
||||||
|
|
||||||
|
|
||||||
/* List of functions exported by this module. */
|
/* List of functions exported by this module. */
|
||||||
|
|
||||||
static PyMethodDef socket_methods[] = {
|
static PyMethodDef socket_methods[] = {
|
||||||
|
@ -4322,6 +4424,14 @@ static PyMethodDef socket_methods[] = {
|
||||||
METH_NOARGS, getdefaulttimeout_doc},
|
METH_NOARGS, getdefaulttimeout_doc},
|
||||||
{"setdefaulttimeout", socket_setdefaulttimeout,
|
{"setdefaulttimeout", socket_setdefaulttimeout,
|
||||||
METH_O, setdefaulttimeout_doc},
|
METH_O, setdefaulttimeout_doc},
|
||||||
|
#ifdef HAVE_IF_NAMEINDEX
|
||||||
|
{"if_nameindex", socket_if_nameindex,
|
||||||
|
METH_NOARGS, if_nameindex_doc},
|
||||||
|
{"if_nametoindex", socket_if_nametoindex,
|
||||||
|
METH_O, if_nametoindex_doc},
|
||||||
|
{"if_indextoname", socket_if_indextoname,
|
||||||
|
METH_O, if_indextoname_doc},
|
||||||
|
#endif
|
||||||
{NULL, NULL} /* Sentinel */
|
{NULL, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2512,6 +2512,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
futimens futimes \
|
futimens futimes \
|
||||||
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
|
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||||
|
if_nameindex \
|
||||||
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
|
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
|
||||||
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
|
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
|
||||||
posix_fallocate posix_fadvise pread \
|
posix_fallocate posix_fadvise pread \
|
||||||
|
|
|
@ -389,6 +389,9 @@
|
||||||
/* Define to 1 if you have the <ieeefp.h> header file. */
|
/* Define to 1 if you have the <ieeefp.h> header file. */
|
||||||
#undef HAVE_IEEEFP_H
|
#undef HAVE_IEEEFP_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `if_nameindex' function. */
|
||||||
|
#undef HAVE_IF_NAMEINDEX
|
||||||
|
|
||||||
/* Define if you have the 'inet_aton' function. */
|
/* Define if you have the 'inet_aton' function. */
|
||||||
#undef HAVE_INET_ATON
|
#undef HAVE_INET_ATON
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue