@@ -230,10 +230,55 @@ static PyObject *get_ipaddress(PyObject *self __unused, PyObject *args)
230230 *
231231 * @return Python list of objects on success, otherwise NULL.
232232 */
233- static PyObject * get_interfaceinfo (PyObject * self __unused , PyObject * args ) {
233+ static PyObject * get_interface_info (PyObject * self __unused , PyObject * args ) {
234234 PyObject * devlist = NULL , * ethinf_py = NULL ;
235+ PyObject * inargs = NULL ;
235236 struct etherinfo * devinfo = NULL , * ptr = NULL ;
237+ char * * fetch_devs ;
238+ int fetch_devs_len = 0 ;
236239
240+ if (!PyArg_ParseTuple (args , "|O" , & inargs )) {
241+ PyErr_SetString (PyExc_LookupError ,
242+ "Argument must be either a string, list or a tuple" );
243+ return NULL ;
244+ }
245+
246+ /* Parse input arguments if we got them */
247+ if ( inargs != NULL ) {
248+ if ( PyString_Check (inargs ) ) { /* Input argument is just a string */
249+ fetch_devs_len = 1 ;
250+ fetch_devs = calloc (1 , sizeof (char * ));
251+ fetch_devs [0 ] = PyString_AsString (inargs );
252+ } else if ( PyTuple_Check (inargs ) ) { /* Input argument is a tuple list with devices */
253+ int i , j = 0 ;
254+
255+ fetch_devs_len = PyTuple_Size (inargs );
256+ fetch_devs = calloc (fetch_devs_len + 1 , sizeof (char * ));
257+ for ( i = 0 ; i < fetch_devs_len ; i ++ ) {
258+ PyObject * elmt = PyTuple_GetItem (inargs , i );
259+ if ( elmt && PyString_Check (elmt ) ) {
260+ fetch_devs [j ++ ] = PyString_AsString (elmt );
261+ }
262+ }
263+ fetch_devs_len = j ;
264+ } else if ( PyList_Check (inargs ) ) { /* Input argument is a list with devices */
265+ int i , j = 0 ;
266+
267+ fetch_devs_len = PyList_Size (inargs );
268+ fetch_devs = calloc (fetch_devs_len + 1 , sizeof (char * ));
269+ for ( i = 0 ; i < fetch_devs_len ; i ++ ) {
270+ PyObject * elmt = PyList_GetItem (inargs , i );
271+ if ( elmt && PyString_Check (elmt ) ) {
272+ fetch_devs [j ++ ] = PyString_AsString (elmt );
273+ }
274+ }
275+ fetch_devs_len = j ;
276+ } else {
277+ PyErr_SetString (PyExc_LookupError ,
278+ "Argument must be either a string, list or a tuple" );
279+ return NULL ;
280+ }
281+ }
237282 devinfo = get_etherinfo ();
238283 if ( !devinfo ) {
239284 PyErr_SetString (PyExc_OSError , strerror (errno ));
@@ -249,6 +294,20 @@ static PyObject *get_interfaceinfo(PyObject *self __unused, PyObject *args) {
249294 ptr = devinfo -> next ; /* Fetch the pointer to the next element first */
250295 devinfo -> next = NULL ; /* Make the current slice do not point anywhere else */
251296
297+ /* Skip this device only if we have a list of devices and the current one */
298+ /* does not match */
299+ if ( fetch_devs_len > 0 ) {
300+ int i ;
301+ for ( i = 0 ; i < fetch_devs_len ; i ++ ) {
302+ if ( fetch_devs [i ] && (strcmp (fetch_devs [i ], devinfo -> device ) == 0 ) ) {
303+ goto found_dev ; /* Add this device to the devlist */
304+ }
305+ }
306+ /* Free the info which we don't need, and continue */
307+ free_etherinfo (devinfo );
308+ goto next_dev ;
309+ }
310+ found_dev :
252311 /* Instantiate a new etherinfo object with the device information */
253312 ethinf_py = PyCObject_FromVoidPtr (devinfo , NULL );
254313 if ( ethinf_py ) {
@@ -260,13 +319,18 @@ static PyObject *get_interfaceinfo(PyObject *self __unused, PyObject *args) {
260319 PyObject * dev = PyObject_CallObject ((PyObject * )& ethtool_etherinfoType , args );
261320 PyList_Append (devlist , dev );
262321 }
322+ next_dev :
263323 devinfo = ptr ; /* Go to the next element */
264324 }
265325 /* clean up headers which might not be used or considered interesting */
266326 if ( devinfo != NULL ) {
267327 free_etherinfo (devinfo );
268328 }
269329
330+ if ( fetch_devs_len > 0 ) {
331+ free (fetch_devs );
332+ }
333+
270334 return devlist ;
271335}
272336
@@ -831,7 +895,7 @@ static struct PyMethodDef PyEthModuleMethods[] = {
831895 },
832896 {
833897 .ml_name = "get_interface_info" ,
834- .ml_meth = (PyCFunction )get_interfaceinfo ,
898+ .ml_meth = (PyCFunction )get_interface_info ,
835899 .ml_flags = METH_VARARGS ,
836900 },
837901 {
0 commit comments