def traceroute( self, src, dstIps, bidir, snapshot, srcPorts=None, dstPorts=None, applications=None, ipProtocols=None, ): headers = HeaderConstraints(dstIps=dstIps, srcPorts=srcPorts, dstPorts=dstPorts, applications=applications, ipProtocols=ipProtocols) if bidir: result = bfq.bidirectionalTraceroute(startLocation=src, headers=headers)\ .answer(snapshot=snapshot)\ .frame() else: result = bfq.traceroute(startLocation=src, headers=headers)\ .answer(snapshot=snapshot)\ .frame() return result
def test_dataplane(isFailed, fromNode, checkMultipath=True): ips = bfq.ipOwners().answer().frame() loopbacks = ips[(ips['Interface'] == 'Loopback0') & (ips['Active'])] localIP = loopbacks[loopbacks['Node'] == fromNode]['IP'][0] leaves = set(loopbacks[loopbacks['Node'].str.contains('leaf')]['IP']) leaves.remove(localIP) spines = set(loopbacks[loopbacks['Node'].str.contains('spine')]['IP']) mpath = len(spines) logging.info("Progress: Analyzing traceroute from Leaf-3 to Leaf-1 and Leaf-2") # Set up the resulting data structure troute = dict() for leaf in leaves: troute[leaf] = dict() # Build headers for traceroute flows for leaf in leaves: troute[leaf]['header'] = header(srcIps=localIP,dstIps=leaf) # Ask questions about traceroute for leaf,data in troute.items(): troute[leaf]['trace'] = bfq.traceroute(startLocation=fromNode, headers=data['header']).answer() # Get first flow disposition for traces for leaf,data in troute.items(): troute[leaf]['result'] = data['trace'].get('answerElements')[0]['rows'][0]['Traces'][0]['disposition'] # Get traceroute paths to reach Leaf-1 and Leaf-2 for leaf,data in troute.items(): troute[leaf]['paths'] = data['trace'].get('answerElements')[0]['rows'][0]['Traces'] # Get traceroute hops to reach Leaf-1 and Leaf-2 for leaf,data in troute.items(): troute[leaf]['hops'] = data['trace'].get('answerElements')[0]['rows'][0]['Traces'][0].get('hops',[]) # Now let's check that the traceroute behaves as we expect for leaf, data in troute.items(): if data['result'] != 'ACCEPTED': logging.error("Traceroute to {} has failed: {}".format(leaf, data['result'])) isFailed = True else: logging.info("Traceroute Progress: {}".format(data['result'])) # Number of paths should be equal to the number of spines if len(data['paths']) != mpath: logging.error("Number of paths {} != {} number of spines".format(len(data['paths']), mpath)) logging.error(data['paths']) isFailed = True else: logging.info("Number of paths {} == {} number of spines".format(len(data['paths']), mpath)) # Traceroute has to traverse exactly two hops for path in data['paths']: if len(path.get('hops',[])) != 2: logging.error("Traceroute has not traversed exactly two hops") logging.error(path) isFailed = True else: logging.info("Traceroute traversed exactly two hops") return isFailed
def test_answer_traceroute(traceroute_network): bf_session.additional_args = {'debugflags': 'traceroute'} answer = bfq.traceroute(startLocation="hop1", headers=HeaderConstraints( dstIps="1.0.0.2")).answer().frame() list_traces = answer.iloc[0]['Traces'] assert len(list_traces) == 1 trace = list_traces[0] assert trace.disposition == "ACCEPTED" hops = trace.hops assert len(hops) == 2 assert hops[-1].steps[-1].action == 'ACCEPTED'
def get_traces(nodes: List[str], snapshot: str): traces = {} for n1 in nodes: for n2 in nodes: results = bfq.traceroute( startLocation=n1, headers=HeaderConstraints(dstIps=n2)).answer( snapshot=snapshot).frame() for idx, result in results.iterrows(): for trace in result.Traces: if trace.disposition not in traces: traces[trace.disposition] = set() hops_str = json.dumps(convert_list_to_tuple(trace.hops)) traces[trace.disposition].add(hops_str) return traces
def BF_traceroute(task: Task, startLocation: str = None, ignoreFilters: bool = False, **kwargs) -> Result: result = bfq.traceroute(startLocation=startLocation, headers=HeaderConstraints(**kwargs), ignoreFilters=ignoreFilters).answer() result = { 'Results': result['answerElements'][0]['rows'], 'Summary': result['answerElements'][0]['summary'], } return Result(host=task.host, result=result)
def _unidirectional_virtual_traceroute(self, source_ip, destination_ip, addresses): for address in addresses.rows: if address.get('IP') == source_ip: node = address.get('Node').get('name') int = address.get('Interface') headers = HeaderConstraints(srcIps=source_ip, dstIps=destination_ip, ipProtocols=['ICMP']) try: tracert = bfq.traceroute(startLocation="{}[{}]".format(node, int), headers=headers).answer() return tracert except: logger.warn('{} address has not been found'.format(source_ip))
print("Detect forwarding loops.") print("#"*100) print(bfq.detectLoops().answer().frame()) # List edges types print("#"*100) print("Lists neighbor relationships of the specified type (layer3, BGP, ospf, etc. in the form of edges).") print("#"*100) print(bfq.edges().answer().frame()) # File parse status print("#"*100) print("For each file in a snapshot, returns the host(s) that were produced by the file and the parse status: pass, fail, partially parsed.") print("#"*100) print(bfq.fileParseStatus().answer().frame()) # IP Interfaces print("#"*100) print("List IPs configured on interfaces") print("#"*100) ip_owners_ans = bfq.ipOwners().answer() print(ip_owners_ans.frame()) # Traceroute !! print("#"*100) print("Traceroute ! The killer feature :-p") print("#"*100) print((bfq.traceroute(startLocation='arista', headers={"dstIps": "ofLocation(n9k)"}).answer()).frame()) print((bfq.traceroute(startLocation='n9k', headers={"dstIps": "ofLocation(arista)"}).answer()).frame()) #print((bfq.traceroute(startLocation='arista', headers={"dstIps": "ofLocation(arista)"}).answer()).frame())