Merge from vendor branch FILE:
[dragonfly.git] / usr.sbin / traceroute / traceroute.c
1 /*      $OpenBSD: traceroute.c,v 1.61 2004/01/26 18:23:51 deraadt Exp $ */
2 /*      $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $  */
3
4 /*-
5  * Copyright (c) 1990, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Van Jacobson.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * $DragonFly: src/usr.sbin/traceroute/traceroute.c,v 1.6 2004/12/18 22:48:14 swildner Exp $
36  * @(#)traceroute.c     8.1 (Berkeley) 6/6/93
37  */
38
39 /*
40  * traceroute host  - trace the route ip packets follow going to "host".
41  *
42  * Attempt to trace the route an ip packet would follow to some
43  * internet host.  We find out intermediate hops by launching probe
44  * packets with a small ttl (time to live) then listening for an
45  * icmp "time exceeded" reply from a gateway.  We start our probes
46  * with a ttl of one and increase by one until we get an icmp "port
47  * unreachable" (which means we got to "host") or hit a max (which
48  * defaults to 64 hops & can be changed with the -m flag).  Three
49  * probes (change with -q flag) are sent at each ttl setting and a
50  * line is printed showing the ttl, address of the gateway and
51  * round trip time of each probe.  If the probe answers come from
52  * different gateways, the address of each responding system will
53  * be printed.  If there is no response within a 5 sec. timeout
54  * interval (changed with the -w flag), a "*" is printed for that
55  * probe.
56  *
57  * Probe packets are UDP format.  We don't want the destination
58  * host to process them so the destination port is set to an
59  * unlikely value (if some clod on the destination is using that
60  * value, it can be changed with the -p flag).
61  *
62  * A sample use might be:
63  *
64  *     [yak 71]% traceroute nis.nsf.net.
65  *     traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
66  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
67  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
68  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
69  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
70  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
71  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
72  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
73  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
74  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
75  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
76  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
77  *
78  * Note that lines 2 & 3 are the same.  This is due to a buggy
79  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
80  * packets with a zero ttl.
81  *
82  * A more interesting example is:
83  *
84  *     [yak 72]% traceroute allspice.lcs.mit.edu.
85  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
86  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
87  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
88  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
89  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
90  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
91  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
92  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
93  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
94  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
95  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
96  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
97  *     12  * * *
98  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
99  *     14  * * *
100  *     15  * * *
101  *     16  * * *
102  *     17  * * *
103  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
104  *
105  * (I start to see why I'm having so much trouble with mail to
106  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
107  * either don't send ICMP "time exceeded" messages or send them
108  * with a ttl too small to reach us.  14 - 17 are running the
109  * MIT C Gateway code that doesn't send "time exceeded"s.  God
110  * only knows what's going on with 12.
111  *
112  * The silent gateway 12 in the above may be the result of a bug in
113  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
114  * sends an unreachable message using whatever ttl remains in the
115  * original datagram.  Since, for gateways, the remaining ttl is
116  * zero, the icmp "time exceeded" is guaranteed to not make it back
117  * to us.  The behavior of this bug is slightly more interesting
118  * when it appears on the destination system:
119  *
120  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
121  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
122  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
123  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
124  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
125  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
126  *      7  * * *
127  *      8  * * *
128  *      9  * * *
129  *     10  * * *
130  *     11  * * *
131  *     12  * * *
132  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
133  *
134  * Notice that there are 12 "gateways" (13 is the final
135  * destination) and exactly the last half of them are "missing".
136  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
137  * is using the ttl from our arriving datagram as the ttl in its
138  * icmp reply.  So, the reply will time out on the return path
139  * (with no notice sent to anyone since icmp's aren't sent for
140  * icmp's) until we probe with a ttl that's at least twice the path
141  * length.  I.e., rip is really only 7 hops away.  A reply that
142  * returns with a ttl of 1 is a clue this problem exists.
143  * Traceroute prints a "!" after the time if the ttl is <= 1.
144  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
145  * non-standard (HPUX) software, expect to see this problem
146  * frequently and/or take care picking the target host of your
147  * probes.
148  *
149  * Other possible annotations after the time are !H, !N, !P (got a host,
150  * network or protocol unreachable, respectively), !S or !F (source
151  * route failed or fragmentation needed -- neither of these should
152  * ever occur and the associated gateway is busted if you see one).  If
153  * almost all the probes result in some kind of unreachable, traceroute
154  * will give up and exit.
155  *
156  * Notes
157  * -----
158  * This program must be run by root or be setuid.  (I suggest that
159  * you *don't* make it setuid -- casual use could result in a lot
160  * of unnecessary traffic on our poor, congested nets.)
161  *
162  * This program requires a kernel mod that does not appear in any
163  * system available from Berkeley:  A raw ip socket using proto
164  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
165  * opposed to data to be wrapped in a ip datagram).  See the README
166  * file that came with the source to this program for a description
167  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
168  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
169  * MODIFIED TO RUN THIS PROGRAM.
170  *
171  * The udp port usage may appear bizarre (well, ok, it is bizarre).
172  * The problem is that an icmp message only contains 8 bytes of
173  * data from the original datagram.  8 bytes is the size of a udp
174  * header so, if we want to associate replies with the original
175  * datagram, the necessary information must be encoded into the
176  * udp header (the ip id could be used but there's no way to
177  * interlock with the kernel's assignment of ip id's and, anyway,
178  * it would have taken a lot more kernel hacking to allow this
179  * code to set the ip id).  So, to allow two or more users to
180  * use traceroute simultaneously, we use this task's pid as the
181  * source port (the high bit is set to move the port number out
182  * of the "likely" range).  To keep track of which probe is being
183  * replied to (so times and/or hop counts don't get confused by a
184  * reply that was delayed in transit), we increment the destination
185  * port number before each probe.
186  *
187  * Don't use this as a coding example.  I was trying to find a
188  * routing problem and this code sort-of popped out after 48 hours
189  * without sleep.  I was amazed it ever compiled, much less ran.
190  *
191  * I stole the idea for this program from Steve Deering.  Since
192  * the first release, I've learned that had I attended the right
193  * IETF working group meetings, I also could have stolen it from Guy
194  * Almes or Matt Mathis.  I don't know (or care) who came up with
195  * the idea first.  I envy the originators' perspicacity and I'm
196  * glad they didn't keep the idea a secret.
197  *
198  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
199  * enhancements to the original distribution.
200  *
201  * I've hacked up a round-trip-route version of this that works by
202  * sending a loose-source-routed udp datagram through the destination
203  * back to yourself.  Unfortunately, SO many gateways botch source
204  * routing, the thing is almost worthless.  Maybe one day...
205  *
206  *  -- Van Jacobson (van@helios.ee.lbl.gov)
207  *     Tue Dec 20 03:50:13 PST 1988
208  */
209
210 #include <sys/param.h>
211 #include <sys/time.h>
212 #include <sys/socket.h>
213 #include <sys/file.h>
214 #include <sys/ioctl.h>
215 #include <sys/sysctl.h>
216
217 #include <netinet/in_systm.h>
218 #include <netinet/in.h>
219 #include <netinet/ip.h>
220 #include <netinet/ip_icmp.h>
221 #include <netinet/ip_var.h>
222 #include <netinet/udp.h>
223
224 #include <arpa/inet.h>
225
226 #include <ctype.h>
227 #include <err.h>
228 #include <errno.h>
229 #include <netdb.h>
230 #include <stdio.h>
231 #include <stdlib.h>
232 #include <string.h>
233 #include <unistd.h>
234
235 #define MAX_LSRR        ((MAX_IPOPTLEN - 4) / 4)
236
237 /*
238  * Format of the data in a (udp) probe packet.
239  */
240 struct packetdata {
241         u_char seq;             /* sequence number of this packet */
242         u_int8_t ttl;           /* ttl packet left with */
243         u_int32_t sec;          /* time packet left */
244         u_int32_t usec;
245 };
246
247 struct in_addr gateway[MAX_LSRR + 1];
248 int lsrrlen = 0;
249 int32_t sec_perturb;
250 int32_t usec_perturb;
251
252 u_char packet[512], *outpacket; /* last inbound (icmp) packet */
253
254 void dump_packet(void);
255 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
256 void send_probe(int, u_int8_t, int, struct sockaddr_in *);
257 int packet_ok(u_char *, int, struct sockaddr_in *, int, int);
258 const char *pr_type(u_int8_t);
259 void print(u_char *, int, struct sockaddr_in *);
260 char *inetname(struct in_addr);
261 u_short in_cksum(u_short *, int);
262 void usage(void);
263
264 int s;                          /* receive (icmp) socket file descriptor */
265 int sndsock;                    /* send (udp) socket file descriptor */
266
267 int datalen;                    /* How much data */
268 int headerlen;                  /* How long packet's header is */
269
270 char *source = 0;
271 char *hostname;
272
273 int nprobes = 3;
274 u_int8_t max_ttl = IPDEFTTL;
275 u_int8_t first_ttl = 1;
276 u_short ident;
277 u_short port = 32768+666;       /* start udp dest port # for probe packets */
278 u_char  proto = IPPROTO_UDP;
279 u_int8_t  icmp_type = ICMP_ECHO; /* default ICMP code/type */
280 u_char  icmp_code = 0;
281 int options;                    /* socket options */
282 int verbose;
283 int waittime = 5;               /* time to wait for response (in seconds) */
284 int nflag;                      /* print addresses numerically */
285 int dump;
286
287 int
288 main(int argc, char *argv[])
289 {
290         int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
291         int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
292         int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0;
293         size_t size = sizeof(max_ttl);
294         struct sockaddr_in from, to;
295         struct hostent *hp;
296         u_int32_t tmprnd;
297         struct ip *ip;
298         u_int8_t ttl;
299         char *ep;
300         long l;
301
302         if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
303                 err(5, "icmp socket");
304         if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
305                 err(5, "raw socket");
306
307         /* revoke privs */
308         seteuid(getuid());
309         setuid(getuid());
310
311         sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size, NULL, 0);
312
313         while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:c")) != -1)
314                 switch (ch) {
315                 case 'S':
316                         sump = 1;
317                         break;
318                 case 'f':
319                         errno = 0;
320                         ep = NULL;
321                         l = strtol(optarg, &ep, 10);
322                         if (errno || !*optarg || *ep || l < 1 || l > max_ttl)
323                                 errx(1, "min ttl must be 1 to %u.", max_ttl);
324                         first_ttl = (u_int8_t)l;
325                         break;
326                 case 'c':
327                         incflag = 0;
328                         break;
329                 case 'd':
330                         options |= SO_DEBUG;
331                         break;
332                 case 'D':
333                         dump = 1;
334                         break;
335                 case 'g':
336                         if (lsrr >= MAX_LSRR)
337                                 errx(1, "too many gateways; max %d", MAX_LSRR);
338                         if (inet_aton(optarg, &gateway[lsrr]) == 0) {
339                                 hp = gethostbyname(optarg);
340                                 if (hp == 0)
341                                         errx(1, "unknown host %s", optarg);
342                                 memcpy(&gateway[lsrr], hp->h_addr, hp->h_length);
343                         }
344                         if (++lsrr == 1)
345                                 lsrrlen = 4;
346                         lsrrlen += 4;
347                         break;
348                 case 'I':
349                         if (protoset)
350                                 errx(1, "protocol already set with -P");
351                         protoset = 1;
352                         proto = IPPROTO_ICMP;
353                         break;
354                 case 'l':
355                         ttl_flag++;
356                         break;
357                 case 'm':
358                         errno = 0;
359                         ep = NULL;
360                         l = strtol(optarg, &ep, 10);
361                         if (errno || !*optarg || *ep || l < first_ttl ||
362                             l > MAXTTL)
363                                 errx(1, "max ttl must be %u to %u.", first_ttl,
364                                     MAXTTL);
365                         max_ttl = (u_int8_t)l;
366                         break;
367                 case 'n':
368                         nflag++;
369                         break;
370                 case 'p':
371                         errno = 0;
372                         ep = NULL;
373                         l = strtol(optarg, &ep, 10);
374                         if (errno || !*optarg || *ep || l <= 0 || l >= 65536)
375                                 errx(1, "port must be >0, <65536.");
376                         port = (int)l;
377                         break;
378                 case 'P':
379                         if (protoset)
380                                 errx(1, "protocol already set with -I");
381                         protoset = 1;
382                         errno = 0;
383                         ep = NULL;
384                         l = strtol(optarg, &ep, 10);
385                         if (errno || !*optarg || *ep || l < 1 ||
386                             l >= IPPROTO_MAX) {
387                                 struct protoent *pent;
388
389                                 pent = getprotobyname(optarg);
390                                 if (pent)
391                                         proto = pent->p_proto;
392                                 else
393                                         errx(1, "proto must be >=1, or a name.");
394                         } else
395                                 proto = (int)l;
396                         break;
397                 case 'q':
398                         errno = 0;
399                         ep = NULL;
400                         l = strtol(optarg, &ep, 10);
401                         if (errno || !*optarg || *ep || l < 1 || l > INT_MAX)
402                                 errx(1, "nprobes must be >0.");
403                         nprobes = (int)l;
404                         break;
405                 case 'r':
406                         options |= SO_DONTROUTE;
407                         break;
408                 case 's':
409                         /*
410                          * set the ip source address of the outbound
411                          * probe (e.g., on a multi-homed host).
412                          */
413                         source = optarg;
414                         break;
415                 case 't':
416                         errno = 0;
417                         ep = NULL;
418                         l = strtol(optarg, &ep, 10);
419                         if (errno || !*optarg || *ep || l < 0 || l > 255)
420                                 errx(1, "tos must be 0 to 255.");
421                         tos = (int)l;
422                         break;
423                 case 'v':
424                         verbose++;
425                         break;
426                 case 'w':
427                         errno = 0;
428                         ep = NULL;
429                         l = strtol(optarg, &ep, 10);
430                         if (errno || !*optarg || *ep || l <= 1 || l > INT_MAX)
431                                 errx(1, "wait must be >1 sec.");
432                         waittime = (int)l;
433                         break;
434                 default:
435                         usage();
436                 }
437         argc -= optind;
438         argv += optind;
439
440         if (argc < 1)
441                 usage();
442
443         setlinebuf (stdout);
444
445         memset(&to, 0, sizeof(struct sockaddr));
446         to.sin_family = AF_INET;
447         if (inet_aton(*argv, &to.sin_addr) != 0)
448                 hostname = *argv;
449         else {
450                 hp = gethostbyname(*argv);
451                 if (hp == 0)
452                         errx(1, "unknown host %s", *argv);
453                 to.sin_family = hp->h_addrtype;
454                 memcpy(&to.sin_addr, hp->h_addr, hp->h_length);
455                 if ((hostname = strdup(hp->h_name)) == NULL)
456                         err(1, "malloc");
457                 if (hp->h_addr_list[1] != NULL)
458                         warnx("Warning: %s has multiple addresses; using %s",
459                             hostname, inet_ntoa(to.sin_addr));
460         }
461         if (*++argv) {
462                 errno = 0;
463                 ep = NULL;
464                 l = strtol(*argv, &ep, 10);
465                 if (errno || !*argv || *ep || l < 0 || l > INT_MAX)
466                         errx(1, "datalen out of range");
467                 datalen = (int)l;
468         }
469
470         switch (proto) {
471         case IPPROTO_UDP:
472                 headerlen = (sizeof(struct ip) + lsrrlen +
473                     sizeof(struct udphdr) + sizeof(struct packetdata));
474                 break;
475         case IPPROTO_ICMP:
476                 headerlen = (sizeof(struct ip) + lsrrlen +
477                     sizeof(struct icmp) + sizeof(struct packetdata));
478                 break;
479         default:
480                 headerlen = (sizeof(struct ip) + lsrrlen +
481                     sizeof(struct packetdata));
482         }
483
484         if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
485                 errx(1, "packet size must be 0 to %d.",
486                     IP_MAXPACKET - headerlen);
487
488         datalen += headerlen;
489
490         outpacket = (u_char *)malloc(datalen);
491         if (outpacket == NULL)
492                 err(1, "malloc");
493         memset(outpacket, 0, datalen);
494
495         ip = (struct ip *)outpacket;
496         if (lsrr != 0) {
497                 u_char *p = (u_char *)(ip + 1);
498
499                 *p++ = IPOPT_NOP;
500                 *p++ = IPOPT_LSRR;
501                 *p++ = lsrrlen - 1;
502                 *p++ = IPOPT_MINOFF;
503                 gateway[lsrr] = to.sin_addr;
504                 for (i = 1; i <= lsrr; i++) {
505                         memcpy(p, &gateway[i], sizeof(struct in_addr));
506                         p += sizeof(struct in_addr);
507                 }
508                 ip->ip_dst = gateway[0];
509         } else
510                 ip->ip_dst = to.sin_addr;
511         ip->ip_off = htons(0);
512         ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;
513         ip->ip_p = proto;
514         ip->ip_v = IPVERSION;
515         ip->ip_tos = tos;
516
517         ident = (getpid() & 0xffff) | 0x8000;
518         tmprnd = arc4random();
519         sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :
520             (tmprnd & 0x7ff);
521         usec_perturb = arc4random();
522
523         if (options & SO_DEBUG)
524                 setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));
525 #ifdef SO_SNDBUF
526         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
527             sizeof(datalen)) < 0)
528                 err(6, "SO_SNDBUF");
529 #endif /* SO_SNDBUF */
530 #ifdef IP_HDRINCL
531         if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
532             sizeof(on)) < 0)
533                 err(6, "IP_HDRINCL");
534 #endif /* IP_HDRINCL */
535         if (options & SO_DEBUG)
536                 setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
537                     (char *)&on, sizeof(on));
538         if (options & SO_DONTROUTE)
539                 setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
540                     (char *)&on, sizeof(on));
541
542         if (source) {
543                 memset(&from, 0, sizeof(struct sockaddr));
544                 from.sin_family = AF_INET;
545                 if (inet_aton(source, &from.sin_addr) == 0)
546                         errx(1, "unknown host %s", source);
547                 ip->ip_src = from.sin_addr;
548                 if (getuid() != 0 &&
549                     (ntohl(from.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U &&
550                     (ntohl(to.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U)
551                         errx(1, "source is on 127/8, destination is not");
552
553                 if (getuid() &&
554                     bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
555                         err(1, "bind");
556         }
557
558         fprintf(stderr, "traceroute to %s (%s)", hostname,
559                 inet_ntoa(to.sin_addr));
560         if (source)
561                 fprintf(stderr, " from %s", source);
562         fprintf(stderr, ", %u hops max, %d byte packets\n", max_ttl, datalen);
563         fflush(stderr);
564
565         if (first_ttl > 1)
566                 printf("Skipping %u intermediate hops\n", first_ttl - 1);
567
568         for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
569                 int got_there = 0, unreachable = 0, timeout = 0, loss;
570                 in_addr_t lastaddr = 0;
571                 quad_t dt;
572
573                 printf("%2u ", ttl);
574                 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
575                         int cc;
576                         struct timeval t1, t2;
577                         int code;
578
579                         gettimeofday(&t1, NULL);
580                         send_probe(++seq, ttl, incflag, &to);
581                         while ((cc = wait_for_reply(s, &from, &t1))) {
582                                 gettimeofday(&t2, NULL);
583                                 if (t2.tv_sec - t1.tv_sec > waittime) {
584                                         cc = 0;
585                                         break;
586                                 }
587                                 i = packet_ok(packet, cc, &from, seq, incflag);
588                                 /* Skip short packet */
589                                 if (i == 0)
590                                         continue;
591                                 if (from.sin_addr.s_addr != lastaddr) {
592                                         print(packet, cc, &from);
593                                         lastaddr = from.sin_addr.s_addr;
594                                 }
595                                 dt = (quad_t)(t2.tv_sec - t1.tv_sec) * 1000000 +
596                                     (quad_t)(t2.tv_usec - t1.tv_usec);
597                                 printf("  %u", (u_int)(dt / 1000));
598                                 if (dt % 1000)
599                                         printf(".%u", (u_int)(dt % 1000));
600                                 printf(" ms");
601                                 ip = (struct ip *)packet;
602                                 if (ttl_flag)
603                                         printf(" (%u)", ip->ip_ttl);
604                                 if (i == -2) {
605 #ifndef ARCHAIC
606                                         ip = (struct ip *)packet;
607                                         if (ip->ip_ttl <= 1)
608                                                 printf(" !");
609 #endif
610                                         ++got_there;
611                                         break;
612                                 }
613                                 /* time exceeded in transit */
614                                 if (i == -1)
615                                         break;
616                                 code = i - 1;
617                                 switch (code) {
618                                 case ICMP_UNREACH_PORT:
619 #ifndef ARCHAIC
620                                         ip = (struct ip *)packet;
621                                         if (ip->ip_ttl <= 1)
622                                                 printf(" !");
623 #endif /* ARCHAIC */
624                                         ++got_there;
625                                         break;
626                                 case ICMP_UNREACH_NET:
627                                         ++unreachable;
628                                         printf(" !N");
629                                         break;
630                                 case ICMP_UNREACH_HOST:
631                                         ++unreachable;
632                                         printf(" !H");
633                                         break;
634                                 case ICMP_UNREACH_PROTOCOL:
635                                         ++got_there;
636                                         printf(" !P");
637                                         break;
638                                 case ICMP_UNREACH_NEEDFRAG:
639                                         ++unreachable;
640                                         printf(" !F");
641                                         break;
642                                 case ICMP_UNREACH_SRCFAIL:
643                                         ++unreachable;
644                                         printf(" !S");
645                                         break;
646                                 case ICMP_UNREACH_FILTER_PROHIB:
647                                         ++unreachable;
648                                         printf(" !X");
649                                         break;
650                                 case ICMP_UNREACH_NET_PROHIB: /*misuse*/
651                                         ++unreachable;
652                                         printf(" !A");
653                                         break;
654                                 case ICMP_UNREACH_HOST_PROHIB:
655                                         ++unreachable;
656                                         printf(" !C");
657                                         break;
658                                 case ICMP_UNREACH_NET_UNKNOWN:
659                                 case ICMP_UNREACH_HOST_UNKNOWN:
660                                         ++unreachable;
661                                         printf(" !U");
662                                         break;
663                                 case ICMP_UNREACH_ISOLATED:
664                                         ++unreachable;
665                                         printf(" !I");
666                                         break;
667                                 case ICMP_UNREACH_TOSNET:
668                                 case ICMP_UNREACH_TOSHOST:
669                                         ++unreachable;
670                                         printf(" !T");
671                                         break;
672                                 default:
673                                         ++unreachable;
674                                         printf(" !<%d>", i - 1);
675                                         break;
676                                 }
677                                 break;
678                         }
679                         if (cc == 0) {
680                                 printf(" *");
681                                 timeout++;
682                                 loss++;
683                         }
684                         fflush(stdout);
685                 }
686                 if (sump)
687                         printf(" (%d%% loss)", (loss * 100) / nprobes);
688                 putchar('\n');
689                 if (got_there || (unreachable && (unreachable + timeout) >= nprobes))
690                         break;
691         }
692         exit(0);
693 }
694
695 int
696 wait_for_reply(int sock, struct sockaddr_in *from, struct timeval *sent)
697 {
698         socklen_t fromlen = sizeof (*from);
699         struct timeval now, wait;
700         int cc = 0, fdsn;
701         fd_set *fdsp;
702
703         fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
704         if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
705                 err(1, "malloc");
706         memset(fdsp, 0, fdsn);
707         FD_SET(sock, fdsp);
708         gettimeofday(&now, NULL);
709         wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec;
710         wait.tv_usec =  sent->tv_usec - now.tv_usec;
711         if (wait.tv_usec < 0) {
712                 wait.tv_usec += 1000000;
713                 wait.tv_sec--;
714         }
715         if (wait.tv_sec < 0)
716                 wait.tv_sec = wait.tv_usec = 0;
717
718         if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
719                 cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
720                     (struct sockaddr *)from, &fromlen);
721
722         free(fdsp);
723         return (cc);
724 }
725
726 void
727 dump_packet(void)
728 {
729         u_char *p;
730         int i;
731
732         fprintf(stderr, "packet data:");
733         for (p = outpacket, i = 0; i < datalen; i++) {
734                 if ((i % 24) == 0)
735                         fprintf(stderr, "\n ");
736                 fprintf(stderr, " %02x", *p++);
737         }
738         fprintf(stderr, "\n");
739 }
740
741 void
742 send_probe(int seq, u_int8_t ttl, int iflag, struct sockaddr_in *to)
743 {
744         struct ip *ip = (struct ip *)outpacket;
745         u_char *p = (u_char *)(ip + 1);
746         struct udphdr *up = (struct udphdr *)(p + lsrrlen);
747         struct icmp *icmpp = (struct icmp *)(p + lsrrlen);
748         struct packetdata *op;
749         struct timeval tv;
750         int i;
751
752         ip->ip_len = datalen;
753         ip->ip_ttl = ttl;
754         ip->ip_id = htons(ident+seq);
755
756         switch (proto) {
757         case IPPROTO_ICMP:
758                 icmpp->icmp_type = icmp_type;
759                 icmpp->icmp_code = icmp_code;
760                 icmpp->icmp_seq = htons(seq);
761                 icmpp->icmp_id = htons(ident);
762                 op = (struct packetdata *)(icmpp + 1);
763                 break;
764         case IPPROTO_UDP:
765                 up->uh_sport = htons(ident);
766                 if (iflag)
767                         up->uh_dport = htons(port+seq);
768                 else
769                         up->uh_dport = htons(port);
770                 up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
771                     lsrrlen));
772                 up->uh_sum = 0;
773                 op = (struct packetdata *)(up + 1);
774                 break;
775         default:
776                 op = (struct packetdata *)(ip + 1);
777                 break;
778         }
779         op->seq = seq;
780         op->ttl = ttl;
781
782         /*
783          * We don't want hostiles snooping the net to get any useful
784          * information about us. Send the timestamp in network byte order,
785          * and perturb the timestamp enough that they won't know our
786          * real clock ticker. We don't want to perturb the time by too
787          * much: being off by a suspiciously large amount might indicate
788          * OpenBSD.
789          *
790          * The timestamps in the packet are currently unused. If future
791          * work wants to use them they will have to subtract out the
792          * perturbation first.
793          */
794         gettimeofday(&tv, NULL);
795         op->sec = htonl(tv.tv_sec + sec_perturb);
796         op->usec = htonl((tv.tv_usec + usec_perturb) % 1000000);
797
798         if (proto == IPPROTO_ICMP && icmp_type == ICMP_ECHO) {
799                 icmpp->icmp_cksum = 0;
800                 icmpp->icmp_cksum = in_cksum((u_short *)icmpp,
801                     datalen - sizeof(struct ip) - lsrrlen);
802                 if (icmpp->icmp_cksum == 0)
803                         icmpp->icmp_cksum = 0xffff;
804         }
805
806         if (dump)
807                 dump_packet();
808
809         i = sendto(sndsock, outpacket, datalen, 0, (struct sockaddr *)to,
810             sizeof(struct sockaddr_in));
811         if (i < 0 || i != datalen)  {
812                 if (i < 0)
813                         perror("sendto");
814                 printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
815                     datalen, i);
816                 fflush(stdout);
817         }
818 }
819
820 static const char *ttab[] = {
821         "Echo Reply",
822         "ICMP 1",
823         "ICMP 2",
824         "Dest Unreachable",
825         "Source Quench",
826         "Redirect",
827         "ICMP 6",
828         "ICMP 7",
829         "Echo",
830         "Router Advert",
831         "Router Solicit",
832         "Time Exceeded",
833         "Param Problem",
834         "Timestamp",
835         "Timestamp Reply",
836         "Info Request",
837         "Info Reply",
838         "Mask Request",
839         "Mask Reply"
840 };
841
842 /*
843  * Convert an ICMP "type" field to a printable string.
844  */
845 const char *
846 pr_type(u_int8_t t)
847 {
848         if (t > 18)
849                 return ("OUT-OF-RANGE");
850         return (ttab[t]);
851 }
852
853 int
854 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq, int iflag)
855 {
856         struct icmp *icp;
857         u_char code;
858         u_int8_t type;
859         int hlen;
860 #ifndef ARCHAIC
861         struct ip *ip;
862
863         ip = (struct ip *) buf;
864         hlen = ip->ip_hl << 2;
865         if (cc < hlen + ICMP_MINLEN) {
866                 if (verbose)
867                         printf("packet too short (%d bytes) from %s\n", cc,
868                             inet_ntoa(from->sin_addr));
869                 return (0);
870         }
871         cc -= hlen;
872         icp = (struct icmp *)(buf + hlen);
873 #else
874         icp = (struct icmp *)buf;
875 #endif /* ARCHAIC */
876         type = icp->icmp_type;
877         code = icp->icmp_code;
878         if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
879             type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
880                 struct ip *hip;
881                 struct udphdr *up;
882                 struct icmp *icmpp;
883
884                 hip = &icp->icmp_ip;
885                 hlen = hip->ip_hl << 2;
886
887                 switch (proto) {
888                 case IPPROTO_ICMP:
889                         if (icmp_type == ICMP_ECHO &&
890                             type == ICMP_ECHOREPLY &&
891                             icp->icmp_id == htons(ident) &&
892                             icp->icmp_seq == htons(seq))
893                                 return (-2); /* we got there */
894
895                         icmpp = (struct icmp *)((u_char *)hip + hlen);
896                         if (hlen + 8 <= cc && hip->ip_p == IPPROTO_ICMP &&
897                             icmpp->icmp_id == htons(ident) &&
898                             icmpp->icmp_seq == htons(seq))
899                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
900                         break;
901
902                 case IPPROTO_UDP:
903                         up = (struct udphdr *)((u_char *)hip + hlen);
904                         if (hlen + 12 <= cc && hip->ip_p == proto &&
905                             up->uh_sport == htons(ident) &&
906                             ((iflag && up->uh_dport == htons(port + seq)) ||
907                             (!iflag && up->uh_dport == htons(port))))
908                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
909                         break;
910                 default:
911                         /* this is some odd, user specified proto,
912                          * how do we check it?
913                          */
914                         if (hip->ip_p == proto)
915                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
916                 }
917         }
918 #ifndef ARCHAIC
919         if (verbose) {
920                 int i;
921                 in_addr_t *lp = (in_addr_t *)&icp->icmp_ip;
922
923                 printf("\n%d bytes from %s", cc, inet_ntoa(from->sin_addr));
924                 printf(" to %s", inet_ntoa(ip->ip_dst));
925                 printf(": icmp type %u (%s) code %d\n", type, pr_type(type),
926                     icp->icmp_code);
927                 for (i = 4; i < cc ; i += sizeof(in_addr_t))
928                         printf("%2d: x%8.8lx\n", i, (unsigned long)*lp++);
929         }
930 #endif /* ARCHAIC */
931         return (0);
932 }
933
934 void
935 print(u_char *buf, int cc, struct sockaddr_in *from)
936 {
937         struct ip *ip;
938         int hlen;
939
940         ip = (struct ip *) buf;
941         hlen = ip->ip_hl << 2;
942         cc -= hlen;
943
944         if (nflag)
945                 printf(" %s", inet_ntoa(from->sin_addr));
946         else
947                 printf(" %s (%s)", inetname(from->sin_addr),
948                     inet_ntoa(from->sin_addr));
949
950         if (verbose)
951                 printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
952 }
953
954
955 /*
956  * Checksum routine for Internet Protocol family headers (C Version)
957  */
958 u_short
959 in_cksum(u_short *addr, int len)
960 {
961         u_short *w = addr, answer;
962         int nleft = len, sum = 0;
963
964         /*
965          *  Our algorithm is simple, using a 32 bit accumulator (sum),
966          *  we add sequential 16 bit words to it, and at the end, fold
967          *  back all the carry bits from the top 16 bits into the lower
968          *  16 bits.
969          */
970         while (nleft > 1)  {
971                 sum += *w++;
972                 nleft -= 2;
973         }
974
975         /* mop up an odd byte, if necessary */
976         if (nleft == 1)
977                 sum += *(u_char *)w;
978
979         /*
980          * add back carry outs from top 16 bits to low 16 bits
981          */
982         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
983         sum += (sum >> 16);                     /* add carry */
984         answer = ~sum;                          /* truncate to 16 bits */
985         return (answer);
986 }
987
988 /*
989  * Construct an Internet address representation.
990  * If the nflag has been supplied, give
991  * numeric value, otherwise try for symbolic name.
992  */
993 char *
994 inetname(struct in_addr in)
995 {
996         static char domain[MAXHOSTNAMELEN], line[MAXHOSTNAMELEN];
997         static int first = 1;
998         struct hostent *hp;
999         char *cp;
1000
1001         if (first && !nflag) {
1002                 first = 0;
1003                 if (gethostname(domain, sizeof domain) == 0 &&
1004                     (cp = strchr(domain, '.')) != NULL) {
1005                         strlcpy(domain, cp + 1, sizeof(domain));
1006                 }
1007         }
1008         if (!nflag && in.s_addr != INADDR_ANY) {
1009                 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1010                 if (hp != NULL) {
1011                         if ((cp = strchr(hp->h_name, '.')) != NULL &&
1012                             strcmp(cp + 1, domain) == 0)
1013                                 *cp = '\0';
1014                         strlcpy(line, hp->h_name, sizeof(line));
1015                         return (line);
1016                 }
1017         }
1018         return (inet_ntoa(in));
1019 }
1020
1021 void
1022 usage(void)
1023 {
1024         fprintf(stderr,
1025             "usage: %s [-cdDIlnrSv] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
1026             "\t[-p port] [-P proto] [-q nqueries] [-s src_addr] [-t tos]\n"
1027             "\t[-w waittime] host [packetsize]\n", getprogname());
1028         exit(1);
1029 }