def traceroute(<EOL>self,<EOL>destination,<EOL>source=C.TRACEROUTE_SOURCE,<EOL>ttl=C.TRACEROUTE_TTL,<EOL>timeout=C.TRACEROUTE_TIMEOUT,<EOL>vrf=C.TRACEROUTE_VRF,<EOL>):
<EOL>if vrf:<EOL><INDENT>command = "<STR_LIT>".format(vrf, destination)<EOL><DEDENT>else:<EOL><INDENT>command = "<STR_LIT>".format(destination)<EOL><DEDENT>if source:<EOL><INDENT>command += "<STR_LIT>".format(source)<EOL><DEDENT>if ttl:<EOL><INDENT>if isinstance(ttl, int) and <NUM_LIT:0> <= timeout <= <NUM_LIT:255>:<EOL><INDENT>command += "<STR_LIT>".format(str(ttl))<EOL><DEDENT><DEDENT>if timeout:<EOL><INDENT>if isinstance(timeout, int) and <NUM_LIT:1> <= timeout <= <NUM_LIT>:<EOL><INDENT>command += "<STR_LIT>".format(str(timeout))<EOL><DEDENT><DEDENT>max_loops = (<NUM_LIT:5> * ttl * timeout) + <NUM_LIT><EOL>if max_loops < <NUM_LIT>:  <EOL><INDENT>max_loops = <NUM_LIT><EOL><DEDENT>output = self.device.send_command(command, max_loops=max_loops)<EOL>traceroute_dict = dict()<EOL>if re.search("<STR_LIT>", output):<EOL><INDENT>traceroute_dict["<STR_LIT:error>"] = "<STR_LIT>" % destination<EOL>return traceroute_dict<EOL><DEDENT>else:<EOL><INDENT>traceroute_dict["<STR_LIT:success>"] = dict()<EOL><DEDENT>results = dict()<EOL>hops = re.findall(r"<STR_LIT>", output)<EOL>for hop in hops:<EOL><INDENT>hop_match = re.search(hop, output)<EOL>start_index = hop_match.start()<EOL>if hops.index(hop) + <NUM_LIT:1> == len(hops):<EOL><INDENT>stop_index = len(output)<EOL><DEDENT>else:<EOL><INDENT>next_hop_match = re.search(hops[hops.index(hop) + <NUM_LIT:1>], output)<EOL>stop_index = next_hop_match.start()<EOL><DEDENT>hop_string = output[start_index:stop_index].replace("<STR_LIT>", "<STR_LIT>")<EOL>hop_list = hop_string.split()<EOL>current_hop = int(hop_list.pop(<NUM_LIT:0>))<EOL>results[current_hop] = dict()<EOL>results[current_hop]["<STR_LIT>"] = dict()<EOL>results[current_hop]["<STR_LIT>"][<NUM_LIT:1>] = {<EOL>"<STR_LIT>": float(),<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>}<EOL>results[current_hop]["<STR_LIT>"][<NUM_LIT:2>] = {<EOL>"<STR_LIT>": float(),<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>}<EOL>results[current_hop]["<STR_LIT>"][<NUM_LIT:3>] = {<EOL>"<STR_LIT>": float(),<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>}<EOL>current_probe = <NUM_LIT:1><EOL>ip_address = "<STR_LIT>"<EOL>host_name = "<STR_LIT>"<EOL>while hop_list:<EOL><INDENT>current_element = hop_list.pop(<NUM_LIT:0>)<EOL>if current_element == "<STR_LIT:*>":<EOL><INDENT>current_probe += <NUM_LIT:1><EOL><DEDENT>elif "<STR_LIT>" in current_element:<EOL><INDENT>ip_address = py23_compat.text_type(ip_address)<EOL>host_name = py23_compat.text_type(host_name)<EOL>rtt = float(current_element.replace("<STR_LIT>", "<STR_LIT>"))<EOL>results[current_hop]["<STR_LIT>"][current_probe][<EOL>"<STR_LIT>"<EOL>] = ip_address<EOL>results[current_hop]["<STR_LIT>"][current_probe][<EOL>"<STR_LIT>"<EOL>] = host_name<EOL>results[current_hop]["<STR_LIT>"][current_probe]["<STR_LIT>"] = rtt<EOL>current_probe += <NUM_LIT:1><EOL><DEDENT>elif "<STR_LIT:(>" in current_element:<EOL><INDENT>ip_address = current_element.replace("<STR_LIT:(>", "<STR_LIT>").replace("<STR_LIT:)>", "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>host_name = current_element<EOL>ip_address = current_element<EOL><DEDENT><DEDENT><DEDENT>traceroute_dict["<STR_LIT:success>"] = results<EOL>return traceroute_dict<EOL>
Executes traceroute on the device and returns a dictionary with the result.

:param destination: Host or IP Address of the destination
:param source (optional): Use a specific IP Address to execute the traceroute
:param ttl (optional): Maimum number of hops -> int (0-255)
:param timeout (optional): Number of seconds to wait for response -> int (1-3600)

Output dictionary has one of the following keys:

    * success
    * error

In case of success, the keys of the dictionary represent the hop ID, while values are
dictionaries containing the probes results:
    * rtt (float)
    * ip_address (str)
    * host_name (str)