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