#!/usr/bin/env python3.11 import re import json import ipaddress import uuid import hashlib from .db import Database def parse_traceroute_output(output, timestamp): lines = output.strip().split('\n') trace = {} hops = [] ip_regex = r"\((.*?)\)" # ipaddress are in () target = output.strip().split('\n')[0].split()[2] for line in lines[1:]: hop = {} hop_info = line.split() hop_number = int(hop_info[0]) hop_name = None hop_ip = None hop_latency = None latencies = [] #print("##### "+str(hop_info)) count = 0 for part in hop_info[1:]: count += 1 # source node drops or blocks icmp packages # We will give funny to name to hop for not answering and move on. if part == '*': hop_name = 'unresponsive' hop_ip = 'unresponsive' break # If first colum is either name or ip-address if count == 1: match = re.search(ip_regex, part) if match: hop_ip = part.strip('()') else: hop_name = part # Second colum is ip-address first latency reading if count == 2: if re.search(ip_regex, part): try: _ip = ipaddress.ip_address(part.strip('()')) hop_ip = part.strip('()') except ValueError: pass # Ignore if it's not a valid IP address # Rest of the input colums are either latency floats, 'ms' or # reruns of the hop_name and hop_ip... # We only need the latency floats anymore. else: try: latency = float(part) latencies.append(latency) except ValueError: pass hop_latency = sum(latencies) / len(latencies) if latencies else None hop['hop_number'] = hop_number if not hop_name == None: hop['hop_name'] = hop_name hop['hop_ip'] = hop_ip hop['hop_latency'] = hop_latency hops.append(hop) trace['target'] = target trace['timestamp'] = timestamp trace['hops'] = hops return trace def store_traceroute(node, trace): db = Database() #hops_json = json.dumps(trace['hops']) path_ids = {} previous_hop_ip = None previous_hop_latency = None for hop in trace['hops']: hop_number = hop['hop_number'] hop_name = hop.get('hop_name') hop_ip = hop.get('hop_ip') hop_latency = hop.get('hop_latency') link_id = None # insert links and get their id's if previous_hop_ip: link_id = db.create_link(previous_hop_ip, hop_ip) path_ids[hop_number] = link_id previous_hop_ip = hop_ip # Save hop details db.create_hop(hop_name, hop_ip, hop_latency) # calculate link latency if possible and store it if link_id and previous_hop_latency: link_latency = hop_latency - previous_hop_latency db.create_latency(link_id, trace['timestamp'], link_latency) # make entry to "Paths" table if path_ids: json_path_ids = json.dumps(path_ids) db.create_path(node, trace['target'], json_path_ids) db.end() def generate_node_id(): mac = uuid.getnode() mac_str = ':'.join(['{:02x}'.format((mac >> ele) & 0xff) for ele in range(0,8*6,8)][::-1]) # Hash the MAC address using SHA-256 to generate a unique ID unique_id = hashlib.sha256(mac_str.encode()).hexdigest() return unique_id