import ipaddress import logging log = logging.getLogger(__name__) def to_ip(data, *args): # for py2 support need to convert data to unicode: if _ttp_["python_major_version"] is 2: ipaddr_data = unicode(data) elif _ttp_["python_major_version"] is 3: ipaddr_data = data if "ipv4" in args: if "/" in ipaddr_data or " " in ipaddr_data: return ipaddress.IPv4Interface(ipaddr_data.replace(" ", "/")), None else: return ipaddress.IPv4Address(ipaddr_data), None elif "ipv6" in args: if "/" in ipaddr_data: return ipaddress.IPv6Interface(ipaddr_data), None else: return ipaddress.IPv6Address(ipaddr_data), None elif "/" in ipaddr_data or " " in ipaddr_data: return ipaddress.ip_interface(ipaddr_data.replace(" ", "/")), None else: return ipaddress.ip_address(ipaddr_data), None def is_ip(data, *args): try: _ = to_ip(data, *args) return data, True except: return data, False def to_net(data, *args): # for py2 support need to convert data to unicode: if _ttp_["python_major_version"] is 2: ipaddr_data = unicode(data) elif _ttp_["python_major_version"] is 3: ipaddr_data = data if "ipv4" in args: return ipaddress.IPv4Network(ipaddr_data), None elif "ipv6" in args: return ipaddress.IPv6Network(ipaddr_data), None else: return ipaddress.ip_network(ipaddr_data), None def to_cidr(data): """Method to convet 255.255.255.0 like mask to CIDR prefix len such as 24 """ try: ret = sum([bin(int(x)).count('1') for x in data.split('.')]) return ret, None except: log.error("ttp_functions.match.to_cidr: '{}' is not a valid netmask".format(data)) return data, None def ip_info(data, *args): if isinstance(data, str): try: ip_obj = to_ip(data, *args)[0] except ValueError: return data, None else: ip_obj = data if isinstance(ip_obj, ipaddress.IPv4Interface) or isinstance(ip_obj, ipaddress.IPv6Interface): ret = { 'compressed': ip_obj.compressed, 'exploded': ip_obj.exploded, 'hostmask': str(ip_obj.hostmask), 'ip': str(ip_obj.ip), 'is_link_local': ip_obj.is_link_local, 'is_loopback': ip_obj.is_loopback, 'is_multicast': ip_obj.is_multicast, 'is_private': ip_obj.is_private, 'is_reserved': ip_obj.is_reserved, 'is_unspecified': ip_obj.is_unspecified, 'max_prefixlen': ip_obj.max_prefixlen, 'netmask': str(ip_obj.netmask), 'network': str(ip_obj.network), 'version': ip_obj.version, 'with_hostmask': ip_obj.with_hostmask, 'with_netmask': ip_obj.with_netmask, 'with_prefixlen': ip_obj.with_prefixlen, 'broadcast_address': str(ip_obj.network.broadcast_address), 'network_address': str(ip_obj.network.network_address), 'num_addresses': ip_obj.network.num_addresses, 'hosts': ip_obj.network.num_addresses - 2, 'prefixlen': ip_obj.network.prefixlen } elif isinstance(ip_obj, ipaddress.IPv4Address) or isinstance(ip_obj, ipaddress.IPv6Address): ret = { 'ip' : str(ip_obj), 'compressed': ip_obj.compressed, 'exploded': ip_obj.exploded , 'is_link_local': ip_obj.is_link_local, 'is_loopback': ip_obj.is_loopback, 'is_multicast': ip_obj.is_multicast, 'is_private': ip_obj.is_private, 'is_reserved': ip_obj.is_reserved, 'is_unspecified': ip_obj.is_unspecified, 'max_prefixlen': ip_obj.max_prefixlen, 'version': ip_obj.version } else: ret = data return ret, None def cidr_match(data, prefix): # try to get value from TTP vars variables prefix = _ttp_["parser_object"].vars.get(prefix, prefix) # convert data to ipaddress object: if isinstance(data, str): try: ip_obj = to_ip(data)[0] except ValueError: return data, None else: ip_obj = data # create ipaddress ipnetwork object out of prefix ip_net = to_net(prefix)[0] if isinstance(ip_obj, ipaddress.IPv4Interface) or isinstance(ip_obj, ipaddress.IPv6Interface): # if object is ipnetwork, can check it as is: check = ip_obj.network.overlaps(ip_net) elif isinstance(ip_obj, ipaddress.IPv4Address) or isinstance(ip_obj, ipaddress.IPv6Address): # if object is ipaddress, need to convert it itno ipinterface with /32 mask: if ip_obj.version is 4: # for py2 support need to convert data to unicode: if _ttp_["python_major_version"] is 2: ipaddr_data = unicode("{}/32".format(str(ip_obj))) elif _ttp_["python_major_version"] is 3: ipaddr_data = "{}/32".format(str(ip_obj)) ip_obj = ipaddress.IPv4Interface(ipaddr_data) elif ip_obj.version is 6: # for py2 support need to convert data to unicode: if _ttp_["python_major_version"] is 2: ipaddr_data = unicode("{}/128".format(str(ip_obj))) elif _ttp_["python_major_version"] is 3: ipaddr_data = "{}/128".format(str(ip_obj)) ip_obj = ipaddress.IPv6Interface(ipaddr_data) check = ip_obj.network.overlaps(ip_net) else: check = None return data, check