ICMP extensions for MPLS support for traceroute(8).
[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.7 2007/05/23 06:38:22 hasso 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 /*
248  * Support for ICMP extensions - draft-ietf-mpls-icmp-08.txt 
249  */
250 #define ICMP_EXT_OFFSET  8 + 128 /* ICMP type, code, checksum (unused)
251                                   * + original datagram */
252 #define ICMP_EXT_VERSION 2
253
254 /* ICMP Extension Header according to RFC4884. */
255 #define EXT_VERSION(x)  (((x) & 0xf0000000) >> 28)
256 #define EXT_CHECKSUM(x) ((x) & 0x0000ffff)
257
258 /*
259  * ICMP extensions, object header
260  */
261 struct icmp_ext_obj_hdr {
262         u_short length;
263         u_char  class_num;
264 #define MPLS_STACK_ENTRY_CLASS 1
265         u_char  c_type;
266 #define MPLS_STACK_ENTRY_C_TYPE 1
267 };
268
269 /* MPLS Label Stack Object. */
270 #define MPLS_LABEL(x)   (((x) & 0xfffff000) >> 12)
271 #define MPLS_EXP(x)     (((x) & 0x00000e00) >> 9)
272 #define MPLS_STACK(x)   (((x) & 0x00000100) >> 8)
273 #define MPLS_TTL(x)     ((x) & 0x000000ff)
274
275 struct in_addr gateway[MAX_LSRR + 1];
276 int lsrrlen = 0;
277 int32_t sec_perturb;
278 int32_t usec_perturb;
279
280 u_char packet[512], *outpacket; /* last inbound (icmp) packet */
281
282 void decode_extensions(unsigned char *, int);
283 void dump_packet(void);
284 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
285 void send_probe(int, u_int8_t, int, struct sockaddr_in *);
286 int packet_ok(u_char *, int, struct sockaddr_in *, int, int);
287 const char *pr_type(u_int8_t);
288 void print(u_char *, int, struct sockaddr_in *);
289 char *inetname(struct in_addr);
290 u_short in_cksum(u_short *, int);
291 void usage(void);
292
293 int s;                          /* receive (icmp) socket file descriptor */
294 int sndsock;                    /* send (udp) socket file descriptor */
295
296 int datalen;                    /* How much data */
297 int headerlen;                  /* How long packet's header is */
298
299 char *source = 0;
300 char *hostname;
301
302 int nprobes = 3;
303 u_int8_t max_ttl = IPDEFTTL;
304 u_int8_t first_ttl = 1;
305 u_short ident;
306 u_short port = 32768+666;       /* start udp dest port # for probe packets */
307 u_char  proto = IPPROTO_UDP;
308 u_int8_t  icmp_type = ICMP_ECHO; /* default ICMP code/type */
309 u_char  icmp_code = 0;
310 int options;                    /* socket options */
311 int verbose;
312 int waittime = 5;               /* time to wait for response (in seconds) */
313 int nflag;                      /* print addresses numerically */
314 int dump;
315 int Mflag;                      /* show MPLS labels if any */
316
317 int
318 main(int argc, char *argv[])
319 {
320         int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
321         int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
322         int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0;
323         size_t size = sizeof(max_ttl);
324         struct sockaddr_in from, to;
325         struct hostent *hp;
326         u_int32_t tmprnd;
327         struct ip *ip;
328         u_int8_t ttl;
329         char *ep;
330         long l;
331
332         if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
333                 err(5, "icmp socket");
334         if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
335                 err(5, "raw socket");
336
337         /* revoke privs */
338         seteuid(getuid());
339         setuid(getuid());
340
341         sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size, NULL, 0);
342
343         while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:cM")) != -1)
344                 switch (ch) {
345                 case 'S':
346                         sump = 1;
347                         break;
348                 case 'f':
349                         errno = 0;
350                         ep = NULL;
351                         l = strtol(optarg, &ep, 10);
352                         if (errno || !*optarg || *ep || l < 1 || l > max_ttl)
353                                 errx(1, "min ttl must be 1 to %u.", max_ttl);
354                         first_ttl = (u_int8_t)l;
355                         break;
356                 case 'c':
357                         incflag = 0;
358                         break;
359                 case 'd':
360                         options |= SO_DEBUG;
361                         break;
362                 case 'D':
363                         dump = 1;
364                         break;
365                 case 'g':
366                         if (lsrr >= MAX_LSRR)
367                                 errx(1, "too many gateways; max %d", MAX_LSRR);
368                         if (inet_aton(optarg, &gateway[lsrr]) == 0) {
369                                 hp = gethostbyname(optarg);
370                                 if (hp == 0)
371                                         errx(1, "unknown host %s", optarg);
372                                 memcpy(&gateway[lsrr], hp->h_addr, hp->h_length);
373                         }
374                         if (++lsrr == 1)
375                                 lsrrlen = 4;
376                         lsrrlen += 4;
377                         break;
378                 case 'I':
379                         if (protoset)
380                                 errx(1, "protocol already set with -P");
381                         protoset = 1;
382                         proto = IPPROTO_ICMP;
383                         break;
384                 case 'l':
385                         ttl_flag++;
386                         break;
387                 case 'm':
388                         errno = 0;
389                         ep = NULL;
390                         l = strtol(optarg, &ep, 10);
391                         if (errno || !*optarg || *ep || l < first_ttl ||
392                             l > MAXTTL)
393                                 errx(1, "max ttl must be %u to %u.", first_ttl,
394                                     MAXTTL);
395                         max_ttl = (u_int8_t)l;
396                         break;
397                 case 'M':
398                         Mflag = 1;
399                         break;
400                 case 'n':
401                         nflag++;
402                         break;
403                 case 'p':
404                         errno = 0;
405                         ep = NULL;
406                         l = strtol(optarg, &ep, 10);
407                         if (errno || !*optarg || *ep || l <= 0 || l >= 65536)
408                                 errx(1, "port must be >0, <65536.");
409                         port = (int)l;
410                         break;
411                 case 'P':
412                         if (protoset)
413                                 errx(1, "protocol already set with -I");
414                         protoset = 1;
415                         errno = 0;
416                         ep = NULL;
417                         l = strtol(optarg, &ep, 10);
418                         if (errno || !*optarg || *ep || l < 1 ||
419                             l >= IPPROTO_MAX) {
420                                 struct protoent *pent;
421
422                                 pent = getprotobyname(optarg);
423                                 if (pent)
424                                         proto = pent->p_proto;
425                                 else
426                                         errx(1, "proto must be >=1, or a name.");
427                         } else
428                                 proto = (int)l;
429                         break;
430                 case 'q':
431                         errno = 0;
432                         ep = NULL;
433                         l = strtol(optarg, &ep, 10);
434                         if (errno || !*optarg || *ep || l < 1 || l > INT_MAX)
435                                 errx(1, "nprobes must be >0.");
436                         nprobes = (int)l;
437                         break;
438                 case 'r':
439                         options |= SO_DONTROUTE;
440                         break;
441                 case 's':
442                         /*
443                          * set the ip source address of the outbound
444                          * probe (e.g., on a multi-homed host).
445                          */
446                         source = optarg;
447                         break;
448                 case 't':
449                         errno = 0;
450                         ep = NULL;
451                         l = strtol(optarg, &ep, 10);
452                         if (errno || !*optarg || *ep || l < 0 || l > 255)
453                                 errx(1, "tos must be 0 to 255.");
454                         tos = (int)l;
455                         break;
456                 case 'v':
457                         verbose++;
458                         break;
459                 case 'w':
460                         errno = 0;
461                         ep = NULL;
462                         l = strtol(optarg, &ep, 10);
463                         if (errno || !*optarg || *ep || l <= 1 || l > INT_MAX)
464                                 errx(1, "wait must be >1 sec.");
465                         waittime = (int)l;
466                         break;
467                 default:
468                         usage();
469                 }
470         argc -= optind;
471         argv += optind;
472
473         if (argc < 1)
474                 usage();
475
476         setlinebuf (stdout);
477
478         memset(&to, 0, sizeof(struct sockaddr));
479         to.sin_family = AF_INET;
480         if (inet_aton(*argv, &to.sin_addr) != 0)
481                 hostname = *argv;
482         else {
483                 hp = gethostbyname(*argv);
484                 if (hp == 0)
485                         errx(1, "unknown host %s", *argv);
486                 to.sin_family = hp->h_addrtype;
487                 memcpy(&to.sin_addr, hp->h_addr, hp->h_length);
488                 if ((hostname = strdup(hp->h_name)) == NULL)
489                         err(1, "malloc");
490                 if (hp->h_addr_list[1] != NULL)
491                         warnx("Warning: %s has multiple addresses; using %s",
492                             hostname, inet_ntoa(to.sin_addr));
493         }
494         if (*++argv) {
495                 errno = 0;
496                 ep = NULL;
497                 l = strtol(*argv, &ep, 10);
498                 if (errno || !*argv || *ep || l < 0 || l > INT_MAX)
499                         errx(1, "datalen out of range");
500                 datalen = (int)l;
501         }
502
503         switch (proto) {
504         case IPPROTO_UDP:
505                 headerlen = (sizeof(struct ip) + lsrrlen +
506                     sizeof(struct udphdr) + sizeof(struct packetdata));
507                 break;
508         case IPPROTO_ICMP:
509                 headerlen = (sizeof(struct ip) + lsrrlen +
510                     sizeof(struct icmp) + sizeof(struct packetdata));
511                 break;
512         default:
513                 headerlen = (sizeof(struct ip) + lsrrlen +
514                     sizeof(struct packetdata));
515         }
516
517         if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
518                 errx(1, "packet size must be 0 to %d.",
519                     IP_MAXPACKET - headerlen);
520
521         datalen += headerlen;
522
523         outpacket = (u_char *)malloc(datalen);
524         if (outpacket == NULL)
525                 err(1, "malloc");
526         memset(outpacket, 0, datalen);
527
528         ip = (struct ip *)outpacket;
529         if (lsrr != 0) {
530                 u_char *p = (u_char *)(ip + 1);
531
532                 *p++ = IPOPT_NOP;
533                 *p++ = IPOPT_LSRR;
534                 *p++ = lsrrlen - 1;
535                 *p++ = IPOPT_MINOFF;
536                 gateway[lsrr] = to.sin_addr;
537                 for (i = 1; i <= lsrr; i++) {
538                         memcpy(p, &gateway[i], sizeof(struct in_addr));
539                         p += sizeof(struct in_addr);
540                 }
541                 ip->ip_dst = gateway[0];
542         } else
543                 ip->ip_dst = to.sin_addr;
544         ip->ip_off = htons(0);
545         ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;
546         ip->ip_p = proto;
547         ip->ip_v = IPVERSION;
548         ip->ip_tos = tos;
549
550         ident = (getpid() & 0xffff) | 0x8000;
551         tmprnd = arc4random();
552         sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :
553             (tmprnd & 0x7ff);
554         usec_perturb = arc4random();
555
556         if (options & SO_DEBUG)
557                 setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));
558 #ifdef SO_SNDBUF
559         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
560             sizeof(datalen)) < 0)
561                 err(6, "SO_SNDBUF");
562 #endif /* SO_SNDBUF */
563 #ifdef IP_HDRINCL
564         if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
565             sizeof(on)) < 0)
566                 err(6, "IP_HDRINCL");
567 #endif /* IP_HDRINCL */
568         if (options & SO_DEBUG)
569                 setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
570                     (char *)&on, sizeof(on));
571         if (options & SO_DONTROUTE)
572                 setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
573                     (char *)&on, sizeof(on));
574
575         if (source) {
576                 memset(&from, 0, sizeof(struct sockaddr));
577                 from.sin_family = AF_INET;
578                 if (inet_aton(source, &from.sin_addr) == 0)
579                         errx(1, "unknown host %s", source);
580                 ip->ip_src = from.sin_addr;
581                 if (getuid() != 0 &&
582                     (ntohl(from.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U &&
583                     (ntohl(to.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U)
584                         errx(1, "source is on 127/8, destination is not");
585
586                 if (getuid() &&
587                     bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
588                         err(1, "bind");
589         }
590
591         fprintf(stderr, "traceroute to %s (%s)", hostname,
592                 inet_ntoa(to.sin_addr));
593         if (source)
594                 fprintf(stderr, " from %s", source);
595         fprintf(stderr, ", %u hops max, %d byte packets\n", max_ttl, datalen);
596         fflush(stderr);
597
598         if (first_ttl > 1)
599                 printf("Skipping %u intermediate hops\n", first_ttl - 1);
600
601         for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
602                 int got_there = 0, unreachable = 0, timeout = 0, loss;
603                 in_addr_t lastaddr = 0;
604                 quad_t dt;
605
606                 printf("%2u ", ttl);
607                 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
608                         int cc;
609                         struct timeval t1, t2;
610                         int code;
611
612                         gettimeofday(&t1, NULL);
613                         send_probe(++seq, ttl, incflag, &to);
614                         while ((cc = wait_for_reply(s, &from, &t1))) {
615                                 gettimeofday(&t2, NULL);
616                                 if (t2.tv_sec - t1.tv_sec > waittime) {
617                                         cc = 0;
618                                         break;
619                                 }
620                                 i = packet_ok(packet, cc, &from, seq, incflag);
621                                 /* Skip short packet */
622                                 if (i == 0)
623                                         continue;
624                                 if (from.sin_addr.s_addr != lastaddr) {
625                                         print(packet, cc, &from);
626                                         lastaddr = from.sin_addr.s_addr;
627                                 }
628                                 dt = (quad_t)(t2.tv_sec - t1.tv_sec) * 1000000 +
629                                     (quad_t)(t2.tv_usec - t1.tv_usec);
630                                 printf("  %u", (u_int)(dt / 1000));
631                                 if (dt % 1000)
632                                         printf(".%u", (u_int)(dt % 1000));
633                                 printf(" ms");
634                                 ip = (struct ip *)packet;
635                                 if (ttl_flag)
636                                         printf(" (%u)", ip->ip_ttl);
637                                 if (i == -2) {
638 #ifndef ARCHAIC
639                                         ip = (struct ip *)packet;
640                                         if (ip->ip_ttl <= 1)
641                                                 printf(" !");
642 #endif
643                                         ++got_there;
644                                         break;
645                                 }
646                                 /* time exceeded in transit */
647                                 if (i == -1)
648                                         break;
649                                 code = i - 1;
650                                 switch (code) {
651                                 case ICMP_UNREACH_PORT:
652 #ifndef ARCHAIC
653                                         ip = (struct ip *)packet;
654                                         if (ip->ip_ttl <= 1)
655                                                 printf(" !");
656 #endif /* ARCHAIC */
657                                         ++got_there;
658                                         break;
659                                 case ICMP_UNREACH_NET:
660                                         ++unreachable;
661                                         printf(" !N");
662                                         break;
663                                 case ICMP_UNREACH_HOST:
664                                         ++unreachable;
665                                         printf(" !H");
666                                         break;
667                                 case ICMP_UNREACH_PROTOCOL:
668                                         ++got_there;
669                                         printf(" !P");
670                                         break;
671                                 case ICMP_UNREACH_NEEDFRAG:
672                                         ++unreachable;
673                                         printf(" !F");
674                                         break;
675                                 case ICMP_UNREACH_SRCFAIL:
676                                         ++unreachable;
677                                         printf(" !S");
678                                         break;
679                                 case ICMP_UNREACH_FILTER_PROHIB:
680                                         ++unreachable;
681                                         printf(" !X");
682                                         break;
683                                 case ICMP_UNREACH_NET_PROHIB: /*misuse*/
684                                         ++unreachable;
685                                         printf(" !A");
686                                         break;
687                                 case ICMP_UNREACH_HOST_PROHIB:
688                                         ++unreachable;
689                                         printf(" !C");
690                                         break;
691                                 case ICMP_UNREACH_NET_UNKNOWN:
692                                 case ICMP_UNREACH_HOST_UNKNOWN:
693                                         ++unreachable;
694                                         printf(" !U");
695                                         break;
696                                 case ICMP_UNREACH_ISOLATED:
697                                         ++unreachable;
698                                         printf(" !I");
699                                         break;
700                                 case ICMP_UNREACH_TOSNET:
701                                 case ICMP_UNREACH_TOSHOST:
702                                         ++unreachable;
703                                         printf(" !T");
704                                         break;
705                                 default:
706                                         ++unreachable;
707                                         printf(" !<%d>", i - 1);
708                                         break;
709                                 }
710                                 break;
711                         }
712                         if (cc == 0) {
713                                 printf(" *");
714                                 timeout++;
715                                 loss++;
716                         }
717                         else if (cc && probe == nprobes - 1 && Mflag)
718                                 decode_extensions(packet, cc);
719                         fflush(stdout);
720                 }
721                 if (sump)
722                         printf(" (%d%% loss)", (loss * 100) / nprobes);
723                 putchar('\n');
724                 if (got_there || (unreachable && (unreachable + timeout) >= nprobes))
725                         break;
726         }
727         exit(0);
728 }
729
730 int
731 wait_for_reply(int sock, struct sockaddr_in *from, struct timeval *sent)
732 {
733         socklen_t fromlen = sizeof (*from);
734         struct timeval now, wait;
735         int cc = 0, fdsn;
736         fd_set *fdsp;
737
738         fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
739         if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
740                 err(1, "malloc");
741         memset(fdsp, 0, fdsn);
742         FD_SET(sock, fdsp);
743         gettimeofday(&now, NULL);
744         wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec;
745         wait.tv_usec =  sent->tv_usec - now.tv_usec;
746         if (wait.tv_usec < 0) {
747                 wait.tv_usec += 1000000;
748                 wait.tv_sec--;
749         }
750         if (wait.tv_sec < 0)
751                 wait.tv_sec = wait.tv_usec = 0;
752
753         if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
754                 cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
755                     (struct sockaddr *)from, &fromlen);
756
757         free(fdsp);
758         return (cc);
759 }
760
761 void
762 decode_extensions(unsigned char *buf, int ip_len)
763 {
764          uint32_t *cmn_hdr;
765          struct icmp_ext_obj_hdr *obj_hdr;
766          uint32_t mpls_hdr;
767          int data_len, obj_len;
768          struct ip *ip;
769
770          ip = (struct ip *)buf;
771
772          if (ip_len <= (int)(sizeof(struct ip) + ICMP_EXT_OFFSET)) {
773                 /*
774                  * No support for ICMP extensions on this host
775                  */
776                 return;
777          }
778
779          /*
780           * Move forward to the start of the ICMP extensions, if present
781           */
782          buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
783          cmn_hdr = (uint32_t *)buf;
784
785          if (EXT_VERSION(ntohl(*cmn_hdr)) != ICMP_EXT_VERSION) {
786                 /*
787                  * Unknown version
788                  */
789                 return;
790          }
791
792          data_len = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
793
794          /*
795           * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
796           * done by sender.
797           *
798           * If the checksum is ok, we'll get 0, as the checksum is calculated
799           * with the checksum field being 0'd.
800           */
801          if (EXT_CHECKSUM(ntohl(*cmn_hdr)) &&
802              in_cksum((u_short *)cmn_hdr, data_len)) {
803                 return;
804          }
805
806          buf += sizeof(*cmn_hdr);
807          data_len -= sizeof(*cmn_hdr);
808
809          while (data_len >= (int)sizeof(struct icmp_ext_obj_hdr)) {
810                 unsigned char *nextbuf;
811
812                 obj_hdr = (struct icmp_ext_obj_hdr *)buf;
813                 obj_len = ntohs(obj_hdr->length);
814
815                 /*
816                  * Sanity check the length field
817                  */
818                 if (obj_len < (int)sizeof(*obj_hdr) || obj_len > data_len)
819                         return;
820
821                 /* Object has to be 4-byte aligned. */
822                 if (obj_len & 3)
823                         return;
824
825                 nextbuf = buf + obj_len;
826                 data_len -= obj_len;
827
828                 /*
829                  * Move past the object header
830                  */
831                 buf += sizeof(struct icmp_ext_obj_hdr);
832                 obj_len -= sizeof(struct icmp_ext_obj_hdr);
833
834                 switch (obj_hdr->class_num) {
835                 case MPLS_STACK_ENTRY_CLASS:
836                         switch (obj_hdr->c_type) {
837                         case MPLS_STACK_ENTRY_C_TYPE:
838                                 while (obj_len >= (int)sizeof(uint32_t)) {
839                                         mpls_hdr = ntohl(*(uint32_t *)buf);
840
841                                         buf += sizeof(uint32_t);
842                                         obj_len -= sizeof(uint32_t);
843                                         printf(" [MPLS: Label %d Exp %d]",
844                                             MPLS_LABEL(mpls_hdr),
845                                             MPLS_EXP(mpls_hdr));
846                                 }
847                                 if (obj_len > 0) {
848                                         /*
849                                          * Something went wrong, and we're at
850                                          * a unknown offset into the packet,
851                                          * ditch the rest of it.
852                                          */
853                                         return;
854                                 }
855                                 break;
856                         default:
857                                 /*
858                                  * Unknown object, skip past it
859                                  */
860                                 buf = nextbuf;
861                                 break;
862                         }
863                         break;
864
865                 default:
866                         /*
867                          * Unknown object, skip past it
868                          */
869                         buf = nextbuf;
870                         break;
871                 }
872         }
873 }
874
875 void
876 dump_packet(void)
877 {
878         u_char *p;
879         int i;
880
881         fprintf(stderr, "packet data:");
882         for (p = outpacket, i = 0; i < datalen; i++) {
883                 if ((i % 24) == 0)
884                         fprintf(stderr, "\n ");
885                 fprintf(stderr, " %02x", *p++);
886         }
887         fprintf(stderr, "\n");
888 }
889
890 void
891 send_probe(int seq, u_int8_t ttl, int iflag, struct sockaddr_in *to)
892 {
893         struct ip *ip = (struct ip *)outpacket;
894         u_char *p = (u_char *)(ip + 1);
895         struct udphdr *up = (struct udphdr *)(p + lsrrlen);
896         struct icmp *icmpp = (struct icmp *)(p + lsrrlen);
897         struct packetdata *op;
898         struct timeval tv;
899         int i;
900
901         ip->ip_len = datalen;
902         ip->ip_ttl = ttl;
903         ip->ip_id = htons(ident+seq);
904
905         switch (proto) {
906         case IPPROTO_ICMP:
907                 icmpp->icmp_type = icmp_type;
908                 icmpp->icmp_code = icmp_code;
909                 icmpp->icmp_seq = htons(seq);
910                 icmpp->icmp_id = htons(ident);
911                 op = (struct packetdata *)(icmpp + 1);
912                 break;
913         case IPPROTO_UDP:
914                 up->uh_sport = htons(ident);
915                 if (iflag)
916                         up->uh_dport = htons(port+seq);
917                 else
918                         up->uh_dport = htons(port);
919                 up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
920                     lsrrlen));
921                 up->uh_sum = 0;
922                 op = (struct packetdata *)(up + 1);
923                 break;
924         default:
925                 op = (struct packetdata *)(ip + 1);
926                 break;
927         }
928         op->seq = seq;
929         op->ttl = ttl;
930
931         /*
932          * We don't want hostiles snooping the net to get any useful
933          * information about us. Send the timestamp in network byte order,
934          * and perturb the timestamp enough that they won't know our
935          * real clock ticker. We don't want to perturb the time by too
936          * much: being off by a suspiciously large amount might indicate
937          * OpenBSD.
938          *
939          * The timestamps in the packet are currently unused. If future
940          * work wants to use them they will have to subtract out the
941          * perturbation first.
942          */
943         gettimeofday(&tv, NULL);
944         op->sec = htonl(tv.tv_sec + sec_perturb);
945         op->usec = htonl((tv.tv_usec + usec_perturb) % 1000000);
946
947         if (proto == IPPROTO_ICMP && icmp_type == ICMP_ECHO) {
948                 icmpp->icmp_cksum = 0;
949                 icmpp->icmp_cksum = in_cksum((u_short *)icmpp,
950                     datalen - sizeof(struct ip) - lsrrlen);
951                 if (icmpp->icmp_cksum == 0)
952                         icmpp->icmp_cksum = 0xffff;
953         }
954
955         if (dump)
956                 dump_packet();
957
958         i = sendto(sndsock, outpacket, datalen, 0, (struct sockaddr *)to,
959             sizeof(struct sockaddr_in));
960         if (i < 0 || i != datalen)  {
961                 if (i < 0)
962                         perror("sendto");
963                 printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
964                     datalen, i);
965                 fflush(stdout);
966         }
967 }
968
969 static const char *ttab[] = {
970         "Echo Reply",
971         "ICMP 1",
972         "ICMP 2",
973         "Dest Unreachable",
974         "Source Quench",
975         "Redirect",
976         "ICMP 6",
977         "ICMP 7",
978         "Echo",
979         "Router Advert",
980         "Router Solicit",
981         "Time Exceeded",
982         "Param Problem",
983         "Timestamp",
984         "Timestamp Reply",
985         "Info Request",
986         "Info Reply",
987         "Mask Request",
988         "Mask Reply"
989 };
990
991 /*
992  * Convert an ICMP "type" field to a printable string.
993  */
994 const char *
995 pr_type(u_int8_t t)
996 {
997         if (t > 18)
998                 return ("OUT-OF-RANGE");
999         return (ttab[t]);
1000 }
1001
1002 int
1003 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq, int iflag)
1004 {
1005         struct icmp *icp;
1006         u_char code;
1007         u_int8_t type;
1008         int hlen;
1009 #ifndef ARCHAIC
1010         struct ip *ip;
1011
1012         ip = (struct ip *) buf;
1013         hlen = ip->ip_hl << 2;
1014         if (cc < hlen + ICMP_MINLEN) {
1015                 if (verbose)
1016                         printf("packet too short (%d bytes) from %s\n", cc,
1017                             inet_ntoa(from->sin_addr));
1018                 return (0);
1019         }
1020         cc -= hlen;
1021         icp = (struct icmp *)(buf + hlen);
1022 #else
1023         icp = (struct icmp *)buf;
1024 #endif /* ARCHAIC */
1025         type = icp->icmp_type;
1026         code = icp->icmp_code;
1027         if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1028             type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1029                 struct ip *hip;
1030                 struct udphdr *up;
1031                 struct icmp *icmpp;
1032
1033                 hip = &icp->icmp_ip;
1034                 hlen = hip->ip_hl << 2;
1035
1036                 switch (proto) {
1037                 case IPPROTO_ICMP:
1038                         if (icmp_type == ICMP_ECHO &&
1039                             type == ICMP_ECHOREPLY &&
1040                             icp->icmp_id == htons(ident) &&
1041                             icp->icmp_seq == htons(seq))
1042                                 return (-2); /* we got there */
1043
1044                         icmpp = (struct icmp *)((u_char *)hip + hlen);
1045                         if (hlen + 8 <= cc && hip->ip_p == IPPROTO_ICMP &&
1046                             icmpp->icmp_id == htons(ident) &&
1047                             icmpp->icmp_seq == htons(seq))
1048                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
1049                         break;
1050
1051                 case IPPROTO_UDP:
1052                         up = (struct udphdr *)((u_char *)hip + hlen);
1053                         if (hlen + 12 <= cc && hip->ip_p == proto &&
1054                             up->uh_sport == htons(ident) &&
1055                             ((iflag && up->uh_dport == htons(port + seq)) ||
1056                             (!iflag && up->uh_dport == htons(port))))
1057                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
1058                         break;
1059                 default:
1060                         /* this is some odd, user specified proto,
1061                          * how do we check it?
1062                          */
1063                         if (hip->ip_p == proto)
1064                                 return (type == ICMP_TIMXCEED? -1 : code + 1);
1065                 }
1066         }
1067 #ifndef ARCHAIC
1068         if (verbose) {
1069                 int i;
1070                 in_addr_t *lp = (in_addr_t *)&icp->icmp_ip;
1071
1072                 printf("\n%d bytes from %s", cc, inet_ntoa(from->sin_addr));
1073                 printf(" to %s", inet_ntoa(ip->ip_dst));
1074                 printf(": icmp type %u (%s) code %d\n", type, pr_type(type),
1075                     icp->icmp_code);
1076                 for (i = 4; i < cc ; i += sizeof(in_addr_t))
1077                         printf("%2d: x%8.8lx\n", i, (unsigned long)*lp++);
1078         }
1079 #endif /* ARCHAIC */
1080         return (0);
1081 }
1082
1083 void
1084 print(u_char *buf, int cc, struct sockaddr_in *from)
1085 {
1086         struct ip *ip;
1087         int hlen;
1088
1089         ip = (struct ip *) buf;
1090         hlen = ip->ip_hl << 2;
1091         cc -= hlen;
1092
1093         if (nflag)
1094                 printf(" %s", inet_ntoa(from->sin_addr));
1095         else
1096                 printf(" %s (%s)", inetname(from->sin_addr),
1097                     inet_ntoa(from->sin_addr));
1098
1099         if (verbose)
1100                 printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1101 }
1102
1103
1104 /*
1105  * Checksum routine for Internet Protocol family headers (C Version)
1106  */
1107 u_short
1108 in_cksum(u_short *addr, int len)
1109 {
1110         u_short *w = addr, answer;
1111         int nleft = len, sum = 0;
1112
1113         /*
1114          *  Our algorithm is simple, using a 32 bit accumulator (sum),
1115          *  we add sequential 16 bit words to it, and at the end, fold
1116          *  back all the carry bits from the top 16 bits into the lower
1117          *  16 bits.
1118          */
1119         while (nleft > 1)  {
1120                 sum += *w++;
1121                 nleft -= 2;
1122         }
1123
1124         /* mop up an odd byte, if necessary */
1125         if (nleft == 1)
1126                 sum += *(u_char *)w;
1127
1128         /*
1129          * add back carry outs from top 16 bits to low 16 bits
1130          */
1131         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
1132         sum += (sum >> 16);                     /* add carry */
1133         answer = ~sum;                          /* truncate to 16 bits */
1134         return (answer);
1135 }
1136
1137 /*
1138  * Construct an Internet address representation.
1139  * If the nflag has been supplied, give
1140  * numeric value, otherwise try for symbolic name.
1141  */
1142 char *
1143 inetname(struct in_addr in)
1144 {
1145         static char domain[MAXHOSTNAMELEN], line[MAXHOSTNAMELEN];
1146         static int first = 1;
1147         struct hostent *hp;
1148         char *cp;
1149
1150         if (first && !nflag) {
1151                 first = 0;
1152                 if (gethostname(domain, sizeof domain) == 0 &&
1153                     (cp = strchr(domain, '.')) != NULL) {
1154                         strlcpy(domain, cp + 1, sizeof(domain));
1155                 }
1156         }
1157         if (!nflag && in.s_addr != INADDR_ANY) {
1158                 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1159                 if (hp != NULL) {
1160                         if ((cp = strchr(hp->h_name, '.')) != NULL &&
1161                             strcmp(cp + 1, domain) == 0)
1162                                 *cp = '\0';
1163                         strlcpy(line, hp->h_name, sizeof(line));
1164                         return (line);
1165                 }
1166         }
1167         return (inet_ntoa(in));
1168 }
1169
1170 void
1171 usage(void)
1172 {
1173         fprintf(stderr,
1174             "usage: %s [-cdDIlMnrSv] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
1175             "\t[-p port] [-P proto] [-q nqueries] [-s src_addr] [-t tos]\n"
1176             "\t[-w waittime] host [packetsize]\n", getprogname());
1177         exit(1);
1178 }