summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2015-08-05 02:54:04 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2015-08-05 02:54:04 +0200
commit725dfb4faa3240fe5730e5abc72dfbb74efe66e9 (patch)
tree1cb94b0d366f5c68e9000a8dc1d9639965b802ce
parent11969913e6718cb7c40ed31be3a3c025815f0931 (diff)
downloadpsutil-663-ptp-ifaces.tar.gz
#663: ptp addresses linux implementation663-ptp-ifaces
-rw-r--r--HISTORY.rst1
-rw-r--r--README.rst12
-rw-r--r--docs/index.rst23
-rw-r--r--examples/ifconfig.py2
-rw-r--r--psutil/__init__.py15
-rw-r--r--psutil/_common.py2
-rw-r--r--psutil/_psutil_posix.c33
-rw-r--r--test/test_psutil.py8
8 files changed, 71 insertions, 25 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index e1d94a28..780cef27 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -6,6 +6,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues
**Enhancements**
- #648: CI test integration for OSX. (patch by Jeff Tang)
+- #663: net_if_addrs() now returns point-to-point addresses (for VPNs).
**Bug fixes**
diff --git a/README.rst b/README.rst
index 56465614..3979924d 100644
--- a/README.rst
+++ b/README.rst
@@ -166,12 +166,12 @@ Network
...]
>>>
>>> psutil.net_if_addrs()
- {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
- 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
+ {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
+ snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
+ snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
+ 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
+ snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
+ snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>>
>>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
diff --git a/docs/index.rst b/docs/index.rst
index 44301922..43f44593 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -410,28 +410,33 @@ Network
Return the addresses associated to each NIC (network interface card)
installed on the system as a dictionary whose keys are the NIC names and
value is a list of namedtuples for each address assigned to the NIC.
- Each namedtuple includes 4 fields:
+ Each namedtuple includes 5 fields:
- **family**
- **address**
- **netmask**
- **broadcast**
+ - **ptp**
*family* can be either
`AF_INET <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
`AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
or :const:`psutil.AF_LINK`, which refers to a MAC address.
- *address* is the primary address, *netmask* and *broadcast* may be ``None``.
+ *address* is the primary address and it is always set.
+ *netmask*, *broadcast* and *ptp* may be ``None``.
+ *ptp* stands for "point to point" and references the destination address on a
+ point to point interface (tipically a VPN).
+ *broadcast* and *ptp* are mutually exclusive.
Example::
>>> import psutil
>>> psutil.net_if_addrs()
- {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
- 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
+ {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
+ snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
+ snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
+ 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
+ snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
+ snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>>
See also `examples/ifconfig.py <https://github.com/giampaolo/psutil/blob/master/examples/ifconfig.py>`__
@@ -446,6 +451,8 @@ Network
*New in 3.0.0*
+ *Changed in 3.1.2:* *ptp* field was added.
+
.. function:: net_if_stats()
Return information about each NIC (network interface card) installed on the
diff --git a/examples/ifconfig.py b/examples/ifconfig.py
index e7a436cc..1f1ee985 100644
--- a/examples/ifconfig.py
+++ b/examples/ifconfig.py
@@ -71,6 +71,8 @@ def main():
print(" broadcast : %s" % addr.broadcast)
if addr.netmask:
print(" netmask : %s" % addr.netmask)
+ if addr.ptp:
+ print(" p2p : %s" % addr.ptp)
print("")
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 79b369c9..385b80a4 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -1749,17 +1749,22 @@ def net_if_addrs():
"""Return the addresses associated to each NIC (network interface
card) installed on the system as a dictionary whose keys are the
NIC names and value is a list of namedtuples for each address
- assigned to the NIC. Each namedtuple includes 4 fields:
+ assigned to the NIC. Each namedtuple includes 5 fields:
- family
- address
- netmask
- broadcast
+ - ptp
'family' can be either socket.AF_INET, socket.AF_INET6 or
psutil.AF_LINK, which refers to a MAC address.
- 'address' is the primary address, 'netmask' and 'broadcast'
- may be None.
+ 'address' is the primary address and it is always set.
+ 'netmask' and 'broadcast' and 'ptp' may be None.
+ 'ptp' stands for "point to point" and references the destination
+ address on a point to point interface (tipically a VPN).
+ 'broadcast' and 'ptp' are mutually exclusive.
+
Note: you can have more than one address of the same family
associated with each interface.
"""
@@ -1769,7 +1774,7 @@ def net_if_addrs():
rawlist = _psplatform.net_if_addrs()
rawlist.sort(key=lambda x: x[1]) # sort by family
ret = collections.defaultdict(list)
- for name, fam, addr, mask, broadcast in rawlist:
+ for name, fam, addr, mask, broadcast, ptp in rawlist:
if has_enums:
try:
fam = socket.AddressFamily(fam)
@@ -1782,7 +1787,7 @@ def net_if_addrs():
# We re-set the family here so that repr(family)
# will show AF_LINK rather than AF_PACKET
fam = _psplatform.AF_LINK
- ret[name].append(_common.snic(fam, addr, mask, broadcast))
+ ret[name].append(_common.snic(fam, addr, mask, broadcast, ptp))
return dict(ret)
diff --git a/psutil/_common.py b/psutil/_common.py
index e9acf595..9f5c06f2 100644
--- a/psutil/_common.py
+++ b/psutil/_common.py
@@ -215,7 +215,7 @@ suser = namedtuple('suser', ['name', 'terminal', 'host', 'started'])
sconn = namedtuple('sconn', ['fd', 'family', 'type', 'laddr', 'raddr',
'status', 'pid'])
# psutil.net_if_addrs()
-snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast'])
+snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast', 'ptp'])
# psutil.net_if_stats()
snicstats = namedtuple('snicstats', ['isup', 'duplex', 'speed', 'mtu'])
diff --git a/psutil/_psutil_posix.c b/psutil/_psutil_posix.c
index 183dab0e..5967df0c 100644
--- a/psutil/_psutil_posix.c
+++ b/psutil/_psutil_posix.c
@@ -17,6 +17,7 @@
#ifdef __linux
#include <netdb.h>
#include <linux/if_packet.h>
+#include <linux/if.h>
#endif // end linux
#if defined(__FreeBSD__) || defined(__APPLE__)
@@ -163,6 +164,7 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
PyObject *py_address = NULL;
PyObject *py_netmask = NULL;
PyObject *py_broadcast = NULL;
+ PyObject *py_ptp = NULL;
if (py_retlist == NULL)
return NULL;
@@ -185,20 +187,41 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family);
if (py_netmask == NULL)
goto error;
+
#ifdef __linux
- py_broadcast = psutil_convert_ipaddr(ifa->ifa_ifu.ifu_broadaddr, family);
+ if (ifa->ifa_flags & IFF_BROADCAST) {
+ py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
+ Py_INCREF(Py_None);
+ py_ptp = Py_None;
+ }
+ else if (ifa->ifa_flags & IFF_POINTOPOINT) {
+ py_ptp = psutil_convert_ipaddr(ifa->ifa_dstaddr, family);
+ Py_INCREF(Py_None);
+ py_broadcast = Py_None;
+ }
+ else {
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ py_broadcast = Py_None;
+ py_ptp = Py_None;
+ }
#else
+ // TODO
py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
+ Py_INCREF(Py_None);
+ py_ptp = Py_None;
#endif
- if (py_broadcast == NULL)
+
+ if ((py_broadcast == NULL) || (py_ptp == NULL))
goto error;
py_tuple = Py_BuildValue(
- "(siOOO)",
+ "(siOOOO)",
ifa->ifa_name,
family,
py_address,
py_netmask,
- py_broadcast
+ py_broadcast,
+ py_ptp
);
if (! py_tuple)
@@ -209,6 +232,7 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
Py_DECREF(py_address);
Py_DECREF(py_netmask);
Py_DECREF(py_broadcast);
+ Py_DECREF(py_ptp);
}
freeifaddrs(ifaddr);
@@ -222,6 +246,7 @@ error:
Py_XDECREF(py_address);
Py_XDECREF(py_netmask);
Py_XDECREF(py_broadcast);
+ Py_XDECREF(py_ptp);
return NULL;
}
diff --git a/test/test_psutil.py b/test/test_psutil.py
index 27806f37..27ffd716 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -1069,13 +1069,19 @@ class TestSystemAPIs(unittest.TestCase):
s = socket.socket(af, socktype, proto)
with contextlib.closing(s):
s.bind(sa)
- for ip in (addr.address, addr.netmask, addr.broadcast):
+ for ip in (addr.address, addr.netmask, addr.broadcast,
+ addr.ptp):
if ip is not None:
# TODO: skip AF_INET6 for now because I get:
# AddressValueError: Only hex digits permitted in
# u'c6f3%lxcbr0' in u'fe80::c8e0:fff:fe54:c6f3%lxcbr0'
if addr.family != AF_INET6:
check_ip_address(ip, addr.family)
+ # broadcast and ptp addresses are mutually exclusive
+ if addr.broadcast:
+ self.assertIsNone(addr.ptp)
+ elif addr.ptp:
+ self.assertIsNone(addr.broadcast)
if BSD or OSX or SUNOS:
if hasattr(socket, "AF_LINK"):