Python: Módulo: Netaddr
pip install netaddr
In [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.2.123/24')
In [3]: ip.network
Out[3]: IPAddress('192.168.2.0')
In [4]: ip.broadcast
Out[4]: IPAddress('192.168.2.255')
In [5]: ip.netmask
Out[5]: IPAddress('255.255.255.0')
In [6]: ip.hostmask
Out[6]: IPAddress('0.0.0.255')
In [7]: ip.ip
Out[7]: IPAddress('192.168.2.123')
In [8]: ip.version
Out[8]: 4
In [9]: ip.info
Out[9]:
{'IPv4': [{'date': '1993-05',
'designation': 'Administered by ARIN',
'prefix': '192/8',
'status': 'Legacy',
'whois': 'whois.arin.net'}]}
In [10]: ip.prefixlen
Out[10]: 24
In [11]: ip.size
Out[11]: 256
netaddr nos permite convertir las direcciones MAC a diferentes formatos y obtener información del fabricante de la MAC.
In [1]: from netaddr import *
In [2]: mac = EUI('e8:ea:6a:00:03:15')
In [3]: mac
Out[3]: EUI('E8-EA-6A-00-03-15')
In [4]: str(mac)
Out[4]: 'E8-EA-6A-00-03-15'
In [5]: str(mac.oui)
Out[5]: 'E8-EA-6A'
In [6]: str(mac.ei)
Out[6]: '00-03-15'
In [7]: str(mac.version)
Out[7]: '48'
In [8]: mac.dialect = mac_unix
In [9]: mac
Out[9]: EUI('e8:ea:6a:0:3:15')
In [10]: mac.dialect = mac_unix_expanded
In [11]: mac
Out[11]: EUI('e8:ea:6a:00:03:15')
In [12]: mac.dialect = mac_cisco
In [13]: mac
Out[13]: EUI('e8ea.6a00.0315')
In [14]: mac.dialect = mac_bare
In [15]: mac
Out[15]: EUI('E8EA6A000315')
In [16]: mac.oui.registration().org
Out[16]: 'StarTech.com'
Generar una lista con las IPs de un prefijo:
In [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.2.32/29')
In [3]: ips = list(ip)
In [4]: ips
Out[4]:
[IPAddress('192.168.2.32'),
IPAddress('192.168.2.33'),
IPAddress('192.168.2.34'),
IPAddress('192.168.2.35'),
IPAddress('192.168.2.36'),
IPAddress('192.168.2.37'),
IPAddress('192.168.2.38'),
IPAddress('192.168.2.39')]
Acceso a las IPs mediante un indice
n [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.2.32/29')
In [3]: ip[3]
Out[3]: IPAddress('192.168.2.35')
In [4]: ip[7]
Out[4]: IPAddress('192.168.2.39')
Acceso a sub rango de IPs, como por ejemplo las IPs usables (omitiendo la primera = network y la última = broadcast)
In [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.2.32/29')
In [3]: list(ip[1:6])
Out[3]:
[IPAddress('192.168.2.33'),
IPAddress('192.168.2.34'),
IPAddress('192.168.2.35'),
IPAddress('192.168.2.36'),
IPAddress('192.168.2.37')]
Acceso a las IPs pares o listado inverso
In [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.2.32/29')
In [3]: list(ip[0::2])
Out[3]:
[IPAddress('192.168.2.32'),
IPAddress('192.168.2.34'),
IPAddress('192.168.2.36'),
IPAddress('192.168.2.38')]
In [4]: list(ip[-1::-1])
Out[4]:
[IPAddress('192.168.2.39'),
IPAddress('192.168.2.38'),
IPAddress('192.168.2.37'),
IPAddress('192.168.2.36'),
IPAddress('192.168.2.35'),
IPAddress('192.168.2.34'),
IPAddress('192.168.2.33'),
IPAddress('192.168.2.32')]
Ordenando IPs y redes
In [1]: from netaddr import *
In [2]: ip_list = [
...: IPAddress('192.0.2.130'),
...: IPAddress('10.0.0.1'),
...: IPNetwork('192.0.2.128/28'),
...: IPNetwork('192.0.3.0/24'),
...: IPNetwork('192.0.2.0/24'),
...: IPNetwork('fe80::/64'),
...: IPAddress('::'),
...: IPNetwork('172.24/12')]
In [3]: ip_list
Out[3]:
[IPAddress('192.0.2.130'),
IPAddress('10.0.0.1'),
IPNetwork('192.0.2.128/28'),
IPNetwork('192.0.3.0/24'),
IPNetwork('192.0.2.0/24'),
IPNetwork('fe80::/64'),
IPAddress('::'),
IPNetwork('172.24.0.0/12')]
In [4]: ip_list.sort()
In [5]: ip_list
Out[5]:
[IPAddress('10.0.0.1'),
IPNetwork('172.24.0.0/12'),
IPNetwork('192.0.2.0/24'),
IPNetwork('192.0.2.128/28'),
IPAddress('192.0.2.130'),
IPNetwork('192.0.3.0/24'),
IPAddress('::'),
IPNetwork('fe80::/64')]
Sumarizar IPs y Rangos
In [1]: from netaddr import *
In [2]: ip_list = [ip for ip in IPNetwork('fe30::/120')]
In [3]: ip_list.append(IPNetwork('192.168.2.0/24'))
In [4]: ip_list.append(IPNetwork('192.168.3.0/24'))
In [6]: ip_list.append(IPNetwork('10.1.1.0/25'))
In [7]: ip_list.append(IPNetwork('10.1.1.128/25'))
In [8]: len(ip_list)
Out[8]: 260
In [9]: ip_list
Out[9]:
[IPAddress('fe30::'),
IPAddress('fe30::1'),
IPAddress('fe30::2'),
- - - OMITIDO - - -
IPAddress('fe30::fe'),
IPAddress('fe30::ff'),
IPNetwork('192.168.2.0/24'),
IPNetwork('192.168.3.0/24'),
IPNetwork('10.1.1.0/25'),
IPNetwork('10.1.1.128/25')]
In [10]: cidr_merge(ip_list)
Out[10]:
[IPNetwork('10.1.1.0/24'),
IPNetwork('192.168.2.0/23'),
IPNetwork('fe30::/120')]
Cálculos de supernet y subnets
In [1]: from netaddr import *
In [2]: ip = IPNetwork('192.168.0.0/16')
In [3]: subnets = list(ip.subnet(23))
In [4]: len(subnets)
Out[4]: 128
In [5]: subnets
Out[5]:
[IPNetwork('192.168.0.0/23'),
IPNetwork('192.168.2.0/23'),
- - - OMITIDO - - -
IPNetwork('192.168.252.0/23')]
IPNetwork('192.168.254.0/23')]
In [6]: subnets = list(ip.subnet(24))
In [7]: subnets
Out[7]:
[IPNetwork('192.168.0.0/24'),
- - - OMITIDO - - -
IPNetwork('192.168.255.0/24')]
In [8]: len(subnets)
Out[8]: 256
In [9]: subnets = list(ip.subnet(22))
In [10]: len(subnets)
Out[10]: 64
In [1]: from netaddr import *
In [2]: ip = IPNetwork('10.1.1.114')
In [3]: supernets = ip.supernet(22)
In [4]: supernets
Out[4]:
[IPNetwork('10.1.0.0/22'),
IPNetwork('10.1.0.0/23'),
IPNetwork('10.1.1.0/24'),
IPNetwork('10.1.1.0/25'),
IPNetwork('10.1.1.64/26'),
IPNetwork('10.1.1.96/27'),
IPNetwork('10.1.1.112/28'),
IPNetwork('10.1.1.112/29'),
IPNetwork('10.1.1.112/30'),
IPNetwork('10.1.1.114/31')]
Comprobar tipo de IP
In [1]: from netaddr import *
In [2]: IPAddress('192.168.2.1').is_unicast()
Out[2]: True
In [3]: IPAddress('fe80::1').is_unicast()
Out[3]: True
In [4]: IPAddress('239.192.0.1').is_multicast()
Out[4]: True
In [5]: IPAddress('ff00::1').is_multicast()
Out[5]: True
In [6]: IPAddress('172.24.0.1').is_private()
Out[6]: True
In [7]: IPAddress('10.0.0.1').is_private()
Out[7]: True
In [8]: IPAddress('fc00::1').is_private()
Out[8]: True
In [9]: IPAddress('253.0.0.1').is_reserved()
Out[9]: True
In [10]: IPAddress('255.255.254.0').is_netmask()
Out[10]: True
In [11]: IPAddress('0.0.1.255').is_hostmask()
Out[11]: True
In [12]: IPAddress('127.0.0.1').is_loopback()
Out[12]: True
In [13]: IPAddress('::1').is_loopback()
Out[13]: True
Comparaciones entre IPs
In [1]: from netaddr import *
In [2]: IPAddress('192.168.2.1') == IPAddress('192.168.2.1')
Out[2]: True
In [3]: IPAddress('192.168.2.1') < IPAddress('192.168.2.2')
Out[3]: True
In [4]: IPAddress('192.168.2.1') > IPAddress('192.168.2.2')
Out[4]: False
In [5]: IPAddress('192.168.2.1') != IPAddress('192.168.2.1')
Out[5]: False
In [6]: IPAddress('192.168.2.1') >= IPAddress('192.168.2.1')
Out[6]: True
In [7]: IPAddress('192.168.2.1') <= IPAddress('192.168.2.1')
Out[7]: True
In [8]: IPAddress('192.168.2.1') >= IPAddress('192.168.2.2')
Out[8]: False
In [9]: IPAddress('192.168.2.1') <= IPAddress('192.168.2.2')
Out[9]: True
In [10]: IPNetwork('192.168.2.0/24').cidr == IPNetwork('192.168.2.134/24').cidr
Out[10]: True
In [11]: IPNetwork('192.168.2.0/24') == IPNetwork('192.168.2.134/24')
Out[11]: True
In [12]: IPNetwork('192.168.2.0/24').ip == IPNetwork('192.168.2.134/24').ip
Out[12]: False
Comprobar si una red/ip está contenido dentro de una red.
from netaddr import *
ip1 = IPNetwork('192.168.2.64/27')
ip2 = IPNetwork('192.168.2.0/24')
ip3 = IPNetwork('192.168.0.0/22')
ip1 in ip2
True
ip1 in ip3
True
ip2 in ip1
False
ip2 in ip3
True
In [1]: from netaddr import *
In [2]: IPAddress('8.8.8.8').reverse_dns
Out[2]: '8.8.8.8.in-addr.arpa.'
In [3]: IPAddress('fe80::feeb:daed').reverse_dns
Out[3]: 'd.e.a.d.b.e.e.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.'
In [4]: IPAddress('192.168.3.65').reverse_dns
Out[4]: '65.3.168.192.in-addr.arpa.'
Más información netaddr