Search code examples
pythonlinuxipip-address

Python IP validation giving incorrect results


I'm trying to validate IP, gateway and subnet mask inputs using the ipaddress library, however I'm getting invalid results when I'm actually trying to use the validated network, which makes me think the validation is incorrect.

network = ipaddress.ip_network("103.162.136.145/255.255.255.252", strict=False)
for ip in ipaddress.ip_network(network):
    print(ip)

The following gives these valid IPs

103.162.136.144
103.162.136.145
103.162.136.146
103.162.136.147

However when I try to use it in linux, I get the following error;

localhost:~# ip addr flush dev eth0
localhost:~# ip addr add 103.162.136.145/255.255.255.252 dev ethd localhost:~# ip link set ethO up
localhost:~# ip route replace default via 103.162.136.144
ip: RTNETLINK answers: Invalid argument

The correct range shown should be actually

103.162.136.145
103.162.136.146

What am I doing wrong in the validation?

Edit - 103.162.136.145/255.255.255.252 is ip/subnet mask and 103.162.136.144 is gateway


Solution

  • As mentioned in the comment, this library seems to return the network address and the broadcast address which are the two additional addresses you did not expect. You then ask:

    that does seem so, but why is it doing it?

    This is an excellent question, but to the authors of the library. One way to pick their brain is to read their friendly manual.

    You did not specify the python version, but I've found this for python3:

    Network objects can be iterated to list all the addresses belonging to the network. For iteration, all hosts are returned, including unusable hosts (for usable hosts, use the hosts() method)

    https://docs.python.org/3/library/ipaddress.html#iteration

    So, instead of iterating over this network object - use a method that returns the usable addresses?

    I'm not a Python programmer, but something like this, maybe?

    for ip in network.hosts():
        print(ip)