import netifaces
import ipaddress
def ipv6_netmask_to_prefixlen(ipv6_netmask):
"""
:param ipv6_netmask: IPv6 netmask, e.g. ffff:ffff:ffff:ffff::
:return count: An integer of prefixlen, e.g. 64
"""
bitCount = [0, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff]
prefixlen = 0
try:
for w in ipv6_netmask.split(':'):
if not w or int(w, 16) == 0: break
prefixlen += bitCount.index(int(w, 16))
except:
raise SyntaxError('Bad NetMask')
return prefixlen
def find_internal_ip_by_device_ip(device_ip):
"""
For a given device ip, lookup the internal IP address of aGalaxy that can
be used for a NAT mapping.
:param device_ip: IPv4 or IPv6 address of remote host
:return ip_address: The interface IP address connect with the host
"""
device_net = ipaddress.ip_address(unicode(device_ip))
for iface in netifaces.interfaces():
for family, addresses in netifaces.ifaddresses(iface).items():
for item in addresses:
if family not in [netifaces.AF_INET, netifaces.AF_INET6]:
continue
try:
ip_network = None
# IPv4
if is_ipv4 and family == netifaces.AF_INET:
ip_network = ipaddress.ip_network(u'{ip_address}/{netmask}'.format(
ip_address=item["addr"],
netmask=item["netmask"]), strict=False)
# IPv6
if is_ipv6 and family == netifaces.AF_INET6:
# IPv6 with netmask is not support in package ipaddress
# Turn it to prefixlen before creating ip_network
prefixlen = ipv6_netmask_to_prefixlen(item["netmask"])
ip_network = ipaddress.ip_network(u'{ip_address}/{prefixlen}'.format(
ip_address=item["addr"],
prefixlen=prefixlen), strict=False)
# device_ip matched the subnet
if ip_network and device_net in ip_network:
ip_address = item["addr"]
return ip_address
except:
pass
raise Exception("Incorrect IP settings")
Subscribe
0 Comments