@@ -42,6 +42,9 @@ Module interface:
4242- socket.inet_ntoa(packed IP) -> IP address string
4343- socket.getdefaulttimeout() -> None | float
4444- socket.setdefaulttimeout(None | float)
45+ - socket.if_nameindex() -> list of tuples (if_index, if_name)
46+ - socket.if_nametoindex(name) -> corresponding interface index
47+ - socket.if_indextoname(index) -> corresponding interface name
4548- an Internet socket address is a pair (hostname, port)
4649 where hostname can be anything recognized by gethostbyname()
4750 (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\
133136setsockopt(level, optname, value) -- set socket options\n\
134137settimeout(None | float) -- set or clear the timeout\n\
135138shutdown(how) -- shut down traffic in one or both directions\n\
139+ if_nameindex() -- return all network interface indices and names\n\
140+ if_nametoindex(name) -- returns the corresponding interface index\n\
141+ if_indextoname(index) -- returns the corresponding interface name\n\
136142\n\
137143 [*] not available on all platforms!" );
138144
@@ -4267,6 +4273,102 @@ A value of None indicates that new socket objects have no timeout.\n\
42674273When the socket module is first imported, the default is None." );
42684274
42694275
4276+ #ifdef HAVE_IF_NAMEINDEX
4277+ /* Python API for getting interface indices and names */
4278+
4279+ static PyObject *
4280+ socket_if_nameindex (PyObject * self , PyObject * arg )
4281+ {
4282+ int i = 0 ;
4283+ PyObject * list ;
4284+ struct if_nameindex * ni = if_nameindex ();
4285+
4286+ if (ni == NULL ) {
4287+ PyErr_SetString (socket_error , "if_nameindex() returned NULL." );
4288+ return NULL ;
4289+ }
4290+
4291+ list = PyList_New (0 );
4292+ if (list == NULL ) {
4293+ if_freenameindex (ni );
4294+ return NULL ;
4295+ }
4296+
4297+ while (ni [i ].if_index != 0 && i < INT_MAX ) {
4298+ PyObject * ni_tuple = Py_BuildValue (
4299+ "Iy" , ni [i ].if_index , ni [i ].if_name );
4300+
4301+ if (ni_tuple == NULL || PyList_Append (list , ni_tuple ) == -1 ) {
4302+ Py_XDECREF (ni_tuple );
4303+ goto error ;
4304+ }
4305+ Py_DECREF (ni_tuple );
4306+
4307+ ++ i ;
4308+ }
4309+
4310+ if_freenameindex (ni );
4311+ return list ;
4312+
4313+ error :
4314+ Py_DECREF (list );
4315+ if_freenameindex (ni );
4316+ return NULL ;
4317+ }
4318+
4319+ PyDoc_STRVAR (if_nameindex_doc ,
4320+ "if_nameindex()\n\
4321+ \n\
4322+ Returns a list of network interface information (index, name) tuples." );
4323+
4324+
4325+ PyObject *
4326+ socket_if_nametoindex (PyObject * self , PyObject * arg )
4327+ {
4328+ char * ifname = PyBytes_AsString (arg );
4329+ unsigned long index ;
4330+
4331+ if (ifname == NULL )
4332+ return NULL ;
4333+
4334+ index = if_nametoindex (ifname );
4335+ if (index == 0 ) {
4336+ PyErr_SetString (socket_error , "no interface with this name" );
4337+ return NULL ;
4338+ }
4339+
4340+ return PyLong_FromUnsignedLong (index );
4341+ }
4342+
4343+ PyDoc_STRVAR (if_nametoindex_doc ,
4344+ "if_nametoindex(if_name)\n\
4345+ \n\
4346+ Returns the interface index corresponding to the interface name if_name." );
4347+
4348+
4349+ PyObject *
4350+ socket_if_indextoname (PyObject * self , PyObject * arg )
4351+ {
4352+ unsigned long index = PyLong_AsUnsignedLongMask (arg );
4353+ char name [IF_NAMESIZE + 1 ]; /* or use IFNAMSIZ ?*/
4354+ char * ret = if_indextoname (index , & name [0 ]);
4355+
4356+ if (ret == NULL ) {
4357+ PyErr_SetString (socket_error , "no interface with this index" );
4358+ return NULL ;
4359+ }
4360+
4361+ return PyBytes_FromString (name );
4362+ }
4363+
4364+ PyDoc_STRVAR (if_indextoname_doc ,
4365+ "if_indextoname(if_index)\n\
4366+ \n\
4367+ Returns the interface name corresponding to the interface index if_index." );
4368+
4369+ #endif /* HAVE_IF_NAMEINDEX */
4370+
4371+
42704372/* List of functions exported by this module. */
42714373
42724374static PyMethodDef socket_methods [] = {
@@ -4322,6 +4424,14 @@ static PyMethodDef socket_methods[] = {
43224424 METH_NOARGS , getdefaulttimeout_doc },
43234425 {"setdefaulttimeout" , socket_setdefaulttimeout ,
43244426 METH_O , setdefaulttimeout_doc },
4427+ #ifdef HAVE_IF_NAMEINDEX
4428+ {"if_nameindex" , socket_if_nameindex ,
4429+ METH_NOARGS , if_nameindex_doc },
4430+ {"if_nametoindex" , socket_if_nametoindex ,
4431+ METH_O , if_nametoindex_doc },
4432+ {"if_indextoname" , socket_if_indextoname ,
4433+ METH_O , if_indextoname_doc },
4434+ #endif
43254435 {NULL , NULL } /* Sentinel */
43264436};
43274437
0 commit comments