annotate toys/pending/traceroute.c @ 1075:565eba9b549e draft

traceroute from Ashwini Sharma
author Rob Landley <rob@landley.net>
date Sun, 22 Sep 2013 11:21:06 -0500
parents
children e11684e3bbc5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1075
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* traceroute - trace the route to "host".
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
3 * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
4 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
5 *
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
6 * No Standard
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
7
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
8 USE_TRACEROUTE(NEWTOY(traceroute, "<1>2f#<1>255=1z#<0>86400=0g*w#<0>86400=5t#<0>255=0s:q#<1>255=3p#<1>65535=33434m#<1>255=30rvndlIUF64", TOYFLAG_USR|TOYFLAG_BIN))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
9
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
10 config TRACEROUTE
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
11 bool "traceroute"
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
12 default n
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
13 help
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
14 usage: traceroute [-FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
15 [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
16
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
17 Trace the route to HOST
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
18
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
19 -F Set the don't fragment bit
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
20 -U Use UDP datagrams instead of ICMP ECHO
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
21 -I Use ICMP ECHO instead of UDP datagrams
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
22 -l Display the TTL value of the returned packet
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
23 -f Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
24 -d Set SO_DEBUG options to socket
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
25 -n Print numeric addresses
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
26 -v verbose
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
27 -r Bypass routing tables, send directly to HOST
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
28 -m Max time-to-live (max number of hops)(RANGE 1 to 255)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
29 -p Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
30 -q Number of probes per TTL (default 3)(RANGE 1 to 255)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
31 -s IP address to use as the source address
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
32 -t Type-of-service in probe packets (default 0)(RANGE 0 to 255)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
33 -w Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
34 -g Loose source route gateway (8 max)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
35 -z Pause Time in milisec (default 0)(RANGE 0 to 86400)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
36 */
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
37 #define FOR_traceroute
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
38 #include "toys.h"
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
39 #include "toynet.h"
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
40 #include <netinet/udp.h>
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
41 #include <netinet/ip_icmp.h>
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
42
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
43 GLOBALS(
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
44 long max_ttl;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
45 long port;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
46 long ttl_probes;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
47 char *src_ip;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
48 long tos;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
49 long wait_time;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
50 struct arg_list *loose_source;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
51 long pause_time;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
52 long first_ttl;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
53 int recv_sock;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
54 int snd_sock;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
55 unsigned msg_len;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
56 struct ip *packet;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
57 uint32_t gw_list[9];
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
58 uint32_t ident;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
59 )
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
60
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
61
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
62 #define ICMP_HD_SIZE 8
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
63 #define send_icmp ((struct icmp *)(TT.packet + 1))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
64 #define send_udp ((struct udphdr *)(TT.packet + 1))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
65
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
66 struct payload_s {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
67 unsigned char seq;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
68 unsigned char ttl;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
69 struct timeval tv;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
70 };
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
71
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
72 static struct payload_s *send_data;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
73 static struct sockaddr_in dest, from;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
74
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
75 // Computes and returns checksum SUM of buffer P of length LEN
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
76 static u_int16_t in_cksum(u_int16_t *p, u_int len)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
77 {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
78 u_int32_t sum = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
79 int nwords = len >> 1;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
80
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
81 while (nwords-- != 0) sum += *p++;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
82 if (len & 1) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
83 union {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
84 u_int16_t w;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
85 u_int8_t c[2];
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
86 } u;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
87 u.c[0] = *(u_char *) p;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
88 u.c[1] = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
89 sum += u.w;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
90 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
91 // end-around-carry
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
92 sum = (sum >> 16) + (sum & 0xffff);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
93 sum += (sum >> 16);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
94 return (~sum);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
95 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
96
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
97 /*
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
98 * sends a single probe packet with sequence SEQ and
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
99 * time-to-live TTL
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
100 */
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
101 static void send_probe(int seq, int ttl)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
102 {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
103 int res, len;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
104 void *out;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
105
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
106 if (toys.optflags & FLAG_U) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
107 send_data->seq = seq;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
108 send_data->ttl = ttl;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
109 dest.sin_port = TT.port + seq;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
110 } else {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
111 send_icmp->icmp_seq = htons(seq);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
112 send_icmp->icmp_cksum = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
113 send_icmp->icmp_cksum = in_cksum((uint16_t *) send_icmp, TT.msg_len - sizeof(struct ip));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
114 if (send_icmp->icmp_cksum == 0) send_icmp->icmp_cksum = 0xffff;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
115 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
116
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
117 res = setsockopt(TT.snd_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
118 if (res < 0) perror_exit("setsockopt ttl %d", ttl);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
119
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
120 if (toys.optflags & FLAG_U) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
121 out = send_data;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
122 len = sizeof(struct payload_s);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
123 } else {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
124 out = send_icmp;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
125 len = TT.msg_len - sizeof(struct ip);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
126 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
127 res = sendto(TT.snd_sock, out, len, 0, (struct sockaddr *) &dest, sizeof(dest));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
128 if (res != len) perror_exit(" sendto");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
129 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
130
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
131 static void resolve_addr(char *host, int type, int proto, struct sockaddr_in *sock)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
132 {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
133 struct addrinfo *rp, *info, hint;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
134 int ret;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
135
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
136 memset(&hint, 0, sizeof(hint));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
137 hint.ai_family = AF_INET;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
138 hint.ai_socktype = type;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
139 hint.ai_protocol = proto;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
140
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
141 ret = getaddrinfo(host, NULL, &hint, &info);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
142 if (ret || !info) perror_exit("bad address: %s ", host);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
143
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
144 for (rp = info; rp; rp = rp->ai_next) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
145 if (rp->ai_addrlen == sizeof(struct sockaddr_in)) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
146 memcpy(sock, rp->ai_addr, rp->ai_addrlen);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
147 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
148 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
149 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
150 freeaddrinfo(info);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
151 if (!rp) perror_exit("Resolve failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
152 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
153
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
154 static void do_trace()
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
155 {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
156 int seq, fexit, ttl, tv = TT.wait_time * 1000;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
157 struct pollfd pfd[1];
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
158
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
159 pfd[0].fd = TT.recv_sock;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
160 pfd[0].events = POLLIN;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
161 for (ttl = TT.first_ttl; ttl <= TT.max_ttl; ++ttl) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
162 int probe, dest_reach = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
163 struct timeval t1, t2;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
164 struct sockaddr_in last;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
165
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
166 memset(&last, 0, sizeof(last));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
167 fexit = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
168 printf("%2d", ttl);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
169
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
170 for (probe = 0, seq = 0; probe < TT.ttl_probes; ++probe) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
171 int res = 0, tleft;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
172
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
173 fflush(NULL);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
174 if (probe && (toys.optflags & FLAG_z)) usleep(TT.pause_time * 1000);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
175
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
176 send_probe(++seq, ttl);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
177 gettimeofday(&t1, NULL);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
178 t2 = t1;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
179
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
180 while ((tleft = (int)(tv - ((unsigned long long)(t2.tv_sec * 1000ULL
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
181 + t2.tv_usec/1000) - (unsigned long long)(t1.tv_sec * 1000ULL
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
182 + t1.tv_usec/1000)))) >= 0) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
183 if (!(res = poll(pfd, 1, tleft))) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
184 printf(" *");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
185 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
186 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
187 gettimeofday(&t2, NULL);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
188 if (res < 0) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
189 if (errno != EINTR) perror_exit("poll");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
190 continue;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
191 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
192
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
193 if (pfd[0].revents) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
194 unsigned addrlen = sizeof(from);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
195 struct ip *rcv_pkt = (struct ip*) toybuf;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
196 int rcv_len, pmtu = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
197
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
198 rcv_len = recvfrom(TT.recv_sock, rcv_pkt, sizeof(toybuf),
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
199 MSG_DONTWAIT, (struct sockaddr *) &from, &addrlen);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
200 if (rcv_len <= 0) continue;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
201 else {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
202 struct icmp *ricmp;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
203 int icmp_res = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
204
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
205 ricmp = (struct icmp *) ((void*)rcv_pkt + (rcv_pkt->ip_hl << 2));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
206 if (ricmp->icmp_code == ICMP_UNREACH_NEEDFRAG)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
207 pmtu = ntohs(ricmp->icmp_nextmtu);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
208
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
209 if ((ricmp->icmp_type == ICMP_TIMXCEED
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
210 && ricmp->icmp_code == ICMP_TIMXCEED_INTRANS)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
211 || ricmp->icmp_type == ICMP_UNREACH
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
212 || ricmp->icmp_type == ICMP_ECHOREPLY) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
213
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
214 struct ip *hip;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
215 struct udphdr *hudp;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
216 struct icmp *hicmp;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
217
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
218 hip = &ricmp->icmp_ip;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
219 if (toys.optflags & FLAG_U) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
220 hudp = (struct udphdr*) (hip + (hip->ip_hl << 2));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
221 if ((hip->ip_hl << 2) + 12 <= (rcv_len - (rcv_pkt->ip_hl << 2))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
222 && hip->ip_p == IPPROTO_UDP
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
223 && hudp->dest == htons(TT.port + seq))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
224 icmp_res = (ricmp->icmp_type == ICMP_TIMXCEED ?-1 : ricmp->icmp_code);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
225 } else {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
226 hicmp = (struct icmp *) ((void*)hip + (hip->ip_hl << 2));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
227 if (ricmp->icmp_type == ICMP_ECHOREPLY && ricmp->icmp_id == htons(TT.ident)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
228 && ricmp->icmp_seq == htons(seq))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
229 icmp_res = ICMP_UNREACH_PORT;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
230
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
231 if ((hip->ip_hl << 2) + ICMP_HD_SIZE <= (rcv_len - (rcv_pkt->ip_hl << 2))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
232 && hip->ip_p == IPPROTO_ICMP
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
233 && hicmp->icmp_id == htons(TT.ident)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
234 && hicmp->icmp_seq == htons(seq))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
235 icmp_res = (ricmp->icmp_type == ICMP_TIMXCEED ? -1 : ricmp->icmp_code);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
236 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
237 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
238 if (!icmp_res) continue;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
239
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
240 if (addrlen > 0) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
241 unsigned delta = (t2.tv_sec * 1000000ULL + t2.tv_usec)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
242 - (t1.tv_sec * 1000000ULL + t1.tv_usec);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
243
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
244 if (memcmp(&last.sin_addr, &from.sin_addr, sizeof(struct in_addr))) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
245 if (!(toys.optflags & FLAG_n)) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
246 char host[NI_MAXHOST];
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
247 if (!getnameinfo((struct sockaddr *) &from,
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
248 sizeof(from), host, NI_MAXHOST, NULL, 0, 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
249 printf(" %s (", host);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
250 else printf(" %s (", inet_ntoa(from.sin_addr));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
251 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
252 printf(" %s", inet_ntoa(from.sin_addr));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
253 if (!(toys.optflags & FLAG_n) ) printf(")");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
254 last = from;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
255 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
256 printf(" %u.%03u ms", delta / 1000, delta % 1000);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
257 if (toys.optflags & FLAG_l) printf(" (%d)", rcv_pkt->ip_ttl);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
258 if (toys.optflags & FLAG_v) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
259 printf(" %d bytes from %s : icmp type %d code %d\t",
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
260 rcv_len, inet_ntoa(from.sin_addr),
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
261 ricmp->icmp_type, ricmp->icmp_code);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
262 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
263 } else printf("\t!H");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
264
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
265 switch (icmp_res) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
266 case ICMP_UNREACH_PORT:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
267 if (rcv_pkt->ip_ttl <= 1) printf(" !");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
268 dest_reach = 1;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
269 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
270 case ICMP_UNREACH_NET:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
271 printf(" !N");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
272 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
273 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
274 case ICMP_UNREACH_HOST:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
275 printf(" !H");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
276 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
277 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
278 case ICMP_UNREACH_PROTOCOL:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
279 printf(" !P");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
280 dest_reach = 1;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
281 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
282 case ICMP_UNREACH_NEEDFRAG:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
283 printf(" !F-%d", pmtu);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
284 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
285 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
286 case ICMP_UNREACH_SRCFAIL:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
287 printf(" !S");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
288 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
289 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
290 case ICMP_UNREACH_FILTER_PROHIB:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
291 case ICMP_UNREACH_NET_PROHIB:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
292 printf(" !A");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
293 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
294 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
295 case ICMP_UNREACH_HOST_PROHIB:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
296 printf(" !C");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
297 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
298 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
299 case ICMP_UNREACH_HOST_PRECEDENCE:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
300 printf(" !V");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
301 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
302 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
303 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
304 printf(" !C");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
305 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
306 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
307 case ICMP_UNREACH_NET_UNKNOWN:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
308 case ICMP_UNREACH_HOST_UNKNOWN:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
309 printf(" !U");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
310 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
311 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
312 case ICMP_UNREACH_ISOLATED:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
313 printf(" !I");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
314 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
315 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
316 case ICMP_UNREACH_TOSNET:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
317 case ICMP_UNREACH_TOSHOST:
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
318 printf(" !T");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
319 ++fexit;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
320 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
321 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
322 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
323 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
324 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
325 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
326 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
327 xputc('\n');
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
328 if (!memcmp(&from.sin_addr, &dest.sin_addr, sizeof(struct in_addr))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
329 || dest_reach || (fexit >= TT.ttl_probes -1))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
330 break;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
331 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
332
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
333 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
334
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
335 void traceroute_main(void)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
336 {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
337 unsigned opt_len = 0, pack_size, tyser = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
338 int set = 1, lsrr = 0;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
339
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
340 if (toys.optflags & FLAG_g) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
341 struct arg_list *node;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
342
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
343 for (node = TT.loose_source; node; node = node->next, lsrr++) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
344 struct sockaddr_in sin;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
345
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
346 memset( &sin, 0, sizeof(sin));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
347 if (lsrr >= 8) error_exit("no more than 8 gateways"); // NGATEWAYS
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
348 resolve_addr(node->arg, SOCK_STREAM, 0, &sin);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
349 TT.gw_list[lsrr] = sin.sin_addr.s_addr;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
350 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
351 opt_len = (lsrr + 1) * sizeof(TT.gw_list[0]);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
352 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
353
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
354 pack_size = sizeof(struct ip) + opt_len;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
355 pack_size += (toys.optflags & FLAG_U) ? sizeof(struct udphdr)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
356 + sizeof(struct payload_s) : ICMP_HD_SIZE;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
357
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
358 if (toys.optargs[1])
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
359 TT.msg_len = get_int_value(toys.optargs[1], pack_size, 32768);//max packet size
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
360
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
361 TT.msg_len = (TT.msg_len < pack_size) ? pack_size : TT.msg_len;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
362 TT.recv_sock = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
363 if (toys.optflags & FLAG_d
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
364 && (setsockopt(TT.recv_sock, SOL_SOCKET, SO_DEBUG, &set, sizeof(set)) < 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
365 perror_exit("SO_DEBUG failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
366 if (toys.optflags & FLAG_r
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
367 && (setsockopt(TT.recv_sock, SOL_SOCKET, SO_DONTROUTE, &set, sizeof(set)) < 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
368 perror_exit("SO_DONTROUTE failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
369
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
370 if (toys.optflags & FLAG_U) TT.snd_sock = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
371 else TT.snd_sock = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
372
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
373 resolve_addr(toys.optargs[0], ((toys.optflags & FLAG_U) ? SOCK_DGRAM : SOCK_RAW),
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
374 ((toys.optflags & FLAG_U) ? IPPROTO_UDP : IPPROTO_ICMP), &dest);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
375
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
376 if (lsrr > 0) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
377 unsigned char optlist[MAX_IPOPTLEN];
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
378 unsigned size;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
379
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
380 TT.gw_list[lsrr] = dest.sin_addr.s_addr;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
381 ++lsrr;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
382
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
383 optlist[0] = IPOPT_NOP;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
384 optlist[1] = IPOPT_LSRR;// loose source route option
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
385 size = lsrr * sizeof(TT.gw_list[0]);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
386 optlist[2] = size + 3;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
387 optlist[3] = IPOPT_MINOFF;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
388 memcpy(optlist + 4, TT.gw_list, size);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
389
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
390 if (setsockopt(TT.snd_sock, IPPROTO_IP, IP_OPTIONS,
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
391 (char *)optlist, size + sizeof(TT.gw_list[0])) < 0)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
392 perror_exit("LSRR IP_OPTIONS");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
393 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
394
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
395 if (setsockopt(TT.snd_sock, SOL_SOCKET, SO_SNDBUF, &TT.msg_len, sizeof(TT.msg_len)) < 0)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
396 perror_exit("SO_SNDBUF failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
397
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
398 if ((toys.optflags & FLAG_t) &&
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
399 setsockopt(TT.snd_sock, IPPROTO_IP, IP_TOS, &tyser, sizeof(tyser)) < 0)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
400 perror_exit("IP_TOS %d failed ", TT.tos);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
401
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
402 #ifdef IP_DONTFRAG
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
403 if ((toys.optflags & FLAG_F) &&
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
404 (setsockopt(TT.snd_sock, IPPROTO_IP, IP_DONTFRAG, &set, sizeof(set)) < 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
405 perror_exit("IP_DONTFRAG failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
406 #endif
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
407
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
408 if ((toys.optflags & FLAG_d)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
409 && (setsockopt(TT.snd_sock, SOL_SOCKET, SO_DEBUG, &set, sizeof(set)) < 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
410 perror_exit("SO_DEBUG failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
411 if ((toys.optflags & FLAG_r) &&
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
412 (setsockopt(TT.snd_sock, SOL_SOCKET, SO_DONTROUTE, &set, sizeof(set)) < 0))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
413 perror_exit("SO_DONTROUTE failed ");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
414
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
415
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
416 TT.packet = xmalloc(TT.msg_len);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
417 TT.ident = getpid();
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
418
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
419 if (toys.optflags & FLAG_U) send_data = (struct payload_s *) (send_udp + 1);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
420 else {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
421 TT.ident |= 0x8000;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
422 send_icmp->icmp_type = ICMP_ECHO;
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
423 send_icmp->icmp_id = htons(TT.ident);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
424 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
425 if (toys.optflags & FLAG_s) {
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
426 struct sockaddr_in *source = xzalloc(sizeof(struct sockaddr_in));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
427 inet_aton(TT.src_ip, &source->sin_addr);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
428 if (setsockopt(TT.snd_sock, IPPROTO_IP, IP_MULTICAST_IF,
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
429 (struct sockaddr*)source, sizeof(*source)))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
430 perror_exit("can't set multicast source interface");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
431 if (bind(TT.snd_sock,(struct sockaddr*)source, sizeof(*source)))
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
432 perror_exit("bind");
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
433 free(source);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
434 }
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
435
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
436 if(TT.first_ttl > TT.max_ttl)
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
437 error_exit("ERROR :Range for -f is 1 to %d (max ttl)", TT.max_ttl);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
438
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
439 printf("traceroute to %s(%s)", toys.optargs[0], inet_ntoa(dest.sin_addr));
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
440 if (toys.optflags & FLAG_s) printf(" from %s", TT.src_ip);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
441 printf(", %ld hops max, %u byte packets\n", TT.max_ttl, TT.msg_len);
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
442
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
443 do_trace();
565eba9b549e traceroute from Ashwini Sharma
Rob Landley <rob@landley.net>
parents:
diff changeset
444 }