def extract_src_dest(self, acl, index): # this function extracts the source or destination. It expects a list that represents all the words in an access-list line, # and the index of the first word of the source or destination in that line. it will return a tuple of the index of the # last word in the source or destination, the IP, and the type of entry the IP is if acl[index] == "any" or acl[index] == "any4": ip_address = "any" ip_type = "any" elif acl[index] == "object": ip_address = acl[index + 1] ip_type = "object" index += 1 elif acl[index] == "object-group": ip_address = acl[index + 1] ip_type = "object-group" index += 1 elif acl[index] == "host": ip_address = IPv4Obj(acl[index + 1]) ip_type = "ip" index += 1 elif RE_BARE_SUBNET.match(' '.join(acl[index:index + 2])): ip_address_string = ' '.join(acl[index:index + 2]) ip_address = IPv4Obj(ip_address_string) ip_type = "ip" index += 1 else: raise Exception("could not determine source/destination type:" + str(acl[index:])) return (index, ip_address, ip_type)
def testVal_object_group_network_01(): """Test object group network results""" conf = [ "!", "name 1.1.2.20 loghost01", "!", "object-group network INSIDE_addrs", " network-object host loghost01", " network-object host 1.1.2.1", " network-object 1.1.2.2 255.255.255.255", " network-object 1.1.2.0 255.255.255.0", "!", ] cfg_factory = CiscoConfParse(conf, factory=True, syntax="asa") obj = cfg_factory.find_objects(r"object-group\snetwork")[0] result_correct_01 = [ IPv4Obj("1.1.2.20/32"), IPv4Obj("1.1.2.1/32"), IPv4Obj("1.1.2.2/32"), IPv4Obj("1.1.2.0/24"), ] result_correct_02 = [ "1.1.2.20", "1.1.2.1", "1.1.2.2", "1.1.2.0/255.255.255.0" ] # Ensure obj.name is set correctly assert obj.name == "INSIDE_addrs" assert obj.networks == result_correct_01 assert obj.network_strings == result_correct_02 ## Test obj.networks again to test the result_cache assert obj.networks == result_correct_01
def ip_network_object(self): try: return IPv4Obj('%s/%s' % (self.ipv4_addr, self.ipv4_netmask), strict=False).network except AttributeError: return IPv4Obj('%s/%s' % (self.ipv4_addr, self.ipv4_netmask), strict=False).network_address except: return self.default_ipv4_addr_object
def testIPv4Obj_contain(): ## Test ccp_util.IPv4Obj.__contains__() ## ## Test whether a prefix is or is not contained in another prefix results_correct = [ ("1.0.0.0/8", "0.0.0.0/0", True), # Is 1.0.0.0/8 in 0.0.0.0/0? ("0.0.0.0/0", "1.0.0.0/8", False), # Is 0.0.0.0/0 in 1.0.0.0/8? ("1.1.1.0/27", "1.0.0.0/8", True), # Is 1.1.1.0/27 in 1.0.0.0/8? ("1.1.1.0/27", "9.9.9.9/32", False), # Is 1.1.1.0/27 in 9.9.9.9/32? ("9.9.9.0/27", "9.9.9.9/32", False), # Is 9.9.9.0/27 in 9.9.9.9/32? ] for prefix1, prefix2, result_correct in results_correct: ## 'foo in bar' tests bar.__contains__(foo) test_result = IPv4Obj(prefix1) in IPv4Obj(prefix2) assert test_result == result_correct
def ipv4_standby_addr_object(self): """Return a ccp_util.IPv4Obj object representing the standby address on this interface; if there is no address, return IPv4Obj('127.0.0.1/32')""" try: return IPv4Obj('%s/%s' % (self.ipv4_standby_addr, self.ipv4_netmask)) except: return self.default_ipv4_addr_object
def testIPv4Obj_attributes(): ## Ensure that attributes are accessible and pass the smell test test_object = IPv4Obj("1.0.0.1 255.255.255.0") results_correct = [ ("ip", IPv4Address("1.0.0.1")), ("ip_object", IPv4Address("1.0.0.1")), ("netmask", IPv4Address("255.255.255.0")), ("prefixlen", 24), ("broadcast", IPv4Address("1.0.0.255")), ("network", IPv4Network("1.0.0.0/24")), ("network_object", IPv4Network("1.0.0.0/24")), ("hostmask", IPv4Address("0.0.0.255")), ("numhosts", 256), ("version", 4), ("is_reserved", False), ("is_multicast", False), ("is_private", False), ("as_cidr_addr", "1.0.0.1/24"), ("as_cidr_net", "1.0.0.0/24"), ("as_decimal", 16777217), ("as_decimal_network", 16777216), ("as_hex_tuple", ("01", "00", "00", "01")), ("as_binary_tuple", ("00000001", "00000000", "00000000", "00000001")), ("as_zeropadded", "001.000.000.001"), ("as_zeropadded_network", "001.000.000.000/24"), ] for attribute, result_correct in results_correct: assert getattr(test_object, attribute) == result_correct
def match_network_object_groups(subnet, object_groups, matched_objects): # takes in an IPv4Obj, a list of object_groups, and a list of network_objects that were previously matched. # iterates through the object_groups and returns a list of all object groups that matched either the subnet # or one of the objects in matched_objects matched_groups = [] for group in object_groups: # accumulate children #children = [] # doesn't work for child in group.children: # match any previously discovered network objects network_object = child.re_match(RE_NETWORK_OBJECT_OBJECT, default=None) # match any statically defined hosts if not network_object: ip_str = child.re_match(RE_NETWORK_OBJECT_HOST, default=None) if network_object: if is_substring_of_obj_list(network_object, matched_objects): matched_groups.append(group) #children.append(child) # doesn't work break elif ip_str: addr = IPv4Obj(ip_str) if addr in subnet: matched_groups.append(group) #children.append(child) # doesn't work break return matched_groups
def match_network_objects(subnet, network_objects): # takes in an IPv4Obj and a list of network_objects. returns a list of network_objects # that match based on if the network_object address(es) are in the subnet or if the subnet # is in the network_object if debug: print('matching network objects with specified subnet') matched_objects = [] for obj in network_objects: #print(obj) #print(obj.children) for child in obj.children: # match any statically defined hosts ip_str = child.re_match(RE_HOST, default=None) if not ip_str: # try to match subnet definitions ip_str = child.re_match(RE_SUBNET, default=None) if ip_str: # if we found an IP address, convert to IPv4Obj and check if it belongs # to the subnet we want, and vice-versa addr = IPv4Obj(ip_str) if addr in subnet: matched_objects.append(obj) break elif subnet in addr: matched_objects.append(obj) break # TODO: match any statically defined subnets return matched_objects
def network_object(self): try: if self.address_family == "ip": return IPv4Obj("%s/%s" % (self.network, self.netmask), strict=False) elif self.address_family == "ipv6": return IPv6Network("%s/%s" % (self.network, self.netmask)) except: return None
def network_object(self): try: if self.address_family=='ip': return IPv4Obj('%s/%s' % (self.network, self.netmask), strict=False) elif self.address_family=='ipv6': return IPv6Network('%s/%s' % (self.network, self.netmask)) except: return None
def in_ipv4_subnet(self, ipv4network=IPv4Obj('0.0.0.0/32', strict=False)): """Accept two string arguments for network and netmask, and return a boolean for whether this interface is within the requested subnet. Return None if there is no address on the interface""" if not (str(self.ipv4_addr_object.ip)=="127.0.0.1"): try: # Return a boolean for whether the interface is in that network and mask return self.ipv4_addr_object in ipv4network except: raise ValueError("FATAL: %s.in_ipv4_subnet(ipv4network={0}) is an invalid arg".format(ipv4network)) else: return None
def testIPv4Obj_parse(): ## Ensure that IPv4Obj can correctly parse various inputs test_strings = [ "1.0.0.1/24", "1.0.0.1/32", "1.0.0.1 255.255.255.0", "1.0.0.1 255.255.255.255", "1.0.0.1 255.255.255.0", "1.0.0.1 255.255.255.255", "1.0.0.1/255.255.255.0", "1.0.0.1/255.255.255.255", ] for test_string in test_strings: test_result = IPv4Obj(test_string) assert isinstance(test_result, IPv4Obj)
def networks(self): """Return a list of IPv4Obj objects which represent the address space allowed by This object-group""" ## FIXME: Implement object caching for other ASAConfigList objects ## Return a cached result if the networks lookup has already been done retval = list() for net_str in self.network_strings: ## Check the ASACfgList cache of network objects if not self.confobj._network_cache.get(net_str, False): net = IPv4Obj(net_str) self.confobj._network_cache[net_str] = net retval.append(net) else: retval.append(self.confobj._network_cache[net_str]) return retval
def testIPv4Obj_sort_01(): """Simple IPv4Obj sorting test""" cidr_addrs_list = [ "192.168.1.3/32", "192.168.1.2/32", "192.168.1.1/32", "192.168.1.4/15", ] result_correct = [ "192.168.1.4/15", # Shorter prefixes are "lower" than longer prefixes "192.168.1.1/32", "192.168.1.2/32", "192.168.1.3/32", ] obj_list = [IPv4Obj(ii) for ii in cidr_addrs_list] # Ensure we get the correct sorted order for this list assert [ii.as_cidr_addr for ii in sorted(obj_list)] == result_correct
def testIPv4Obj_sort_02(): """Complex IPv4Obj sorting test""" cidr_addrs_list = [ "192.168.1.1/32", "192.168.0.1/32", "192.168.0.2/16", "192.168.0.3/15", "0.0.0.0/32", "0.0.0.1/31", "16.0.0.1/8", "0.0.0.2/30", "127.0.0.0/0", "16.0.0.0/1", "128.0.0.0/1", "16.0.0.0/4", "16.0.0.3/4", "0.0.0.0/0", "0.0.0.0/8", ] result_correct = [ "0.0.0.0/0", "127.0.0.0/0", "16.0.0.0/1", "0.0.0.0/8", # for the same network, longer prefixlens sort "higher" than shorter prefixlens "0.0.0.2/30", # for the same network, longer prefixlens sort "higher" than shorter prefixlens "0.0.0.1/31", # for the same network, longer prefixlens sort "higher" than shorter prefixlens "0.0.0.0/32", "16.0.0.0/4", "16.0.0.3/4", "16.0.0.1/8", # for the same network, longer prefixlens sort "higher" than shorter prefixlens "128.0.0.0/1", "192.168.0.3/15", "192.168.0.2/16", "192.168.0.1/32", "192.168.1.1/32", ] obj_list = [IPv4Obj(ii) for ii in cidr_addrs_list] # Ensure we get the correct sorted order for this list assert [ii.as_cidr_addr for ii in sorted(obj_list)] == result_correct
def testIPv4Obj_attributes(): ## Ensure that attributes are accessible and pass the smell test test_object = IPv4Obj('1.0.0.1 255.255.255.0') results_correct = [ ('ip', IPv4Address('1.0.0.1')), ('ip_object', IPv4Address('1.0.0.1')), ('netmask', IPv4Address('255.255.255.0')), ('prefixlen', 24), ('broadcast', IPv4Address('1.0.0.255')), ('network', IPv4Network('1.0.0.0/24')), ('network_object', IPv4Network('1.0.0.0/24')), ('hostmask', IPv4Address('0.0.0.255')), ('numhosts', 256), ('version', 4), ('is_reserved', False), ('is_multicast', False), ('is_private', False), ('as_decimal', 16777217), ('as_hex_tuple', ('01', '00', '00', '01')), ('as_binary_tuple', ('00000001', '00000000', '00000000', '00000001')), ] for attribute, result_correct in results_correct: assert getattr(test_object, attribute) == result_correct
def testIPv4Obj_gt_02(): """Simple greater-than test - different network number""" assert IPv4Obj("1.1.1.0/24") > IPv4Obj("1.1.0.0/24")
def testIPv4Obj_neq_01(): """Simple in-equality test fail (ref - Github issue #180)""" assert IPv4Obj("1.1.1.1/24") != ""
def testIPv4Obj_recursive(): """IPv4Obj() should be able to parse itself""" obj = IPv4Obj(IPv4Obj("1.1.1.1/24")) assert str(obj.ip_object) == "1.1.1.1" assert obj.prefixlen == 24
def __init__(self, *args, **kwargs): super(BaseASAIntfLine, self).__init__(*args, **kwargs) self.ifindex = None # Optional, for user use self.default_ipv4_addr_object = IPv4Obj('127.0.0.1/32', strict=False)
def testIPv4Obj_eq_02(): """Simple equality test""" obj1 = IPv4Obj("1.1.1.1/24") obj2 = IPv4Obj("1.1.1.0/24") assert obj1 != obj2
def testIPv4Obj_contains_03(): """Test __contains__ method""" obj1 = IPv4Obj("1.1.1.255/32") obj2 = IPv4Obj("1.1.1.0/24") assert obj1 in obj2
def testIPv4Obj_lt_03(): """Simple less-than test - different prefixlen""" obj1 = IPv4Obj("1.1.1.0/24") obj2 = IPv4Obj("1.1.0.0/23") assert obj2 < obj1
def testIPv4Obj_lt_02(): """Simple less-than test - different network number""" obj1 = IPv4Obj("1.1.1.0/24") obj2 = IPv4Obj("1.1.0.0/24") assert obj2 < obj1
def testIPv4Obj_lt_01(): """Simple less-than test - same network number""" obj1 = IPv4Obj("1.1.1.1/24") obj2 = IPv4Obj("1.1.1.0/24") assert obj2 < obj1
def testIPv4Obj_gt_03(): """Simple greater-than test - different prefixlen""" assert IPv4Obj("1.1.1.0/24") > IPv4Obj("1.1.0.0/23")
def testIPv4Obj_gt_01(): """Simple greater-than test - same network number""" assert IPv4Obj("1.1.1.1/24") > IPv4Obj("1.1.1.0/24")
config = CiscoConfParse(args.in_file) pickle.dump(config, fh) print("Done.") sys.exit() # if we made it this far, we have an input! try to cast our inputs to things and see if shit explodes! subnet = None source = None dest = None if args.ip: # try to cast to IPv4Obj for syntax checking subnet = args.ip.split(',') for i, ip in enumerate(subnet): try: subnet[i] = IPv4Obj(ip) except: print('Invalid subnet/IP "%s"' % (ip)) sys.exit() if args.source: source = args.source.split(',') for i, ip in enumerate(source): try: source[i] = IPv4Obj(ip) except: print('Invalid subnet/IP "%s"' % (ip)) sys.exit() if args.dest: dest = args.dest.split(',') for i, ip in enumerate(dest): try: