ipaddress — Direcciones de Internet¶
Propósito: | Clases para trabajar con direcciones del protocolo de Internet (IP) |
---|
El módulo ipaddress
incluye clases para trabajar con direcciones de red
IPv4 y IPv6. Las clases soportan la validación, encontrar direcciones y hosts
en una red, y otras operaciones comunes.
Direcciones¶
El objeto más básico representa la dirección de red propia. Pasa una cadena de
texto, números enteros o una secuencia de bytes a ip_address()
para
construir una dirección. El valor de retorno será una instancia
IPv4Address
o IPv6Address
, dependiendo del tipo de dirección que sea
usado.
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(' IP version:', addr.version)
print(' is private:', addr.is_private)
print(' packed form:', binascii.hexlify(addr.packed))
print(' integer:', int(addr))
print()
Ambas clases pueden proporcionar varias representaciones de la dirección para diferentes propósitos, así como responder afirmaciones básicas tales como si la dirección está reservada para la comunicación de multidifusión o si está en una red privada.
$ python3 ipaddress_addresses.py
IPv4Address('10.9.0.6')
IP version: 4
is private: True
packed form: b'0a090006'
integer: 168361990
IPv6Address('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa')
IP version: 6
is private: True
packed form: b'fdfd87b5b4755e3eb1bce121a8eb14aa'
integer: 337611086560236126439725644408160982186
Redes¶
Una red se define por un rango de direcciones. Usualmente expresada con una dirección base y una máscara que indica qué partes de la dirección representa la red, y qué partes quedan para representar direcciones en esa red. La máscara puede ser expresada explícitamente, o utilizando un valor de longitud de prefijo como en el siguiente ejemplo.
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(' is private:', net.is_private)
print(' broadcast:', net.broadcast_address)
print(' compressed:', net.compressed)
print(' with netmask:', net.with_netmask)
print(' with hostmask:', net.with_hostmask)
print(' num addresses:', net.num_addresses)
print()
Al igual que con las direcciones, hay dos clases de red para redes IPv4 e IPv6. Cada clase proporciona propiedades o métodos para acceder valores asociados con la red, como la dirección de transmisión y Las direcciones en la red están disponibles para que las usen los hosts.
$ python3 ipaddress_networks.py
IPv4Network('10.9.0.0/24')
is private: True
broadcast: 10.9.0.255
compressed: 10.9.0.0/24
with netmask: 10.9.0.0/255.255.255.0
with hostmask: 10.9.0.0/0.0.0.255
num addresses: 256
IPv6Network('fdfd:87b5:b475:5e3e::/64')
is private: True
broadcast: fdfd:87b5:b475:5e3e:ffff:ffff:ffff:ffff
compressed: fdfd:87b5:b475:5e3e::/64
with netmask: fdfd:87b5:b475:5e3e::/ffff:ffff:ffff:ffff::
with hostmask: fdfd:87b5:b475:5e3e::/::ffff:ffff:ffff:ffff
num addresses: 18446744073709551616
Una instancia de red es iterable y proporciona las direcciones en la red.
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()
Este ejemplo solo imprime algunas de las direcciones, ya que una red IPv6 puede contener muchas más direcciones de las que caben en la salida.
$ 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
Iterar sobre la red produce direcciones, pero no todas son válidas para los
hosts. Por ejemplo, se incluyen abas, la dirección base de la red y la
dirección de transmisión. Para encontrar las direcciones que pueden ser
utilizadas por hosts regulares en la red, usa el método hosts()
, que
produce un generador.
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()
Comparando de la salida de este ejemplo con el ejemplo anterior muestra que las direcciones de host no incluyen los primeros valores producidos al iterar sobre toda la red.
$ 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
Además del protocolo iterador, las redes admiten el operador in
para
determinar si una dirección es parte de una red.
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('{}\nis on {}'.format(ip, net))
break
else:
print('{}\nis not on a known network'.format(ip))
print()
La implementación de in
utiliza la máscara de red para probar la dirección,
por lo que es mucho más eficiente que expandir la lista completa de direcciones
en la red.
$ python3 ipaddress_network_membership.py
10.9.0.6
is on 10.9.0.0/24
10.7.0.31
is not on a known network
fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa
is on fdfd:87b5:b475:5e3e::/64
fe80::3840:c439:b25e:63b0
is not on a known network
Interfaces¶
Una interfaz de red representa una dirección específica en una red y puede estar representada por una dirección de host y un prefijo de red o máscara de red.
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('network:\n ', iface.network)
print('ip:\n ', iface.ip)
print('IP with prefixlen:\n ', iface.with_prefixlen)
print('netmask:\n ', iface.with_netmask)
print('hostmask:\n ', iface.with_hostmask)
print()
El objeto de la interfaz tiene propiedades para acceder a la red completa y a la dirección por separado, así como varias formas diferentes de expresar la interfaz y máscara de red.
$ python3 ipaddress_interfaces.py
IPv4Interface('10.9.0.6/24')
network:
10.9.0.0/24
ip:
10.9.0.6
IP with prefixlen:
10.9.0.6/24
netmask:
10.9.0.6/255.255.255.0
hostmask:
10.9.0.6/0.0.0.255
IPv6Interface('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64')
network:
fdfd:87b5:b475:5e3e::/64
ip:
fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa
IP with prefixlen:
fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64
netmask:
fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/ffff:ffff:ffff:ffff::
hostmask:
fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/::ffff:ffff:ffff:ffff
Ver también
- Documentación de la biblioteca estándar para ipaddress
- PEP 3144 – Manipulación de direcciones IP la biblioteca estándar de Python
- Una introducción al módulo ipaddress
- Wikipedia: Dirección IP – Una introducción a direcciones IP y redes.
- Computer Networks (5th Edition) – De Andrew S. Tanenbaum y David J. Wetherall. Publicado por Pearson, 2010. ISBN-10: 0132126958