[Python] Find internal Ipv6 address for directly connected interface

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
Notify of

0 Comments
Inline Feedbacks
View all comments