Esempio n. 1
0
    def traceroute(self, src_dst_list):
        LOG.info("Performing Netkit traceroutes for %s" % self.server.host)
        shell = self.server.get_shell()
        shell.setecho(False)
        resultant_paths = defaultdict(dict) #indexed format for presenting/analysis
        paths = [] # list format for plotting

        template_dir =  resource_filename("AutoNetkit","lib/templates")
        linux_traceroute_template = open(os.path.join(template_dir, "textfsm", "linux_traceroute"), "r")

# build reverse-IP lookup
#TODO: move this into seperate helper function
        ip_mappings = {}
#TODO: see if netaddr has a better way other than casting to string
        ip_mappings.update( dict( (str(device.lo_ip.ip), device) 
            for device in self.network.devices()))
        for link in self.network.links():
            ip_mappings[str(link.local_ip)] = link.local_host
            ip_mappings[str(link.remote_ip)] = link.remote_host

#convert pairs list into 2-tuples, eg [1, 2, 3, 4, ...] -> (1, 2), (3, 4), ...
        label_pairs = [ (src_dst_list[i], src_dst_list[i+1])
                for i in range(0, len(src_dst_list), 2)]
        for src_label, dst_label in label_pairs:
            try:
                src = self.network.find(src_label)
            except ank.network.DeviceNotFoundException:
                LOG.warn("Unable to find device %s" % src_label)
                continue
            try:
                dst = self.network.find(dst_label)
            except ank.network.DeviceNotFoundException:
                LOG.warn("Unable to find device %s" % dst_label)
                continue

            LOG.info("Tracing from %s to %s" % (src_label, dst_label))
            self.server.connect_vm(src.tap_ip, shell)
            #TODO: make this handle appropriate ID for servers (no lo_ip)
# TODO: probably be st to integrate into the device namedtuple for consistency
            shell.sendline("traceroute -n %s" % dst.lo_ip.ip)
            shell.expect(self.server.NETKIT_PROMPT)
            command_output = shell.before
            self.server.disconnect_vm(shell)
            shell.prompt()
            re_table = textfsm.TextFSM(linux_traceroute_template)
            route = re_table.ParseText(command_output)
# conver to just the returned IPs
            route = [result[0] for result in route]
# try lookups
#TODO: put a try/except here, KeyError?
            resolved_route = [ip_mappings[host] for host in route]
            print "resolved route", resolved_route
            resultant_paths[src_label][dst_label] = resolved_route
            resolved_route.insert(0, src)
            paths.append(resolved_route)

        #pprint.pprint( resultant_paths)
# format for plotting
#TODO: enable/disable this from command line/function default
        print "plotting paths", paths
        ank.plot_paths(self.network, paths = paths)