Skip to content

Commit

Permalink
calculate broadcast addr via ipaddress lib
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Jan 23, 2025
1 parent d4b37d9 commit 45812fc
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
13 changes: 12 additions & 1 deletion psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2228,14 +2228,25 @@ 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}:
broadcast = _common.broadcast_addr(nt)
nt._replace(broadcast=broadcast)

ret[name].append(nt)

return dict(ret)


Expand Down
19 changes: 17 additions & 2 deletions psutil/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

# Note: this module is imported by setup.py so it should not import
# psutil or third-party modules.


import collections
import enum
import functools
Expand Down Expand Up @@ -603,6 +601,23 @@ 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):
import ipaddress

if addr.family == socket.AF_INET:
return str(
ipaddress.IPv4Network(
f"{addr.address}/{addr.netmask}", strict=False
).broadcast_address
)
elif 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
8 changes: 8 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,13 @@ def test_net_if_addrs(self):
elif addr.ptp:
assert addr.broadcast is None

# check broadcast address
if addr.broadcast 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 45812fc

Please sign in to comment.