def pch_handle_ixpm(self,filename,mypath,reserved_tree): doc=self.file_opener(filename,mypath,3) table = doc.read() doc.close() table=table.split('\n') tree=SubnetTree.SubnetTree() IXP_IP= {} sub_to_ixp={} dirty={} hstring=string_handler.string_handler() count=0 dumped_ixps=[] for i in range(0,len(table)-1): temp_string=table[i+1].split(',') if len(temp_string)>1: ip=hstring.extract_ip(temp_string[1],'IP') for inode in ip: inode=hstring.clean_ip(inode,'IP') if hstring.is_valid_ip_address(inode,'IP'): subnet=hstring.extract_ip(temp_string[0],'Subnet') for snode in subnet: snode=hstring.clean_ip(snode,'Subnet') if hstring.is_valid_ip_address(snode,'Subnet'): tree[snode]=snode if inode in tree and inode not in IXP_IP.keys() and inode not in dumped_ixps and inode not in reserved_tree: IXP_IP[inode]=[temp_string[3].replace(' ','')] elif inode in IXP_IP.keys(): if IXP_IP[inode]!=[temp_string[3].replace(' ','')]: IXP_IP.pop(inode,None) dumped_ixps.append(inode) elif inode not in dumped_ixps: dirty[inode]=[temp_string[3].replace(' ','')] return IXP_IP,dirty
def extract_pfx(self,json_pfx,ixlan_dict,id_to_names,reserved_tree): handler=string_handler.string_handler() pfxs_dict={} i=0 temp_subnet_tree=SubnetTree.SubnetTree() denied_subs=[] for node in json_pfx: subnet=handler.extract_ip(node['prefix'],'Subnet') for s in subnet: if handler.is_valid_ip_address(s,'Subnet') and s not in reserved_tree: ixpfx=s ixlan_id=node['ixlan_id'] if ixlan_id in ixlan_dict.keys(): ix_id=ixlan_dict[ixlan_id] if ix_id in id_to_names.keys() and s not in pfxs_dict and s not in denied_subs: pfxs_dict[s]=id_to_names[ix_id] temp_subnet_tree[s]=ix_id elif s in pfx_dict: del_flag=True new_item=['',''] if handler.string_comparison(pfxs_dict[s][0],id_to_names[ix_id][0]): del_flag=False new_item=[pfxs_dict[s][0],''] if handler.string_comparison(pfxs_dict[s][1],id_to_names[ix_id][1]): del_flag=False new_item=[new_item[0],pfxs_dict[s][1]] if del_flag: pfxs_dict.pop(s,None) temp_subnet_tree.remove(s) denied_subs.append(s) else: pfxs_dict[s]=new_item return (pfxs_dict,temp_subnet_tree)
def pch_handle_sub(self,filename,mypath,reserved_tree): handled_string=string_handler.string_handler() doc=self.file_opener(filename,mypath,1) table = doc.read() doc.close() table=table.split('\n') IXP={} subnets={} denied_subs=[] for i in range(0,len(table)-1): temp_string=table[i+1].split(', ') if len(temp_string)>5: mykey=temp_string[0] myip=temp_string[6] myip=handled_string.extract_ip(myip,'Subnet') for ips in myip: ips=handled_string.clean_ip(ips,'Subnet') if ips!='': if handled_string.is_valid_ip_address(ips,'Subnet') and ips not in subnets.keys() and ips not in denied_subs and ips not in reserved_tree: subnets[ips]=mykey IXP[mykey]=[temp_string[1],ips] elif ips in subnets.keys(): if subnets[ips]!=mykey: IXP.pop(subnets[ips],None) subnets.pop(ips,None) denied_subs.append(ips) return (IXP)
def print_traIXroute_dest(self,input_IP,outputfile,mypath): outputfile='Output/'+outputfile write_path=mypath+'/Output' if os.path.exists(write_path)==False: os.makedirs(write_path) try: string_handle=string_handler.string_handler() dns_name='*' output_IP='*' if string_handle.is_valid_ip_address(input_IP,'IP'): try: dns_name=socket.gethostbyaddr(input_IP)[0] except: pass output_IP=input_IP else: try: output_IP=socket.gethostbyname(input_IP) except: pass dns_name=input_IP data='traIXroute to '+dns_name+' ('+output_IP+').' print (data) f = open(outputfile, 'a') f.write(data+'\n') f.close() except: print('---> Could not open output file, try to execute traIXroute with administrator rights. Exiting.') exit(0)
def print_traIXroute_dest(self, input_IP, outputfile, mypath): outputfile = 'Output/' + outputfile write_path = mypath + '/Output' if os.path.exists(write_path) == False: os.makedirs(write_path) try: string_handle = string_handler.string_handler() dns_name = '*' output_IP = '*' if string_handle.is_valid_ip_address(input_IP, 'IP'): try: dns_name = socket.gethostbyaddr(input_IP)[0] except: pass output_IP = input_IP else: try: output_IP = socket.gethostbyname(input_IP) except: pass dns_name = input_IP data = 'traIXroute to ' + dns_name + ' (' + output_IP + ').' print(data) f = open(outputfile, 'a') f.write(data + '\n') f.close() except: print( '---> Could not open output file, try to execute traIXroute with administrator rights. Exiting.' ) exit(0)
def pch_handle_sub(self, filename, mypath, reserved_tree): handled_string = string_handler.string_handler() doc = self.file_opener(filename, mypath, 1) table = doc.read() doc.close() table = table.split('\n') IXP = {} subnets = {} denied_subs = [] for i in range(0, len(table) - 1): temp_string = table[i + 1].split(',') if len(temp_string) > 5: mykey = temp_string[0] myip = temp_string[6] myip = handled_string.extract_ip(myip, 'Subnet') for ips in myip: ips = handled_string.clean_ip(ips, 'Subnet') if ips != '': if handled_string.is_valid_ip_address( ips, 'Subnet' ) and ips not in subnets.keys( ) and ips not in denied_subs and ips not in reserved_tree: subnets[ips] = mykey IXP[mykey] = [temp_string[1], ips] elif ips in subnets.keys(): if subnets[ips] != mykey: IXP.pop(subnets[ips], None) subnets.pop(ips, None) denied_subs.append(ips) return (IXP)
def trace_call(self, IP_name, classic, arguments): # Instead of an IP address, a domain name has been given as destination to send the probe, the domain name is reversed. string_handle = string_handler.string_handler() if not string_handle.is_valid_ip_address(IP_name, 'IP'): try: IP_name = socket.gethostbyname(IP_name) except: print( 'Wrong address format.\nExpected an IPv4 format or a valid url.' ) exit(0) elif not string_handle.check_input_ip(IP_name): print( 'Wrong address format.\nExpected an IPv4 format or a valid url.' ) exit(0) if classic == 1: [route, mytime] = self.scamper_call(IP_name, arguments) if len(route) == 0: print( '--> Scamper returned an empty IP path. You may use "sudo" in the beginning or the scamper arguments might be wrong.' ) elif classic == 0: [route, mytime] = self.traceroute_call(IP_name, arguments) if len(route) == 0: print( '--> Traceroute returned an empty IP path. You may use "sudo" in the beginning.' ) return [route, mytime]
def unite_long_short(self, table_long, table_short): final_table = {} dict_m = dict_merger.dict_merger() temp_table = dict_m.inner_join(table_long, table_short) str_handle = string_handler.string_handler() for node in temp_table: myvalues = temp_table[node] if len(myvalues) > 2: new_item = [myvalues[0], myvalues[1]] elif len(myvalues) > 1: new_item = [myvalues[0], myvalues[0]] else: new_item = ['', ''] Subnet = str_handle.extract_ip(myvalues[2], 'Subnet')[0] if Subnet != '' and Subnet not in final_table.keys(): final_table[Subnet] = new_item elif Subnet in final_table.keys(): del_flag = True if str_handle.string_comparison(final_table[Subnet][0], new_item[0]): del_flag = False new_item = [final_table[Subnet][0], ''] if str_handle.string_comparison(final_table[Subnet][0], new_item[1]): del_flag = False new_item = [new_key[0], final_table[Subnet][1]] if del_flag: final_table.pop(Subnet, None) else: final_table[Subnet] = new_item return final_table
def unite_long_short(self,table_long,table_short): final_table={} dict_m=dict_merger.dict_merger() temp_table=dict_m.inner_join(table_long,table_short) str_handle=string_handler.string_handler() for node in temp_table: myvalues=temp_table[node] if len(myvalues)>4: new_item=[myvalues[0],myvalues[3],myvalues[1],myvalues[2]] elif len(myvalues)>3: new_item=[myvalues[0],myvalues[0],myvalues[1],myvalues[2]] else: new_item=['','','',''] Subnet=str_handle.extract_ip(myvalues[4],'Subnet')[0] if Subnet!='' and Subnet not in final_table.keys(): final_table[Subnet]=new_item elif Subnet in final_table.keys(): del_flag=True if str_handle.string_comparison(final_table[Subnet][0],new_item[0]): del_flag=False new_item=[final_table[Subnet][0],''] if str_handle.string_comparison(final_table[Subnet][0],new_item[1]): del_flag=False new_item=[new_key[0],final_table[Subnet][1]] if del_flag: final_table.pop(Subnet, None) else: final_table[Subnet]=new_item return final_table
def check_names(self,rule,expression,current,i,encounter_type,str_to_chk,ixp_long,ixp_short): string_handle=string_handler.string_handler() if len(rule)>i+1 and len(ixp_long)>current+1 and encounter_type[current]!='IXP prefix': [final1,final2]=self.find_numbers(rule,str_to_chk,current,True) if final1=='' or final2=='': return True if self.is_int(final1) and self.is_int(final2): flag=(string_handle.string_comparison(ixp_long[current],ixp_long[current+1]) or string_handle.string_comparison(ixp_short[current],ixp_short[current+1])) if (final1==final2 and not flag) or (final1!=final2 and flag): return False return True
def check_names(self,rule,expression,current,i,encounter_type,str_to_chk,ixp_long,ixp_short): string_handle=string_handler.string_handler() if len(rule)>i+1 and len(ixp_long)>current+1 and encounter_type[current]!='IXP prefix': [final1,final2]=self.find_numbers(rule,str_to_chk,current,True) if final1=='' or final2=='': return True if self.is_int(final1) and self.is_int(final2): flag=(string_handle.string_comparison(ixp_long[current],ixp_long[current+1]) or string_handle.string_comparison(ixp_short[current],ixp_short[current+1])) if (final1==final2 and not flag) or (final1!=final2 and flag): return False return True
def check_edges(self,rule,path_asn,current,str_to_chk,ixp_long,ixp_short): [final1,final2]=self.find_numbers(rule,str_to_chk,current,False) if final1=='' or final2=='': return True if self.is_int(final1) and self.is_int(final2) and 'AS_M' in str_chk: if (final1==final2 and path_asn[current-1]!=path_asn[current+1]) or (final1!=final2 and path_asn[current-1]==path_asn[current+1]): return False elif self.is_int(final1) and self.is_int(final2) and 'IXP_IP' in str_chk: string_hanlde=string_handler.string_handler() flag=(string_handle.string_comparison(ixp_long[current-1],ixp_long[current+1]) or string_handle.string_comparison(ixp_short[current-1],ixp_short[current+1])) if (final1==final2 and not flag) or (final1!=final2 and flag): return False return True
def check_edges(self,rule,path_asn,current,str_to_chk,ixp_long,ixp_short): [final1,final2]=self.find_numbers(rule,str_to_chk,current,False) if final1=='' or final2=='': return True if self.is_int(final1) and self.is_int(final2) and 'AS_M' in str_chk: if (final1==final2 and path_asn[current-1]!=path_asn[current+1]) or (final1!=final2 and path_asn[current-1]==path_asn[current+1]): return False elif self.is_int(final1) and self.is_int(final2) and 'IXP_IP' in str_chk: string_hanlde=string_handler.string_handler() flag=(string_handle.string_comparison(ixp_long[current-1],ixp_long[current+1]) or string_handle.string_comparison(ixp_short[current-1],ixp_short[current+1])) if (final1==final2 and not flag) or (final1!=final2 and flag): return False return True
def pch_handle_ixpm(self, filename, mypath, reserved_tree): doc = self.file_opener(filename, mypath, 3) table = doc.read() doc.close() table = table.split('\n') tree = SubnetTree.SubnetTree() IXP_IP = {} sub_to_ixp = {} dirty = {} hstring = string_handler.string_handler() count = 0 dumped_ixps = [] for i in range(0, len(table) - 1): temp_string = table[i + 1].split(',') if len(temp_string) > 1: ip = hstring.extract_ip(temp_string[1], 'IP') for inode in ip: inode = hstring.clean_ip(inode, 'IP') if hstring.is_valid_ip_address(inode, 'IP'): subnet = hstring.extract_ip(temp_string[0], 'Subnet') for snode in subnet: snode = hstring.clean_ip(snode, 'Subnet') if hstring.is_valid_ip_address(snode, 'Subnet'): tree[snode] = snode if inode in tree and inode not in IXP_IP.keys( ) and inode not in dumped_ixps and inode not in reserved_tree: IXP_IP[inode] = [ temp_string[3].replace(' ', '') ] elif inode in IXP_IP.keys(): if IXP_IP[inode] != [ temp_string[3].replace(' ', '') ]: IXP_IP.pop(inode, None) dumped_ixps.append(inode) elif inode not in dumped_ixps: dirty[inode] = [ temp_string[3].replace(' ', '') ] return IXP_IP, dirty
def assign_names(self,sname1,sname2,lname1,lname2): string_handle=string_handler.string_handler() d3=[] if string_handle.string_comparison(lname1,lname2): d3.append(lname1) elif lname1=='' and lname2!='' : d3.append(lname2) elif lname1!='' and lname2=='': d3.append(lname1) else: d3.append('') if string_handle.string_comparison(sname1,sname2): d3.append(sname1) elif sname1=='' and sname2!='': d3.append(sname2) elif sname1!='' and sname2=='': d3.append(sname1) else: d3.append('') return d3
def extract_ip(self,json_ip,temp_subnet_tree,add_subnet_tree,reserved_tree): handler=string_handler.string_handler() ixp_to_asn={} dirty_ixp_to_names={} dirty_ixp2asn={} dumped_ixps=[] for node in json_ip: if node['ipaddr4'] is None: temp='' else: temp=node['ipaddr4'] ips=handler.extract_ip(temp,'IP') for ixpip in ips: if handler.is_valid_ip_address(ixpip,'IP'): ixid='no_id' # the ix id for the ip must be the same with the prefix's one # in which the ip belongs. if ixpip in temp_subnet_tree: ixid=temp_subnet_tree[ixpip] # if the prefix ix id is the same with the ip ix id or the ip is given by the user, # add the ip. if ((ixid != 'no_id' and ixid == node['ix_id']) and ixpip not in ixp_to_asn.keys() and ixpip not in dumped_ixps and ixpip not in reserved_tree)or ixpip in add_subnet_tree: ixp_to_asn[ixpip]=[str(node['asn'])] elif ixpip in ixp_to_asn.keys(): if ixp_to_asn[ixpip]!= [str(node['asn'])]: dumped_ixps.append(ixpip) ixp_to_asn.pop(ixpip,None) # else consider the IP as dirty. elif ixpip not in dumped_ixps: dirty_ixp2asn[ixpip]=[str(node['asn'])] dirty_ixp_to_names[ixpip]=['',node['name']] return (ixp_to_asn,dirty_ixp_to_names,dirty_ixp2asn)
def trace_call(self,IP_name,classic,arguments): # Instead of an IP address, a domain name has been given as destination to send the probe, the domain name is reversed. string_handle=string_handler.string_handler() if not string_handle.is_valid_ip_address(IP_name,'IP'): try: IP_name=socket.gethostbyname(IP_name) except: print('Wrong address format.\nExpected an IPv4 format or a valid url.') exit(0) elif not string_handle.check_input_ip(IP_name): print('Wrong address format.\nExpected an IPv4 format or a valid url.') exit(0) if classic==1: [route,mytime]=self.scamper_call(IP_name,arguments) if len(route)==0: print('--> Scamper returned an empty IP path. You may use "sudo" in the beginning or the scamper arguments might be wrong.') elif classic==0: [route,mytime]=self.traceroute_call(IP_name,arguments) if len(route)==0: print('--> Traceroute returned an empty IP path. You may use "sudo" in the beginning.') return [route,mytime]
def parser(self,argv): inputIP='' outputfile='output' download=0 valid1=0 valid2=0 other_output_flag=0 search=0 source=0 help=0 merge_flag=0 classic=-1 asn_print=False arguments='' print_rule=False stringh=string_handler.string_handler() check_argv=[x for x in argv] input_file='input.txt' temp_argv=' '.join(argv) if temp_argv.count('[')>1 or temp_argv.count(']')>1: print ('Expected only one [ and only one ]. Exiting.') exit(0) elif '[' in temp_argv and ']' not in temp_argv: print ('Expected one ]. Exiting.') exit(0) elif ']' in temp_argv and '[' not in temp_argv: print ('Expected one [. Exiting.') exit(0) elif '[' in temp_argv and ']' in temp_argv: try: if len(temp_argv.split(']'))>1: temp_argv=temp_argv.split('[')[0]+temp_argv.split(']')[1] else: temp_argv=temp_argv.split('[')[0] except: print(' Wrong syntax. Exiting.') exit(0) # Sanity checks for arguments as well as defining if the destination IP will be extracted from the cmd or input file. if temp_argv.count("-i")>1 or temp_argv.count("-d")>1 or temp_argv.count("-t")>1 or argv.count('')>1 or temp_argv.count("-h")>1 or temp_argv.count("-u")>1 or argv.count("-m")>1 or temp_argv.count("-o")>1 or temp_argv.count("-s")>1: print('Each traIXroute option must be used only once.') exit(0) elif ('-i' in temp_argv or '-d' in temp_argv) and ('-t' not in temp_argv and '-s' not in temp_argv): print('Please, choose one probing tool. Exiting.') exit(0) elif ('-t' in temp_argv or '-s' in temp_argv) and ('-i' not in temp_argv and '-d' not in temp_argv): print('Please, choose one destination IP. Exiting.') exit(0) elif '-i' in temp_argv and '-d' in temp_argv: print ('Please, choose only one method to set the destination IP to probe. Exiting.') exit(0) elif '-i' in temp_argv and ( '-t' in temp_argv or '-s' in temp_argv): [inputIP,check_argv]=self.extract_element(argv,'-i',False,check_argv) try: check_argv.remove('-i') except: pass valid1=1 elif '-d' in temp_argv and ( '-t' in temp_argv or '-s' in temp_argv): [input_file,check_argv]=self.extract_element(argv,'-d',False,check_argv) try: check_argv.remove('-d') except: pass source=1 valid1=1 inputIP=input_file # -s for scamper, -t for traceroute (mandatory options). if '-s' in temp_argv and '-t' in temp_argv: print('Please, choose only one probing tool. Exiting.') exit(0) elif '-s' not in temp_argv and '-t' not in temp_argv and '-u' not in temp_argv and '-m' not in temp_argv and '-h' not in temp_argv: print('Please, choose one probing tool. Exiting.') exit(0) if '-s' in temp_argv and ('-i' in temp_argv or '-d' in temp_argv): [arguments,check_argv]=self.extract_element(argv,'-s',True,check_argv) if stringh.extract_ip(arguments, 'IP')!=[]: print('Wrong input, please give an IPv4 address or a url using the -i option.') exit(0) valid2=1 classic=1 try: check_argv.remove('-s') except: pass elif '-t' in temp_argv and ('-i' in temp_argv or '-d' in temp_argv): classic=0 [arguments,check_argv]=self.extract_element(argv,'-t',True,check_argv) temp=stringh.extract_ip(arguments,'IP') try: check_argv.remove('-t') except: pass if len(temp)>0: inputIP=temp[0] arguments=arguments.replace(inputIP,'') if '-6' in arguments: print('IPv6 is not supported yet.') exit(0) valid2=1 if '-asn' in temp_argv: asn_print=True try: check_argv.remove('-asn') except: pass if '-rule' in temp_argv: print_rule=True try: check_argv.remove('-rule') except: pass # The name of the output file, output.txt is the default name. if '-o' in temp_argv: [outputfile,check_argv]=self.extract_element(argv,'-o',False,check_argv) if outputfile=='': print('Expected a file name. Exiting.') exit(0) try: check_argv.remove('-o') except: pass other_output_flag=1 if '-u' in temp_argv: download=1 try: check_argv.remove('-u') except: pass if '-m' in temp_argv: merge_flag=1 try: check_argv.remove('-m') except: pass # A valid traIXroute command stands when a destination IP address and a probing tool have been properly set. if valid1 and valid2: search=1 elif not download and not merge_flag: help=1 if '-h' in temp_argv: help=1 try: check_argv.remove('-h') except: pass check_input=''.join(check_argv) if len(check_input): print('Wrong set of arguments for traIXroute. Exiting.') exit(0) if (not search and not download and not merge_flag) or help: print('usage: sudo python3 traIXroute.py -i <IP> -s <arguments>\nAlternative arguments:\n-h: Prints a list of the available command line options.\n-i <IP/URL>: The IP/URL destination to send the probe.\n-d <filename>: The file with the list of IP addresses.\n-u: Updates the databases.\n-o: Specifies the output file name.\n-m: Exports the database to two distinct files the ixp_prefixes.txt and ixp_membership.txt.\n-asn: Enables printing the ASN for each IP hop.\n-rule: Enables printing the IXP detection rule in the IXP Hops.\n-s "options": Calls traIXroute with scamper and (optional) scamper arguments.\n-t "options": Calls traIXroute with traceroute and (optional) traceroute arguments.') return inputIP,outputfile,download,search,classic,source,input_file,arguments,other_output_flag,merge_flag,asn_print,print_rule
def check_rules(self,rule,path_asn,path_cur,ixp_long,ixp_short,asn2names,encounter_type): if len(rule)>len(path_asn): return False for i in range(0,len(rule)): if len(path_asn)> path_cur+i-1: if 'IXP_IP' in rule[i] and '!AS_M' in rule[i] and 'IXP prefix' not in encounter_type[path_cur+i-1]: return False elif 'IXP_IP' in rule[i] and 'AS_M' in rule[i] and '!' not in rule[i] and 'IXP IP' not in encounter_type[path_cur+i-1]: return False elif ('IXP_IP' not in rule[i] or '!AS_M' not in rule[i]) and 'IXP prefix' in encounter_type[path_cur+i-1]: return False elif ('IXP_IP' not in rule[i] or 'AS_M' not in rule[i]) and 'IXP IP' in encounter_type[path_cur+i-1]: return False # Applies each condition of the condition part of the candidate rule onto the path. string_h=string_handler.string_handler() check=0 for i in range(0,len(rule)): current=path_cur+i-1 #The current condition of the condition part of the rule. expression=rule[i] # Checking for IXP membership based on a non-IXP IP. if '!AS_M' in expression and 'and' not in expression and path_cur!=current: # Finds the path_asn in the routeview path_asn dict. If not, an assessment is not possible. check=check+1 if path_asn[current]=='*' and encounter_type[current]!='IXP prefix': return False if encounter_type[path_cur]=='IXP IP' or encounter_type[path_cur]=='IXP prefix': as_names='' if path_asn[current] in asn2names.keys(): as_names=asn2names[path_asn[current]] ix_long=ixp_long[path_cur] ix_short=ixp_short[path_cur] else: as_names='' if path_asn[path_cur] in asn2names.keys(): as_names=asn2names[path_asn[path_cur]] ix_long=ixp_long[current] ix_short=ixp_short[current] for node in as_names: for name in node: if (string_h.string_comparison(ix_long,name) or string_h.string_comparison(ix_short,name)) : return False if not self.check_number(rule,expression,path_asn,current,i,encounter_type,'!AS_M'): return False elif 'AS_M' in expression and 'and' not in expression and path_cur!=current: if path_asn[current]=='*' and encounter_type[current]!='IXP prefix': return False check=check+1 flag=False if encounter_type[path_cur]=='IXP IP' or encounter_type[path_cur]=='IXP prefix': as_names='' if path_asn[current] in asn2names.keys(): as_names=asn2names[path_asn[current]] ix_long=ixp_long[path_cur] ix_short=ixp_short[path_cur] else: as_names='' if path_asn[path_cur] in asn2names.keys(): as_names=asn2names[path_asn[path_cur]] ix_long=ixp_long[current] ix_short=ixp_short[current] for node in (as_names): for name in node: if string_h.string_comparison(ix_long,name) or string_h.string_comparison(ix_short,name): flag=1 break if flag==0: return False if not self.check_number(rule,expression,path_asn,current,i,encounter_type,'AS_M'): return False # Checking for IXP IP or Prefix based on either IXP membership or Prefixes data. if 'IXP_IP' in expression and '!AS_M' in expression: check=check+1 if not self.check_names(rule,expression,current,i,encounter_type,'IXP_IP',ixp_long,ixp_short): return False elif not self.check_number(rule,expression,path_asn,current,i,encounter_type,'!AS_M'): return False elif 'IXP_IP' in expression and 'AS_M' in expression: check=check+1 if not self.check_names(rule,expression,current,i,encounter_type,'IXP_IP',ixp_long,ixp_short): return False elif not self.check_number(rule,expression,path_asn,current,i,encounter_type,'AS_M'): return False if len(rule)>2 and len(path_asn)> current+1: check=check+1 if not self.check_edges(rule,path_asn,current,'AS_M',ixp_long,ixp_short): return False elif not self.check_edges(rule,path_asn,current,'IXP_IP',ixp_long,ixp_short): return False if check>0: return True else: return False
def main(self,argv): # Calls the parser for the arguments. (inputIP, outputfile,download,search,classic,source,input_file,arguments,other_output_flag,merge_flag,asn_print,print_rule)=self.parser(argv) mypath=sys.path[0] exact_time=datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S") if not other_output_flag: outputfile=outputfile+'_'+exact_time+'.txt' num_ips=0 # Calls the download module if needed. if download or (not os.path.exists(mypath+'/database') and (search or merge_flag)): print ('Updating the database...') mydownload=download_files.download_files() outcome=mydownload.download_files(mypath) if mydownload: print ('Database was downloaded successfully.') else: print ('Database was not downloaded. Exiting...') exit(0) if search: if source: try: f=open(input_file,'r') except: print('Input file was not found. Exiting.') exit(0) input_list=f.read() f.close input_list=input_list.split('\n') temp_point=0 inputIP=input_list[temp_point] # Instead of an IP address, a domain name has been given as destination to send the probe, the domain name is reversed. string_handle=string_handler.string_handler() if not string_handle.is_valid_ip_address(inputIP,'IP'): try: IP_name=socket.gethostbyname(inputIP) except: print('Wrong input IP address format.\nExpected an IPv4 format or a valid url.') exit(0) elif not string_handle.check_input_ip(inputIP): print('Wrong input IP address format.\nExpected an IPv4 format or a valid url.') exit(0) detection_rules_node=detection_rules.detection_rules() [rules,assmt]=detection_rules_node.rules_extract('rules.txt') final_rules_hit=[0 for x in range(0,len(rules))] myinput=trace_tool.trace_tool() # Extract info from the database folder. if search or merge_flag: mydb=database_extract.database() [final_ixp2asn,final_sub2names,reserved_sub_tree,final_asn2ip,final_ixp2name,asn_routeviews,Sub_tree,dirty_ixp2asn,additional_info_tree]=mydb.dbextract('ixp_subnets','ixp_exchange','ixp_membership','ix.json','netixlan.json','ixpfx.json','ixlan.json','routeviews','additional_info.txt',merge_flag,mypath) if search: output=traIXroute_output.traIXroute_output() output.print_args(classic, search,arguments) while(1): # Loads the IP list after parsing the input file. if source: inputIP=input_list[temp_point] # Calls the module responsible for probing. output.print_traIXroute_dest(inputIP,outputfile,mypath) [IP_route,path_delay]=myinput.trace_call(inputIP,classic,arguments) num_ips=num_ips+1 if IP_route!=0 and len(IP_route)>1: # IP path info extraction and print. path_info_extract=path_info_extraction.path_info_extraction() [asn_vector,encounter_type,ixp_long,ixp_short,unsure]=path_info_extract.path_info_extraction(final_ixp2asn,Sub_tree,IP_route,asn_routeviews,final_sub2names,final_ixp2name,dirty_ixp2asn,additional_info_tree) output.print_path_info(IP_route,asn_vector,path_delay,mypath,outputfile,ixp_short,ixp_long,unsure,asn_print) # Applying rules. rule_hits=detection_rules_node.resolve_path(IP_route,rules,assmt,asn_vector,encounter_type,ixp_long,ixp_short,final_asn2ip,mypath,outputfile,asn_print,print_rule) final_rules_hit=[x + y for x, y in zip(final_rules_hit, rule_hits)] if source: temp_point=temp_point+1 else: inputIP= input('Enter next target to probe or type exit for terminating:') # Extracting statistics. if (inputIP=='exit' or (source and temp_point>=len(input_list))): self.stats_extract(mypath,'stats_'+exact_time+'.txt',num_ips,rules,final_rules_hit,exact_time) break
def check_rules(self,rule,path_asn,path_cur,ixp_long,ixp_short,asn2names,encounter_type): if len(rule)>len(path_asn): return False for i in range(0,len(rule)): if len(path_asn)> path_cur+i-1: if 'IXP_IP' in rule[i] and '!AS_M' in rule[i] and 'IXP prefix' not in encounter_type[path_cur+i-1]: return False elif 'IXP_IP' in rule[i] and 'AS_M' in rule[i] and '!' not in rule[i] and 'IXP IP' not in encounter_type[path_cur+i-1]: return False elif ('IXP_IP' not in rule[i] or '!AS_M' not in rule[i]) and 'IXP prefix' in encounter_type[path_cur+i-1]: return False elif ('IXP_IP' not in rule[i] or 'AS_M' not in rule[i]) and 'IXP IP' in encounter_type[path_cur+i-1]: return False # Applies each condition of the condition part of the candidate rule onto the path. string_h=string_handler.string_handler() check=0 for i in range(0,len(rule)): current=path_cur+i-1 #The current condition of the condition part of the rule. expression=rule[i] # Checking for IXP membership based on a non-IXP IP. if '!AS_M' in expression and 'and' not in expression and path_cur!=current: # Finds the path_asn in the routeview path_asn dict. If not, an assessment is not possible. check=check+1 if path_asn[current]=='*' and encounter_type[current]!='IXP prefix': return False if encounter_type[path_cur]=='IXP IP' or encounter_type[path_cur]=='IXP prefix': as_names='' if path_asn[current] in asn2names.keys(): as_names=asn2names[path_asn[current]] ix_long=ixp_long[path_cur] ix_short=ixp_short[path_cur] else: as_names='' if path_asn[path_cur] in asn2names.keys(): as_names=asn2names[path_asn[path_cur]] ix_long=ixp_long[current] ix_short=ixp_short[current] for node in as_names: for name in node: if (string_h.string_comparison(ix_long,name) or string_h.string_comparison(ix_short,name)) : return False if not self.check_number(rule,expression,path_asn,current,i,encounter_type,'!AS_M'): return False elif 'AS_M' in expression and 'and' not in expression and path_cur!=current: if path_asn[current]=='*' and encounter_type[current]!='IXP prefix': return False check=check+1 flag=False if encounter_type[path_cur]=='IXP IP' or encounter_type[path_cur]=='IXP prefix': as_names='' if path_asn[current] in asn2names.keys(): as_names=asn2names[path_asn[current]] ix_long=ixp_long[path_cur] ix_short=ixp_short[path_cur] else: as_names='' if path_asn[path_cur] in asn2names.keys(): as_names=asn2names[path_asn[path_cur]] ix_long=ixp_long[current] ix_short=ixp_short[current] for node in (as_names): for name in node: if string_h.string_comparison(ix_long,name) or string_h.string_comparison(ix_short,name): flag=1 break if flag==0: return False if not self.check_number(rule,expression,path_asn,current,i,encounter_type,'AS_M'): return False # Checking for IXP IP or Prefix based on either IXP membership or Prefixes data. if 'IXP_IP' in expression and '!AS_M' in expression: check=check+1 if not self.check_names(rule,expression,current,i,encounter_type,'IXP_IP',ixp_long,ixp_short): return False elif not self.check_number(rule,expression,path_asn,current,i,encounter_type,'!AS_M'): return False elif 'IXP_IP' in expression and 'AS_M' in expression: check=check+1 if not self.check_names(rule,expression,current,i,encounter_type,'IXP_IP',ixp_long,ixp_short): return False elif not self.check_number(rule,expression,path_asn,current,i,encounter_type,'AS_M'): return False if len(rule)>2 and len(path_asn)> current+1: check=check+1 if not self.check_edges(rule,path_asn,current,'AS_M',ixp_long,ixp_short): return False elif not self.check_edges(rule,path_asn,current,'IXP_IP',ixp_long,ixp_short): return False if check>0: return True else: return False