ipaddress - Indirizzi Internet
Scopo: Classi per lavorare con indirizzi di Protocollo Internet (IP)
Il modulo ipaddress include classi per lavorare con indirizzi di rete IPv4 e IPv6. Le classi supportano validazione, la ricerca di host e indirizzi su una rete e altre comuni operazioni.
Indirizzi
L'oggetto più basico rappresenta l'indirizzo di rete stesso. Si passi una stringa, intero, o sequenza di byte a ip_address()
per costruire un indirizzo. Il valore di ritorno sarà una istanza di IPv4Address
o IPv6Address
, a seconda del tipo di indirizzo usato.
# ipaddress_addresses.py
import binascii
import ipaddress
ADDRESSES = [
'10.9.0.6',
'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa',
]
for ip in ADDRESSES:
addr = ipaddress.ip_address(ip)
print('{!r}'.format(addr))
print(' versione IP:', addr.version)
print(' è privato:', addr.is_private)
print(' formato pacchettizzato:', binascii.hexlify(addr.packed))
print(' intero:', int(addr))
print()
Entrambe le classi forniscono varie rappresentazioni dell'indirizzo per scopi diversi, così come basiche asserzioni tipo se l'indirizzo è riservato per comunicazioni multicast oppure se si tratta di una rete privata.
$ python3 ipaddress_addresses.py IPv4Address('10.9.0.6') versione IP: 4 è privato: True formato pacchettizzato: b'0a090006' intero: 168361990 IPv6Address('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa') versione IP: 6 è privato: True formato pacchettizzato: b'fdfd87b5b4755e3eb1bce121a8eb14aa' intero: 337611086560236126439725644408160982186
Reti
Una rete viene definita come un intervallo di indirizzi, generalmente espressi con un indirizzo base e una maschera che indica quali porzioni dell'indirizzo rappresentano la rete e quali porzioni rimangono per rappresentare gli indirizzi su quella rete. La maschera può essere espressa esplicitamente, oppure usando come prefisso un valore di lunghezza, come nell'esempio di seguito.
# ipaddress_networks.py
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
print(' è privato:', net.is_private)
print(' broadcast:', net.broadcast_address)
print(' compresso:', net.compressed)
print(' con maschera net:', net.with_netmask)
print(' con maschera host:', net.with_hostmask)
print(' numero indirizzi:', net.num_addresses)
print()
Come per gli indirizzi, ci sono due classi rete per le reti IPv4 e IPv6. Ogni classe fornisce proprietà o metodi per accedere valori associati alla rete tipo l'indirizzo broadcast e gli indirizzi sulla rete disponibili per l'uso dagli
$ python3 ipaddress_networks.py IPv4Network('10.9.0.0/24') è privato: True broadcast: 10.9.0.255 compresso: 10.9.0.0/24 con maschera net: 10.9.0.0/255.255.255.0 con maschera host: 10.9.0.0/0.0.0.255 numero indirizzi: 256 IPv6Network('fdfd:87b5:b475:5e3e::/64') è privato: True broadcast: fdfd:87b5:b475:5e3e:ffff:ffff:ffff:ffff compresso: fdfd:87b5:b475:5e3e::/64 con maschera net: fdfd:87b5:b475:5e3e::/ffff:ffff:ffff:ffff:: con maschera host: fdfd:87b5:b475:5e3e::/::ffff:ffff:ffff:ffff numero indirizzi: 18446744073709551616
Una istanza di rete è iterabile, e mantiene gli indirizzi sulla rete.
# ipaddress_network_iterate.py
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
for i, ip in zip(range(3), net):
print(ip)
print()
Questo esempio stampa solo alcuni indirizzi, visto che una rete IPv6 può contenere molti più indirizzi di quanti ne possa contenere il risultato.
$ python3 ipaddress_network_iterate.py IPv4Network('10.9.0.0/24') 10.9.0.0 10.9.0.1 10.9.0.2 IPv6Network('fdfd:87b5:b475:5e3e::/64') fdfd:87b5:b475:5e3e:: fdfd:87b5:b475:5e3e::1 fdfd:87b5:b475:5e3e::2
L'iterazione sulla rete estrae gli indirizzi, ma non tutti sono validi per gli host. Ad esempio sono inclusi sia l'indirizzo base di una rete che quello di broadcast. Per trovare gli indirizzi che possono essere usati da normali host sulla rete, si usi il metodo hosts()
, che produce un generatore.
# ipaddress_network_iterate_hosts.py
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
for i, ip in zip(range(3), net.hosts()):
print(ip)
print()
Confrontando il risultato di questo esempio con quello precedente si nota che gli indirizzi host non includono i primi valori prodotti quando si itera sull'intera rete.
$ python3 ipaddress_network_iterate_hosts.py IPv4Network('10.9.0.0/24') 10.9.0.1 10.9.0.2 10.9.0.3 IPv6Network('fdfd:87b5:b475:5e3e::/64') fdfd:87b5:b475:5e3e::1 fdfd:87b5:b475:5e3e::2 fdfd:87b5:b475:5e3e::3
Oltre al protocollo di iterazione, viene supportato l'operatore in
per determinare su un indirizzo faccia parte di una rete.
# ipaddress_network_membership.py
import ipaddress
NETWORKS = [
ipaddress.ip_network('10.9.0.0/24'),
ipaddress.ip_network('fdfd:87b5:b475:5e3e::/64'),
]
ADDRESSES = [
ipaddress.ip_address('10.9.0.6'),
ipaddress.ip_address('10.7.0.31'),
ipaddress.ip_address(
'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa'
),
ipaddress.ip_address('fe80::3840:c439:b25e:63b0'),
]
for ip in ADDRESSES:
for net in NETWORKS:
if ip in net:
print('{}\nè su {}'.format(ip, net))
break
else:
print('{}\nnon è un su una rete conosciuta'.format(ip))
print()
L'implementazione di in
usa la maschera di rete per verificare l'indirizzo, quindi è molto più efficiente rispetto all'espansione della lista completa degli indirizzi sulla rete.
$ python3 ipaddress_network_membership.py 10.9.0.6 è su 10.9.0.0/24 10.7.0.31 non è un su una rete conosciuta fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa è su fdfd:87b5:b475:5e3e::/64 fe80::3840:c439:b25e:63b0 non è un su una rete conosciuta
Interfacce
Una interfaccia di rete rappresenta un indirizzo specifico su di una rete e può essere rappresentato da un indirizzo host e da un prefisso di rete o maschera di rete.
# ipaddress_interfaces.py
import ipaddress
ADDRESSES = [
'10.9.0.6/24',
'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64',
]
for ip in ADDRESSES:
iface = ipaddress.ip_interface(ip)
print('{!r}'.format(iface))
print('rete:\n ', iface.network)
print('ip:\n ', iface.ip)
print('IP con prefisso di lunghezza:\n ', iface.with_prefixlen)
print('maschera di rete:\n ', iface.with_netmask)
print('maschera host:\n ', iface.with_hostmask)
print()
L'oggetto interfaccia ha proprietà per accedere all'intera rete e agli indirizzi separatamente, così come ha diversi modi per esprimere l'interfaccia e la maschera di rete.
$ python3 ipaddress_interfaces.py IPv4Interface('10.9.0.6/24') rete: 10.9.0.0/24 ip: 10.9.0.6 IP con prefisso di lunghezza: 10.9.0.6/24 maschera di rete: 10.9.0.6/255.255.255.0 maschera host: 10.9.0.6/0.0.0.255 IPv6Interface('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64') rete: fdfd:87b5:b475:5e3e::/64 ip: fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa IP con prefisso di lunghezza: fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64 maschera di rete: fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/ffff:ffff:ffff:ffff:: maschera host: fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/::ffff:ffff:ffff:ffff
Vedere anche:
- ipaddresses
- La documentazione della libreria standard per questo modulo.
- PEP 3144
- Libreria per la manipolazione di inidirizzi IP per la libreria standard Python
- An introduction to the ipaddress module
- Introduzione al modulo ipaddress
- Wikipedia: Indirizzi IP
- Introduzione agli indirizzi IP e alle reti.
- Computer Networks (5th Edition)
- Di Andrew S. Tanenbaum e David J. Wetherall. Pubblicato da Pearson, 2010. ISBN-10: 0132126958