Skip to content
Advertisement

Unable to get the network’s broadcast address with Python’s Ipaddress module

This is my code to get the broadcast address of my network:

def get_broadcast_address():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    ip_addr = ipaddress.IPv4Network(s.getsockname()[0])
    ip_address = ipaddress.IPv4Network(s.getsockname()[0] + "/" + str(ip_addr.netmask))
    return ip_address.broadcast_address

It first gets the local IP and then the subnet mask. I know I can do a binary calculation to obtain the broadcast address, but I am wondering why the above function does not work.

This outputs IPv4Address('192.168.1.47'). I expect it to output 192.168.1.255. Why does this happen?

Advertisement

Answer

Address IP can be used with different masks – all depend on user/admin decision and settings in your system – and you can’t expect that it will automatically use 24 for your address.

Socket gives IP but it doesn’t give mask.

If you not set mask in IPv4Network (or other command) then it will use 32 which later gives you 192.168.1.47 instead of expected 192.168.1.255

If you set manually 24 with your IP to create Interface then you can get expected network and expected broadcast.

import socket
import ipaddress

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))

socket_ip = s.getsockname()[0]
socket_ip = '192.168.1.47'
print('socket_ip   :', socket_ip)

network = ipaddress.IPv4Network(socket_ip)
print('network     :', network)
print('network mask:', network.netmask)

print('---')
mask = str(network.netmask)
print('mask:', mask)
ip_address = ipaddress.IPv4Interface(socket_ip + "/" + mask)
print('ip_address:', ip_address)
print('network   :', ip_address.network)
print('broadcast :', ip_address.network.broadcast_address)

print('---')
mask = '24'
print('mask:', mask)
ip_address = ipaddress.IPv4Interface(socket_ip + "/" + mask)
print('ip_address:', ip_address)
print('network   :', ip_address.network)
print('broadcast :', ip_address.network.broadcast_address)

Result

socket_ip   : 192.168.1.47
network     : 192.168.1.47/32
network mask: 255.255.255.255
---
mask: 255.255.255.255
ip_address: 192.168.1.47/32
network   : 192.168.1.47/32
broadcast : 192.168.1.47
---
mask: 24
ip_address: 192.168.1.47/24
network   : 192.168.1.0/24
broadcast : 192.168.1.255

To get correct mask you would have to ask system for this. Maybe with psutil or using subprocess with system command ipconfig (Windows) or ifconfig (Linux)

But if you have installed psutil then you don’t need previous method

import psutil

for interface, data in psutil.net_if_addrs().items(): 
    addr = data[0]
    print('interface:', interface)
    print('address  :', addr.address)
    print('netmask  :', addr.netmask)
    print('broadcast:', addr.broadcast)
    print('---')

Result (for my Linux)

interface: lo
address  : 127.0.0.1
netmask  : 255.0.0.0
broadcast: None
---
interface: wlp5s0
address  : 192.168.1.31
netmask  : 255.255.255.0
broadcast: 192.168.1.255
---
interface: docker0
address  : 172.17.0.1
netmask  : 255.255.0.0
broadcast: 172.17.255.255
---
interface: enp3s0
address  : 00:26:2d:84:78:64
netmask  : None
broadcast: ff:ff:ff:ff:ff:ff
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement