def _checkNetWild(self, net, wild, net_check): """ Check if net_check is included in a network/wildcard :param net: network address :param mask: mask address :param net_check: network to find if it's included. :return: """ if '/' not in net_check: return False if net == '0.0.0.0': return True if not wild_is_contiguous(wild): net_list = split_non_contiguous(net, wild) else: net_list = [net + '/' + wild] if not wild_is_contiguous(net_check.split('/')[1]): net_check_list = split_non_contiguous( net_check.split('/')[0], net_check.split('/')[1]) else: net_check_list = [net_check] ''' Now we should have two lists without any non-contiguous IP included. Time to go through both of them checking that all networks to be "checked" are included ''' net_checked = [] for net1 in net_list: try: if net1.split('/')[1] == '0.0.0.0': # When using wildcard 0.0.0.0 is 255.255.255.255, but Netaddr use the 0.0.0.0 ask mask for ALL, so this needs to be changed net1 = net1.split('/')[0] + '/' + '255.255.255.255' net_object_ori = netaddr.IPNetwork(net1) except: return None if len(net_check_list) == 0: break net_check_temp = net_check_list[:] for net2 in net_check_temp: try: net_object_des = netaddr.IPNetwork(net2) except: return None if net2 in net_checked: continue if net_object_des in net_object_ori: net_checked.append(net2) net_check_list.remove(net2) return len(net_check_list) == 0
def split_non_contiguous_wild(self): """ It will try to split a rule with a non contiguous wildcard into several networks It's not going to split any rule in more than <NONCONT_LIMIT> networks :return: None """ end = False pos_list = -1 non_c = False if type(self.rules[0]) != str: # To avoid errors with "empty" policies while not end: pos_list += 1 if pos_list >= len(self.rules): break contig_num = self.rules[pos_list].get_contiguous() if 0 < contig_num <= NONCONT_LIMIT: # This is a limit in the number of "new rules" that can be created original_rule = self.rules[pos_list].get_rule() original_rule_number = pos_list + 1 if original_rule[1] != 'any' and original_rule[ 1] != '0.0.0.0/255.255.255.255': if not wild_is_contiguous( original_rule[1].split('/')[1]): netlistS = split_non_contiguous( original_rule[1].split('/')[0], original_rule[1].split('/')[1]) if len(netlistS) > 0: non_c = True else: # It's possible that we can't split the source (because it will create more than 128) # but still it's possible to split the destination netlistS = [original_rule[1]] else: netlistS = [original_rule[1]] else: netlistS = ['0.0.0.0/255.255.255.255'] if original_rule[2] != 'any' and original_rule[ 2] != '0.0.0.0/255.255.255.255': if not wild_is_contiguous( original_rule[2].split('/')[1]): netlistD = split_non_contiguous( original_rule[2].split('/')[0], original_rule[2].split('/')[1]) if len(netlistD) > 0: non_c = True else: netlistD = [original_rule[2]] else: netlistD = [original_rule[2]] else: netlistD = ['0.0.0.0/255.255.255.255'] # At this point we could have two different list with Source IPs and Dest IP, that together they # can't reach NONCONT_LIMIT networks. We just combine then. if non_c: source_dest_list = [] for a in netlistS: for b in netlistD: source_dest_list.append([a, b]) inew_number = original_rule_number for new_net in source_dest_list: if source_dest_list.index(new_net) == 0: self.rules[original_rule_number - 1].set_source(new_net[0]) self.rules[original_rule_number - 1].set_destination(new_net[1]) else: inew_number += 1 # The first entry we already have it newrule = FWRule() newrule.set_rule_data( sAddress=new_net[0], dAddress=new_net[1], dPort=original_rule[3], sPort=original_rule[4], protocol=original_rule[5], ACCEPT=original_rule[6], wildcard=True, name=original_rule[0], rulenumber=inew_number) if self.DEBUG: newrule.set_debug() self.rules.insert(inew_number - 1, newrule) pos_list = inew_number - 1 # Lists starts in 0! if self.get_rules_number() == pos_list or pos_list >= 50000: # 50000 seems to be a good safe value to break the while in case of any issue. I would not expect to split in more than 50k rules break self.renum_policy()
raise ImportError("The ipaddr module is not installed, exiting...") parser = argparse.ArgumentParser() parser.add_argument('network', help='Network with DSMO mask in the format X.X.X.X/Y.Y.Y.Y') parser.add_argument('--host', help='Display the split as HOST (/32)', action='store_true') args = parser.parse_args() dsmo_net = args.network if len(dsmo_net.split('/')) != 2 or len(dsmo_net.split('.')) != 7: print 'ERROR: Format of network not valid. It should be in the format X.X.X.X/Y.Y.Y.Y' quit() only_host = args.host net_split = tools.split_non_contiguous(dsmo_net.split('/')[0], dsmo_net.split('/')[1]) for net in net_split: ip = net.split('/')[0] netmask = tools.mask_to_wild(net.split('/')[1]) if only_host: if '/0.0.0.0' in net: # 0.0.0.0 in wildcard is host but in also means ANY is 'standard' way net = net.split('/')[0] + '/255.255.255.255' ip = ipaddr.IPv4Network(net) for host in list(ip): ip_host = str(host) print ip_host else: print ip + '/' + netmask