-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add in support for network interface flags. #2037
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -789,3 +789,7 @@ I: 2099 | |
|
||
N: Torsten Blum | ||
I: 2114 | ||
|
||
N: Chris Lalancette | ||
W: https://github.com/clalancette | ||
I: 2037 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -735,20 +735,28 @@ Network | |
- **speed**: the NIC speed expressed in mega bits (MB), if it can't be | ||
determined (e.g. 'localhost') it will be set to ``0``. | ||
- **mtu**: NIC's maximum transmission unit expressed in bytes. | ||
- **flags**: a string of comma-separated flags on the interface (may be the empty string). | ||
Possible flags are: ``up``, ``broadcast``, ``debug``, ``loopback``, | ||
``pointopoint``, ``notrailers``, ``running``, ``noarp``, ``promisc``, | ||
``allmulti``, ``master``, ``slave``, ``multicast``, ``portsel``, | ||
``dynamic``, ``oactive``, ``simplex``, ``link0``, ``link1``, ``link2``, | ||
and ``d2`` (some flags are only available on certain platforms). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added it in 3082526 . Let me know if that is where you want it. |
||
|
||
Example: | ||
|
||
>>> import psutil | ||
>>> psutil.net_if_stats() | ||
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500), | ||
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)} | ||
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500, flags='up,broadcast,running,multicast'), | ||
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536, flags='up,loopback,running')} | ||
|
||
Also see `nettop.py`_ and `ifconfig.py`_ for an example application. | ||
|
||
.. versionadded:: 3.0.0 | ||
|
||
.. versionchanged:: 5.7.3 `isup` on UNIX also checks whether the NIC is running. | ||
|
||
.. versionchanged:: 5.9.1 *flags* field was added on POSIX. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 5.9.2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d83c959. |
||
|
||
Sensors | ||
------- | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1060,7 +1060,7 @@ def net_if_stats(): | |
for name in names: | ||
try: | ||
mtu = cext_posix.net_if_mtu(name) | ||
isup = cext_posix.net_if_is_running(name) | ||
flags = cext_posix.net_if_flags(name) | ||
duplex, speed = cext.net_if_duplex_speed(name) | ||
except OSError as err: | ||
# https://github.com/giampaolo/psutil/issues/1279 | ||
|
@@ -1069,7 +1069,9 @@ def net_if_stats(): | |
else: | ||
debug(err) | ||
else: | ||
ret[name] = _common.snicstats(isup, duplex_map[duplex], speed, mtu) | ||
output_flags = ','.join(flags) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please rename this variable to just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment here. |
||
isup = 'running' in flags | ||
ret[name] = _common.snicstats(isup, duplex_map[duplex], speed, mtu, output_flags) | ||
return ret | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -263,7 +263,7 @@ def net_if_stats(): | |
for name in names: | ||
try: | ||
mtu = cext_posix.net_if_mtu(name) | ||
isup = cext_posix.net_if_is_running(name) | ||
flags = cext_posix.net_if_flags(name) | ||
duplex, speed = cext_posix.net_if_duplex_speed(name) | ||
except OSError as err: | ||
# https://github.com/giampaolo/psutil/issues/1279 | ||
|
@@ -272,7 +272,9 @@ def net_if_stats(): | |
else: | ||
if hasattr(_common, 'NicDuplex'): | ||
duplex = _common.NicDuplex(duplex) | ||
ret[name] = _common.snicstats(isup, duplex, speed, mtu) | ||
output_flags = ','.join(flags) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please rename this variable to just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment here. |
||
isup = 'running' in flags | ||
ret[name] = _common.snicstats(isup, duplex, speed, mtu, output_flags) | ||
return ret | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
#include <Python.h> | ||
#include <errno.h> | ||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can remove this, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call, removed in 3082526 |
||
#include <sys/resource.h> | ||
#include <sys/types.h> | ||
#include <signal.h> | ||
|
@@ -429,6 +430,186 @@ psutil_net_if_mtu(PyObject *self, PyObject *args) { | |
return PyErr_SetFromErrno(PyExc_OSError); | ||
} | ||
|
||
static bool | ||
check_and_append_iff_flag(PyObject *py_retlist, short int flags, short int flag_to_check, const char * flag_name) | ||
{ | ||
PyObject *py_str = NULL; | ||
|
||
if (flags & flag_to_check) { | ||
py_str = PyUnicode_DecodeFSDefault(flag_name); | ||
if (! py_str) | ||
return false; | ||
if (PyList_Append(py_retlist, py_str)) { | ||
Py_DECREF(py_str); | ||
return false; | ||
} | ||
Py_CLEAR(py_str); | ||
} | ||
|
||
return true; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like doing the flag comparison / check in here ( Also, instead of return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's fair. I've switched this helper function to return an int, and I'm now doing the check in the main function. All in d83c959. |
||
|
||
/* | ||
* Get all of the NIC flags and return them. | ||
*/ | ||
static PyObject * | ||
psutil_net_if_flags(PyObject *self, PyObject *args) { | ||
char *nic_name; | ||
int sock = -1; | ||
int ret; | ||
struct ifreq ifr; | ||
PyObject *py_retlist = PyList_New(0); | ||
short int flags; | ||
|
||
if (py_retlist == NULL) | ||
return NULL; | ||
|
||
if (! PyArg_ParseTuple(args, "s", &nic_name)) | ||
goto error; | ||
|
||
sock = socket(AF_INET, SOCK_DGRAM, 0); | ||
if (sock == -1) { | ||
PyErr_SetFromErrno(PyExc_OSError); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use (sorry, I know I told you to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem, it happens. Fixed in d83c959. |
||
goto error; | ||
} | ||
|
||
PSUTIL_STRNCPY(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name)); | ||
ret = ioctl(sock, SIOCGIFFLAGS, &ifr); | ||
if (ret == -1) { | ||
PyErr_SetFromErrno(PyExc_OSError); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d83c959. |
||
goto error; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in e05f926. |
||
} | ||
|
||
close(sock); | ||
sock = -1; | ||
|
||
flags = ifr.ifr_flags & 0xFFFF; | ||
|
||
// Linux/glibc IFF flags: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/gnu/net/if.h;h=251418f82331c0426e58707fe4473d454893b132;hb=HEAD | ||
// macOS IFF flags: https://opensource.apple.com/source/xnu/xnu-792/bsd/net/if.h.auto.html | ||
// AIX IFF flags: https://www.ibm.com/support/pages/how-hexadecimal-flags-displayed-ifconfig-are-calculated | ||
// FreeBSD IFF flags: https://www.freebsd.org/cgi/man.cgi?query=if_allmulti&apropos=0&sektion=0&manpath=FreeBSD+10-current&format=html | ||
clalancette marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#ifdef IFF_UP | ||
// Available in (at least) Linux, macOS, AIX, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_UP, "up")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_BROADCAST | ||
// Available in (at least) Linux, macOS, AIX, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_BROADCAST, "broadcast")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_DEBUG | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_DEBUG, "debug")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_LOOPBACK | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_LOOPBACK, "loopback")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_POINTOPOINT | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_POINTOPOINT, "pointopoint")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_NOTRAILERS | ||
// Available in (at least) Linux, macOS, AIX | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_NOTRAILERS, "notrailers")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_RUNNING | ||
// Available in (at least) Linux, macOS, AIX, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_RUNNING, "running")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_NOARP | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_NOARP, "noarp")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_PROMISC | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_PROMISC, "promisc")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_ALLMULTI | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_ALLMULTI, "allmulti")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_MASTER | ||
// Available in (at least) Linux | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_MASTER, "master")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_SLAVE | ||
// Available in (at least) Linux | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_SLAVE, "slave")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_MULTICAST | ||
// Available in (at least) Linux, macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_MULTICAST, "multicast")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_PORTSEL | ||
// Available in (at least) Linux | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_PORTSEL, "portsel")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_AUTOMEDIA | ||
// Available in (at least) Linux | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_AUTOMEDIA, "automedia")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_DYNAMIC | ||
// Available in (at least) Linux | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_DYNAMIC, "dynamic")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_OACTIVE | ||
// Available in (at least) macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_OACTIVE, "oactive")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_SIMPLEX | ||
// Available in (at least) macOS, AIX, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_SIMPLEX, "simplex")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_LINK0 | ||
// Available in (at least) macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_LINK0, "link0")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_LINK1 | ||
// Available in (at least) macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_LINK1, "link1")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_LINK2 | ||
// Available in (at least) macOS, BSD | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_LINK2, "link2")) | ||
goto error; | ||
#endif | ||
#ifdef IFF_D2 | ||
// Available in (at least) AIX | ||
if (!check_and_append_iff_flag(py_retlist, flags, IFF_D2, "d2")) | ||
goto error; | ||
#endif | ||
|
||
return py_retlist; | ||
|
||
error: | ||
Py_DECREF(py_retlist); | ||
if (sock != -1) | ||
close(sock); | ||
return NULL; | ||
} | ||
|
||
|
||
/* | ||
* Inspect NIC flags, returns a bool indicating whether the NIC is | ||
|
@@ -667,6 +848,7 @@ static PyMethodDef mod_methods[] = { | |
{"getpagesize", psutil_getpagesize_pywrapper, METH_VARARGS}, | ||
{"getpriority", psutil_posix_getpriority, METH_VARARGS}, | ||
{"net_if_addrs", psutil_net_if_addrs, METH_VARARGS}, | ||
{"net_if_flags", psutil_net_if_flags, METH_VARARGS}, | ||
{"net_if_is_running", psutil_net_if_is_running, METH_VARARGS}, | ||
{"net_if_mtu", psutil_net_if_mtu, METH_VARARGS}, | ||
{"setpriority", psutil_posix_setpriority, METH_VARARGS}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -808,7 +808,7 @@ def test_net_if_stats(self): | |
psutil.NIC_DUPLEX_UNKNOWN) | ||
for name, stats in nics.items(): | ||
self.assertIsInstance(name, str) | ||
isup, duplex, speed, mtu = stats | ||
isup, duplex, speed, mtu, flags = stats | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d83c959. |
||
self.assertIsInstance(isup, bool) | ||
self.assertIn(duplex, all_duplexes) | ||
self.assertIn(duplex, all_duplexes) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"may be AN empty string"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in d83c959.