def getIpInfo(dev, ipaddrs=None, ipv4_gateway=None): """Report IP addresses of a device. if there are multiple primary IP addresses, report in ipv4addr the one that is in the same subnet of ipv4_gateway, if it is supplied.""" # TODO: support same logic for ipv6 if ipaddrs is None: ipaddrs = getIpAddrs() ipv4addr = ipv4netmask = '' ipv4addrs = [] ipv6addrs = [] def addr_in_gw_net(address, prefix, ipv4_gw): addr_net = IPNetwork('{}/{}'.format(address, prefix)) gw_net = IPNetwork('{}/{}'.format(ipv4_gw, prefix)) return addr_net in gw_net for addr in ipaddrs[dev]: if addr['scope'] == 'link': continue address_cidr = nl_addr.cidr_form(addr) # x.y.z.t/N if addr['family'] == 'inet': # ipv4 ipv4addrs.append(address_cidr) if nl_addr.is_primary(addr) and ipv4_gateway and ipv4addr == '': address, prefix = nl_addr.split(addr) if addr_in_gw_net(address, prefix, ipv4_gateway): ipv4addr = address ipv4netmask = str(IPNetwork(address_cidr).netmask) else: # ipv6 ipv6addrs.append(address_cidr) if ipv4addrs and ipv4addr == '': # If we didn't find an address in the gateway subnet (which is # legal if there is another route that takes us to the gateway) we # choose to report the first address ipv4addr = ipv4addrs[0].split('/')[0] ipv4netmask = str(IPNetwork(ipv4addrs[0]).netmask) return ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs