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 sportan 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.

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('   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.

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('     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.

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()

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.

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()

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.

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('{}\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.

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('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