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