pythonnetwork-programmingip-addresscidr

How can I check if an ip is in a network in Python?


Given an ip address (say 192.168.0.1), how do I check if it's in a network (say 192.168.0.0/24) in Python?

Are there general tools in Python for ip address manipulation? Stuff like host lookups, ip adddress to int, network address with netmask to int and so on? Hopefully in the standard Python library for 2.5.


Solution

  • This article shows you can do it with socket and struct modules without too much extra effort. I added a little to the article as follows:

    import socket,struct
    
    def makeMask(n):
        "return a mask of n bits as a long integer"
        return (2L<<n-1) - 1
    
    def dottedQuadToNum(ip):
        "convert decimal dotted quad string to long integer"
        return struct.unpack('L',socket.inet_aton(ip))[0]
    
    def networkMask(ip,bits):
        "Convert a network address to a long integer" 
        return dottedQuadToNum(ip) & makeMask(bits)
    
    def addressInNetwork(ip,net):
       "Is an address in a network"
       return ip & net == net
    
    address = dottedQuadToNum("192.168.1.1")
    networka = networkMask("10.0.0.0",24)
    networkb = networkMask("192.168.0.0",24)
    print (address,networka,networkb)
    print addressInNetwork(address,networka)
    print addressInNetwork(address,networkb)
    

    This outputs:

    False
    True
    

    If you just want a single function that takes strings it would look like this:

    import socket,struct
    
    def addressInNetwork(ip,net):
       "Is an address in a network"
       ipaddr = struct.unpack('L',socket.inet_aton(ip))[0]
       netaddr,bits = net.split('/')
       netmask = struct.unpack('L',socket.inet_aton(netaddr))[0] & ((2L<<int(bits)-1) - 1)
       return ipaddr & netmask == netmask