Valid local networks IPs are defined in
RFC 1918:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix) The most foolproof way of checking for local IPs is to use the various bitmasks. As I'm sure you know, IPv4 addresses are merely 32 bit integers, and it's fairly easy to write a function to convert them:
import socket, struct
def ip2int(ip):
return struct.unpack("I", socket.inet_aton(ip))[0]
This will only check for IPv4 addresses, mind. Still, I'm not sure IPv6 actually has local ranges - the address space is so large compared to IPv4 they might not be needed. Anyway, to check for local IPs in v4:
def inmask(ip, mask):
ip = ip2int(ip)
return ip & ip2int(mask) == ip
def islocal(ip):
return inmask(ip, "10.255.255.255") or
inmask(ip, "172.31.255.255") or
inmask(ip, "192.168.255.255")
You'd probably also want to combine this with socket.gethostbyname, which converts a hostname (such as "localhost") into an IP address. So maybe we should redefine islocal to:
def islocal(ip):
ip = socket.gethostbyname(ip)
return inmask(ip, "10.255.255.255") or
inmask(ip, "172.31.255.255") or
inmask(ip, "192.168.255.255")