Étant donné une adresse IP (disons 192.168.0.1), comment puis-je vérifier si elle fait partie d’un réseau (disons 192.168.0.0/24) en Python ?
En utilisant ipaddress
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1') in ipaddress.ip_network('192.168.0.0/24')
True
Si vous souhaitez évaluer un grand nombre d’adresses IP de cette manière, vous devrez probablement calculer le masque de réseau à l’avance, comme suit
n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)
Ensuite, pour chaque adresse, calculez la représentation binaire à l’aide de l’une des méthodes suivantes
a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0] # Seulement IPv4
Enfin, il suffit de vérifier :
in_network = (a & mask) == netw
J’aime bien utiliser netaddr pour cela :
from netaddr import CIDR, IP
if IP("192.168.0.1") in CIDR("192.168.0.0/24"):
print "192.168.0.1 se trouve bien dans 192.168.0.0/24"
La nouvelle version de netaddr fonctionne comme suit:
from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
print "192.168.0.1 se trouve bien dans 192.168.0.0/24"
Pour les utilisateur de Python3
import ipaddress
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/24')
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/16')
Sortie :
False
True
En utilisant Python >= 3.7 ipaddress:
import ipaddress
address = ipaddress.ip_address("192.168.0.1")
network = ipaddress.ip_network("192.168.0.0/16")
print(network.supernet_of(ipaddress.ip_network(f"{address}/{address.max_prefixlen}")))
Vérifier si 192.168.0.1 se trouve dans 192.168.0.0/16 est la même chose que de vérifier si 192.168.0.1/32 est un sous-réseau de 192.168.0.0/16