Skip to content

Commit

Permalink
669 windows broadcast addr (#2501)
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo authored Jan 23, 2025
1 parent d4b37d9 commit a509e5a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
4 changes: 3 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ XXXX-XX-XX

**Enhancements**

- 669_, [Windows]: `net_if_addrs()`_ also returns the ``broadcast`` address
instead of ``None``.
- 2480_: Python 2.7 is no longer supported. Latest version supporting Python
2.7 is psutil 6.1.X. Install it with: ``pip2 install psutil==6.1.*``.
- 2490_: removed long deprecated ``Process.memory_info_ex()`` method. It was
Expand All @@ -15,7 +17,7 @@ XXXX-XX-XX

**Bug fixes**

- 2496_, [Linux]: Avoid segfault (a cPython bug) on ``Process.memory_maps()``
- 2496_, [Linux]: Avoid segfault (a cPython bug) on ``Process.memory_maps()``
for processes that use hundreds of GBs of memory.

**Compatibility notes**
Expand Down
3 changes: 3 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,9 @@ Network
.. versionchanged:: 4.4.0 added support for *netmask* field on Windows which
is no longer ``None``.

.. versionchanged:: 7.0.0 added support for *broadcast* field on Windows
which is no longer ``None``.

.. function:: net_if_stats()

Return information about each NIC (network interface card) installed on the
Expand Down
18 changes: 17 additions & 1 deletion psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2228,14 +2228,30 @@ 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

if fam == _psplatform.AF_LINK:
# The underlying C function may return an incomplete MAC
# address in which case we fill it with null bytes, see:
# https://github.com/giampaolo/psutil/issues/786
separator = ":" if POSIX else "-"
while addr.count(separator) < 5:
addr += f"{separator}00"
ret[name].append(_common.snicaddr(fam, addr, mask, broadcast, ptp))

nt = _common.snicaddr(fam, addr, mask, broadcast, ptp)

# On Windows broadcast is None, so we determine it via
# ipaddress module.
if WINDOWS and fam in {socket.AF_INET, socket.AF_INET6}:
try:
broadcast = _common.broadcast_addr(nt)
except Exception as err: # noqa: BLE001
debug(err)
else:
if broadcast is not None:
nt._replace(broadcast=broadcast)

ret[name].append(nt)

return dict(ret)


Expand Down
30 changes: 26 additions & 4 deletions psutil/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Common objects shared by __init__.py and _ps*.py modules."""

# Note: this module is imported by setup.py so it should not import
# psutil or third-party modules.
"""Common objects shared by __init__.py and _ps*.py modules.
Note: this module is imported by setup.py, so it should not import
psutil or third-party modules.
"""

import collections
import enum
Expand Down Expand Up @@ -603,6 +603,28 @@ def conn_to_ntuple(fd, fam, type_, laddr, raddr, status, status_map, pid=None):
return sconn(fd, fam, type_, laddr, raddr, status, pid)


def broadcast_addr(addr):
"""Given the address ntuple returned by ``net_if_addrs()``
calculates the broadcast address.
"""
import ipaddress

if not addr.address or not addr.netmask:
return None
if addr.family == socket.AF_INET:
return str(
ipaddress.IPv4Network(
f"{addr.address}/{addr.netmask}", strict=False
).broadcast_address
)
if addr.family == socket.AF_INET6:
return str(
ipaddress.IPv6Network(
f"{addr.address}/{addr.netmask}", strict=False
).broadcast_address
)


def deprecated_method(replacement):
"""A decorator which can be used to mark a method as deprecated
'replcement' is the method name which will be called instead.
Expand Down
9 changes: 9 additions & 0 deletions psutil/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from psutil import POSIX
from psutil import SUNOS
from psutil import WINDOWS
from psutil._common import broadcast_addr
from psutil.tests import ASCII_FS
from psutil.tests import CI_TESTING
from psutil.tests import GITHUB_ACTIONS
Expand Down Expand Up @@ -858,6 +859,14 @@ def test_net_if_addrs(self):
elif addr.ptp:
assert addr.broadcast is None

# check broadcast address
if (
addr.broadcast
and addr.netmask
and addr.family in {socket.AF_INET, socket.AF_INET6}
):
assert addr.broadcast == broadcast_addr(addr)

if BSD or MACOS or SUNOS:
if hasattr(socket, "AF_LINK"):
assert psutil.AF_LINK == socket.AF_LINK
Expand Down

0 comments on commit a509e5a

Please sign in to comment.