Home | History | Annotate | Line # | Download | only in traceroute
traceroute.c revision 1.78
      1 /*	$NetBSD: traceroute.c,v 1.78 2011/05/12 01:59:16 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that: (1) source code distributions
      9  * retain the above copyright notice and this paragraph in its entirety, (2)
     10  * distributions including binary code include the above copyright notice and
     11  * this paragraph in its entirety in the documentation or other materials
     12  * provided with the distribution, and (3) all advertising materials mentioning
     13  * features or use of this software display the following acknowledgement:
     14  * ``This product includes software developed by the University of California,
     15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
     16  * the University nor the names of its contributors may be used to endorse
     17  * or promote products derived from this software without specific prior
     18  * written permission.
     19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
     20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
     21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     22  */
     23 
     24 #include <sys/cdefs.h>
     25 #ifndef lint
     26 #if 0
     27 static const char rcsid[] =
     28     "@(#)Header: traceroute.c,v 1.49 97/06/13 02:30:23 leres Exp  (LBL)";
     29 #else
     30 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997\
     31  The Regents of the University of California.  All rights reserved.");
     32 __RCSID("$NetBSD: traceroute.c,v 1.78 2011/05/12 01:59:16 christos Exp $");
     33 #endif
     34 #endif
     35 
     36 /*
     37  * traceroute host  - trace the route ip packets follow going to "host".
     38  *
     39  * Attempt to trace the route an ip packet would follow to some
     40  * internet host.  We find out intermediate hops by launching probe
     41  * packets with a small ttl (time to live) then listening for an
     42  * icmp "time exceeded" reply from a gateway.  We start our probes
     43  * with a ttl of one and increase by one until we get an icmp "port
     44  * unreachable" (which means we got to "host") or hit a max (which
     45  * defaults to 30 hops & can be changed with the -m flag).  Three
     46  * probes (change with -q flag) are sent at each ttl setting and a
     47  * line is printed showing the ttl, address of the gateway and
     48  * round trip time of each probe.  If the probe answers come from
     49  * different gateways, the address of each responding system will
     50  * be printed.  If there is no response within a 5 sec. timeout
     51  * interval (changed with the -w flag), a "*" is printed for that
     52  * probe.
     53  *
     54  * Probe packets are UDP format.  We don't want the destination
     55  * host to process them so the destination port is set to an
     56  * unlikely value (if some clod on the destination is using that
     57  * value, it can be changed with the -p flag).
     58  *
     59  * A sample use might be:
     60  *
     61  *     [yak 71]% traceroute nis.nsf.net.
     62  *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
     63  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
     64  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
     65  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
     66  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
     67  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
     68  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
     69  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
     70  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
     71  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
     72  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
     73  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
     74  *
     75  * Note that lines 2 & 3 are the same.  This is due to a buggy
     76  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
     77  * packets with a zero ttl.
     78  *
     79  * A more interesting example is:
     80  *
     81  *     [yak 72]% traceroute allspice.lcs.mit.edu.
     82  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
     83  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
     84  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
     85  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
     86  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
     87  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
     88  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
     89  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
     90  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
     91  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
     92  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
     93  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
     94  *     12  * * *
     95  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
     96  *     14  * * *
     97  *     15  * * *
     98  *     16  * * *
     99  *     17  * * *
    100  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
    101  *
    102  * (I start to see why I'm having so much trouble with mail to
    103  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
    104  * either don't send ICMP "time exceeded" messages or send them
    105  * with a ttl too small to reach us.  14 - 17 are running the
    106  * MIT C Gateway code that doesn't send "time exceeded"s.  God
    107  * only knows what's going on with 12.
    108  *
    109  * The silent gateway 12 in the above may be the result of a bug in
    110  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
    111  * sends an unreachable message using whatever ttl remains in the
    112  * original datagram.  Since, for gateways, the remaining ttl is
    113  * zero, the icmp "time exceeded" is guaranteed to not make it back
    114  * to us.  The behavior of this bug is slightly more interesting
    115  * when it appears on the destination system:
    116  *
    117  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
    118  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
    119  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
    120  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
    121  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
    122  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
    123  *      7  * * *
    124  *      8  * * *
    125  *      9  * * *
    126  *     10  * * *
    127  *     11  * * *
    128  *     12  * * *
    129  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
    130  *
    131  * Notice that there are 12 "gateways" (13 is the final
    132  * destination) and exactly the last half of them are "missing".
    133  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
    134  * is using the ttl from our arriving datagram as the ttl in its
    135  * icmp reply.  So, the reply will time out on the return path
    136  * (with no notice sent to anyone since icmp's aren't sent for
    137  * icmp's) until we probe with a ttl that's at least twice the path
    138  * length.  I.e., rip is really only 7 hops away.  A reply that
    139  * returns with a ttl of 1 is a clue this problem exists.
    140  * Traceroute prints a "!" after the time if the ttl is <= 1.
    141  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
    142  * non-standard (HPUX) software, expect to see this problem
    143  * frequently and/or take care picking the target host of your
    144  * probes.
    145  *
    146  * Other possible annotations after the time are !H, !N, !P (got a host,
    147  * network or protocol unreachable, respectively), !S or !F (source
    148  * route failed or fragmentation needed -- neither of these should
    149  * ever occur and the associated gateway is busted if you see one).  If
    150  * almost all the probes result in some kind of unreachable, traceroute
    151  * will give up and exit.
    152  *
    153  * Notes
    154  * -----
    155  * This program must be run by root or be setuid.  (I suggest that
    156  * you *don't* make it setuid -- casual use could result in a lot
    157  * of unnecessary traffic on our poor, congested nets.)
    158  *
    159  * This program requires a kernel mod that does not appear in any
    160  * system available from Berkeley:  A raw ip socket using proto
    161  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
    162  * opposed to data to be wrapped in a ip datagram).  See the README
    163  * file that came with the source to this program for a description
    164  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
    165  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
    166  * MODIFIED TO RUN THIS PROGRAM.
    167  *
    168  * The udp port usage may appear bizarre (well, ok, it is bizarre).
    169  * The problem is that an icmp message only contains 8 bytes of
    170  * data from the original datagram.  8 bytes is the size of a udp
    171  * header so, if we want to associate replies with the original
    172  * datagram, the necessary information must be encoded into the
    173  * udp header (the ip id could be used but there's no way to
    174  * interlock with the kernel's assignment of ip id's and, anyway,
    175  * it would have taken a lot more kernel hacking to allow this
    176  * code to set the ip id).  So, to allow two or more users to
    177  * use traceroute simultaneously, we use this task's pid as the
    178  * source port (the high bit is set to move the port number out
    179  * of the "likely" range).  To keep track of which probe is being
    180  * replied to (so times and/or hop counts don't get confused by a
    181  * reply that was delayed in transit), we increment the destination
    182  * port number before each probe.
    183  *
    184  * Don't use this as a coding example.  I was trying to find a
    185  * routing problem and this code sort-of popped out after 48 hours
    186  * without sleep.  I was amazed it ever compiled, much less ran.
    187  *
    188  * I stole the idea for this program from Steve Deering.  Since
    189  * the first release, I've learned that had I attended the right
    190  * IETF working group meetings, I also could have stolen it from Guy
    191  * Almes or Matt Mathis.  I don't know (or care) who came up with
    192  * the idea first.  I envy the originators' perspicacity and I'm
    193  * glad they didn't keep the idea a secret.
    194  *
    195  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
    196  * enhancements to the original distribution.
    197  *
    198  * I've hacked up a round-trip-route version of this that works by
    199  * sending a loose-source-routed udp datagram through the destination
    200  * back to yourself.  Unfortunately, SO many gateways botch source
    201  * routing, the thing is almost worthless.  Maybe one day...
    202  *
    203  *  -- Van Jacobson (van (at) ee.lbl.gov)
    204  *     Tue Dec 20 03:50:13 PST 1988
    205  */
    206 
    207 #include <sys/param.h>
    208 #include <sys/file.h>
    209 #include <sys/ioctl.h>
    210 #include <sys/socket.h>
    211 #include <sys/time.h>
    212 #include <sys/sysctl.h>
    213 
    214 #include <netinet/in_systm.h>
    215 #include <netinet/in.h>
    216 #include <netinet/ip.h>
    217 #include <netinet/ip_var.h>
    218 #include <netinet/ip_icmp.h>
    219 #include <netinet/udp.h>
    220 #include <netinet/udp_var.h>
    221 
    222 #include <arpa/inet.h>
    223 
    224 #include <ctype.h>
    225 #include <err.h>
    226 #include <errno.h>
    227 #ifdef HAVE_MALLOC_H
    228 #include <malloc.h>
    229 #endif
    230 #include <memory.h>
    231 #include <netdb.h>
    232 #include <stdio.h>
    233 #include <stdlib.h>
    234 #include <string.h>
    235 #include <unistd.h>
    236 #include <poll.h>
    237 #ifdef IPSEC
    238 #include <net/route.h>
    239 #include <netinet6/ipsec.h>
    240 #endif
    241 
    242 #include "gnuc.h"
    243 #ifdef HAVE_OS_PROTO_H
    244 #include "os-proto.h"
    245 #endif
    246 
    247 #include "ifaddrlist.h"
    248 #include "as.h"
    249 #include "prog_ops.h"
    250 
    251 /* Maximum number of gateways (include room for one noop) */
    252 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
    253 
    254 #ifndef MAXHOSTNAMELEN
    255 #define MAXHOSTNAMELEN	64
    256 #endif
    257 
    258 #define Fprintf (void)fprintf
    259 #define Printf (void)printf
    260 
    261 /* Host name and address list */
    262 struct hostinfo {
    263 	char *name;
    264 	int n;
    265 	u_int32_t *addrs;
    266 };
    267 
    268 /* Data section of the probe packet */
    269 struct outdata {
    270 	u_char seq;		/* sequence number of this packet */
    271 	u_char ttl;		/* ttl packet left with */
    272 	struct tv32 {
    273 		int32_t tv32_sec;
    274 		int32_t tv32_usec;
    275 	} tv;			/* time packet left */
    276 };
    277 
    278 /*
    279  * Support for ICMP extensions
    280  *
    281  * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
    282  */
    283 #define ICMP_EXT_OFFSET    8 /* ICMP type, code, checksum, unused */ + \
    284                          128 /* original datagram */
    285 #define ICMP_EXT_VERSION 2
    286 /*
    287  * ICMP extensions, common header
    288  */
    289 struct icmp_ext_cmn_hdr {
    290 #if BYTE_ORDER == BIG_ENDIAN
    291 	unsigned char   version:4;
    292 	unsigned char   reserved1:4;
    293 #else
    294 	unsigned char   reserved1:4;
    295 	unsigned char   version:4;
    296 #endif
    297 	unsigned char   reserved2;
    298 	unsigned short  checksum;
    299 };
    300 
    301 /*
    302  * ICMP extensions, object header
    303  */
    304 struct icmp_ext_obj_hdr {
    305     u_short length;
    306     u_char  class_num;
    307 #define MPLS_STACK_ENTRY_CLASS 1
    308     u_char  c_type;
    309 #define MPLS_STACK_ENTRY_C_TYPE 1
    310 };
    311 
    312 struct mpls_header {
    313 #if BYTE_ORDER == BIG_ENDIAN
    314 	 uint32_t	label:20;
    315 	 unsigned char  exp:3;
    316 	 unsigned char  s:1;
    317 	 unsigned char  ttl:8;
    318 #else
    319 	 unsigned char  ttl:8;
    320 	 unsigned char  s:1;
    321 	 unsigned char  exp:3;
    322 	 uint32_t	label:20;
    323 #endif
    324 };
    325 
    326 static u_char	packet[512];		/* last inbound (icmp) packet */
    327 
    328 static struct ip *outip;		/* last output (udp) packet */
    329 static struct udphdr *outudp;		/* last output (udp) packet */
    330 static void *outmark;			/* packed location of struct outdata */
    331 static struct outdata outsetup;	/* setup and copy for alignment */
    332 
    333 static struct icmp *outicmp;		/* last output (icmp) packet */
    334 
    335 /* loose source route gateway list (including room for final destination) */
    336 static u_int32_t gwlist[NGATEWAYS + 1];
    337 
    338 static int s;				/* receive (icmp) socket file descriptor */
    339 static int sndsock;			/* send (udp/icmp) socket file descriptor */
    340 
    341 static struct sockaddr whereto;	/* Who to try to reach */
    342 static struct sockaddr_in wherefrom;	/* Who we are */
    343 static int packlen;			/* total length of packet */
    344 static int minpacket;			/* min ip packet size */
    345 static int maxpacket = 32 * 1024;	/* max ip packet size */
    346 static int printed_ttl = 0;
    347 
    348 static const char *prog;
    349 static char *source;
    350 static char *hostname;
    351 static char *device;
    352 
    353 static int nprobes = 3;
    354 static int max_ttl = 30;
    355 static int first_ttl = 1;
    356 static u_int16_t ident;
    357 static in_port_t port = 32768 + 666;	/* start udp dest port # for probe packets */
    358 
    359 static int options;			/* socket options */
    360 static int verbose;
    361 static int waittime = 5;		/* time to wait for response (in seconds) */
    362 static int nflag;			/* print addresses numerically */
    363 static int dump;
    364 static int Mflag;			/* show MPLS labels if any */
    365 static int as_path;			/* print as numbers for each hop */
    366 static char *as_server = NULL;
    367 static void *asn;
    368 static int useicmp = 0;		/* use icmp echo instead of udp packets */
    369 #ifdef CANT_HACK_CKSUM
    370 static int docksum = 0;		/* don't calculate checksums */
    371 #else
    372 static int docksum = 1;		/* calculate checksums */
    373 #endif
    374 static int optlen;			/* length of ip options */
    375 
    376 static int mtus[] = {
    377         17914,
    378          8166,
    379          4464,
    380          4352,
    381          2048,
    382          2002,
    383          1536,
    384          1500,
    385          1492,
    386 	 1480,
    387 	 1280,
    388          1006,
    389           576,
    390           552,
    391           544,
    392           512,
    393           508,
    394           296,
    395            68,
    396             0
    397 };
    398 static int *mtuptr = &mtus[0];
    399 static int mtudisc = 0;
    400 static int nextmtu;   /* from ICMP error, set by packet_ok(), might be 0 */
    401 
    402 /* Forwards */
    403 static double deltaT(struct timeval *, struct timeval *);
    404 static void freehostinfo(struct hostinfo *);
    405 static void getaddr(u_int32_t *, char *);
    406 static struct hostinfo *gethostinfo(char *);
    407 static u_int16_t in_cksum(u_int16_t *, int);
    408 static u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
    409 static char *inetname(struct in_addr);
    410 static int packet_ok(u_char *, ssize_t, struct sockaddr_in *, int);
    411 static const char *pr_type(u_char);
    412 static void print(u_char *, int, struct sockaddr_in *);
    413 static void resize_packet(void);
    414 static void dump_packet(void);
    415 static void send_probe(int, int, struct timeval *);
    416 static void setsin(struct sockaddr_in *, u_int32_t);
    417 static int str2val(const char *, const char *, int, int);
    418 static void tvsub(struct timeval *, struct timeval *);
    419 static void usage(void) __attribute__((__noreturn__));
    420 static ssize_t wait_for_reply(int, struct sockaddr_in *, struct timeval *);
    421 static void decode_extensions(unsigned char *buf, int ip_len);
    422 static void frag_err(void);
    423 static int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
    424 #ifdef IPSEC
    425 #ifdef IPSEC_POLICY_IPSEC
    426 static int setpolicy(int, const char *);
    427 #endif
    428 #endif
    429 
    430 int
    431 main(int argc, char **argv)
    432 {
    433 	int op, code, n;
    434 	u_char *outp;
    435 	u_int32_t *ap;
    436 	struct sockaddr_in *from = &wherefrom;
    437 	struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
    438 	struct hostinfo *hi;
    439 	int on = 1;
    440 	int ttl, probe, i;
    441 	int seq = 0;
    442 	int tos = 0, settos = 0, ttl_flag = 0;
    443 	int lsrr = 0;
    444 	u_int16_t off = 0;
    445 	struct ifaddrlist *al, *al2;
    446 	char errbuf[132];
    447 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
    448 	size_t size = sizeof(max_ttl);
    449 
    450 	setprogname(argv[0]);
    451 	prog = getprogname();
    452 
    453 	if (prog_init && prog_init() == -1)
    454 		err(1, "init failed");
    455 
    456 	if ((s = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
    457 		err(1, "icmp socket");
    458 
    459 	/*
    460 	 * XXX 'useicmp' will always be zero here. I think the HP-UX users
    461 	 * running our traceroute code will forgive us.
    462 	 */
    463 #ifndef __hpux
    464 	sndsock = prog_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    465 #else
    466 	sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
    467 	    useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
    468 #endif
    469 	if (sndsock < 0)
    470 		err(1, "raw socket");
    471 
    472 	/* Revert to non-privileged user after opening sockets */
    473 	setuid(getuid());
    474 
    475 	(void) prog_sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
    476 	    NULL, 0);
    477 
    478 	opterr = 0;
    479 	while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
    480 		switch (op) {
    481 
    482 		case 'a':
    483 			as_path = 1;
    484 			break;
    485 
    486 		case 'A':
    487 			as_path = 1;
    488 			as_server = optarg;
    489 			break;
    490 
    491 		case 'd':
    492 			options |= SO_DEBUG;
    493 			break;
    494 
    495 		case 'D':
    496 			dump = 1;
    497 			break;
    498 
    499 		case 'f':
    500 			first_ttl = str2val(optarg, "first ttl", 1, 255);
    501 			break;
    502 
    503 		case 'F':
    504 			off = IP_DF;
    505 			break;
    506 
    507 		case 'g':
    508 			if (lsrr >= NGATEWAYS)
    509 				errx(1, "more than %d gateways", NGATEWAYS);
    510 			getaddr(gwlist + lsrr, optarg);
    511 			++lsrr;
    512 			break;
    513 
    514 		case 'i':
    515 			device = optarg;
    516 			break;
    517 
    518 		case 'I':
    519 			++useicmp;
    520 			break;
    521 
    522 		case 'l':
    523 			++ttl_flag;
    524 			break;
    525 
    526 		case 'm':
    527 			max_ttl = str2val(optarg, "max ttl", 1, 255);
    528 			break;
    529 
    530 		case 'M':
    531 			Mflag = 1;
    532 			break;
    533 
    534 		case 'n':
    535 			++nflag;
    536 			break;
    537 
    538 		case 'p':
    539 			port = str2val(optarg, "port", 1, -1);
    540 			break;
    541 
    542 		case 'q':
    543 			nprobes = str2val(optarg, "nprobes", 1, -1);
    544 			break;
    545 
    546 		case 'r':
    547 			options |= SO_DONTROUTE;
    548 			break;
    549 
    550 		case 's':
    551 			/*
    552 			 * set the ip source address of the outbound
    553 			 * probe (e.g., on a multi-homed host).
    554 			 */
    555 			source = optarg;
    556 			break;
    557 
    558 		case 't':
    559 			tos = str2val(optarg, "tos", 0, 255);
    560 			++settos;
    561 			break;
    562 
    563 		case 'v':
    564 			++verbose;
    565 			break;
    566 
    567 		case 'x':
    568 			docksum = (docksum == 0);
    569 			break;
    570 
    571 		case 'w':
    572 			waittime = str2val(optarg, "wait time", 2, 24 * 3600);
    573 			break;
    574 
    575 		case 'P':
    576 			off = IP_DF;
    577 			mtudisc = 1;
    578 			break;
    579 
    580 		default:
    581 			usage();
    582 		}
    583 
    584 	if (first_ttl > max_ttl)
    585 		errx(1, "first ttl (%d) may not be greater than max ttl (%d)",
    586 		    first_ttl, max_ttl);
    587 
    588 	if (!docksum)
    589 		warnx("ckecksums disabled");
    590 
    591 	if (lsrr > 0)
    592 		optlen = (lsrr + 1) * sizeof(gwlist[0]);
    593 	minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
    594 	if (useicmp)
    595 		minpacket += 8;			/* XXX magic number */
    596 	else
    597 		minpacket += sizeof(*outudp);
    598 	if (packlen == 0)
    599 		packlen = minpacket;		/* minimum sized packet */
    600 	else if (minpacket > packlen || packlen > maxpacket)
    601 		errx(1, "packet size must be %d <= s <= %d",
    602 		    minpacket, maxpacket);
    603 
    604 	if (mtudisc)
    605 		packlen = *mtuptr++;
    606 
    607 	/* Process destination and optional packet size */
    608 	switch (argc - optind) {
    609 
    610 	case 2:
    611 		packlen = str2val(argv[optind + 1],
    612 		    "packet length", minpacket, -1);
    613 		/* Fall through */
    614 
    615 	case 1:
    616 		hostname = argv[optind];
    617 		hi = gethostinfo(hostname);
    618 		setsin(to, hi->addrs[0]);
    619 		if (hi->n > 1)
    620 			warnx("%s has multiple addresses; using %s",
    621 			    hostname, inet_ntoa(to->sin_addr));
    622 		hostname = hi->name;
    623 		hi->name = NULL;
    624 		freehostinfo(hi);
    625 		break;
    626 
    627 	default:
    628 		usage();
    629 	}
    630 
    631 #ifdef HAVE_SETLINEBUF
    632 	setlinebuf (stdout);
    633 #else
    634 	setvbuf(stdout, NULL, _IOLBF, 0);
    635 #endif
    636 
    637 	outip = malloc((unsigned)packlen);
    638 	if (outip == NULL)
    639 		err(1, "malloc");
    640 	memset(outip, 0, packlen);
    641 
    642 	outip->ip_v = IPVERSION;
    643 	if (settos)
    644 		outip->ip_tos = tos;
    645 #ifdef BYTESWAP_IP_LEN
    646 	outip->ip_len = htons(packlen);
    647 #else
    648 	outip->ip_len = packlen;
    649 #endif
    650 	outip->ip_off = off;
    651 	outp = (u_char *)(outip + 1);
    652 #ifdef HAVE_RAW_OPTIONS
    653 	if (lsrr > 0) {
    654 		u_char *optlist;
    655 
    656 		optlist = outp;
    657 		outp += optlen;
    658 
    659 		/* final hop */
    660 		gwlist[lsrr] = to->sin_addr.s_addr;
    661 
    662 		outip->ip_dst.s_addr = gwlist[0];
    663 
    664 		/* force 4 byte alignment */
    665 		optlist[0] = IPOPT_NOP;
    666 		/* loose source route option */
    667 		optlist[1] = IPOPT_LSRR;
    668 		i = lsrr * sizeof(gwlist[0]);
    669 		optlist[2] = i + 3;
    670 		/* Pointer to LSRR addresses */
    671 		optlist[3] = IPOPT_MINOFF;
    672 		memcpy(optlist + 4, gwlist + 1, i);
    673 	} else
    674 #endif
    675 		outip->ip_dst = to->sin_addr;
    676 
    677 	outip->ip_hl = (outp - (u_char *)outip) >> 2;
    678 	ident = htons(arc4random() & 0xffff) | 0x8000;
    679 	if (useicmp) {
    680 		outip->ip_p = IPPROTO_ICMP;
    681 
    682 		outicmp = (struct icmp *)outp;
    683 		outicmp->icmp_type = ICMP_ECHO;
    684 		outicmp->icmp_id = htons(ident);
    685 
    686 		outmark = outp + 8;	/* XXX magic number */
    687 	} else {
    688 		outip->ip_p = IPPROTO_UDP;
    689 
    690 		outudp = (struct udphdr *)outp;
    691 		outudp->uh_sport = htons(ident);
    692 		outudp->uh_ulen =
    693 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
    694 		outmark = outudp + 1;
    695 	}
    696 
    697 	if (options & SO_DEBUG)
    698 		(void)prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
    699 		    sizeof(on));
    700 #ifdef IPSEC
    701 #ifdef IPSEC_POLICY_IPSEC
    702 	/*
    703 	 * do not raise error even if setsockopt fails, kernel may have ipsec
    704 	 * turned off.
    705 	 */
    706 	if (setpolicy(s, "in bypass") < 0)
    707 		exit(1);
    708 	if (setpolicy(s, "out bypass") < 0)
    709 		exit(1);
    710 #else
    711     {
    712 	int level = IPSEC_LEVEL_AVAIL;
    713 
    714 	(void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
    715 		sizeof(level));
    716 	(void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
    717 		sizeof(level));
    718 #ifdef IP_AUTH_TRANS_LEVEL
    719 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
    720 		sizeof(level));
    721 #else
    722 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
    723 		sizeof(level));
    724 #endif
    725 #ifdef IP_AUTH_NETWORK_LEVEL
    726 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
    727 		sizeof(level));
    728 #endif
    729     }
    730 #endif /*IPSEC_POLICY_IPSEC*/
    731 #endif /*IPSEC*/
    732 
    733 #ifdef IPSEC
    734 #ifdef IPSEC_POLICY_IPSEC
    735 	/*
    736 	 * do not raise error even if setsockopt fails, kernel may have ipsec
    737 	 * turned off.
    738 	 */
    739 	if (setpolicy(sndsock, "in bypass") < 0)
    740 		exit(1);
    741 	if (setpolicy(sndsock, "out bypass") < 0)
    742 		exit(1);
    743 #else
    744     {
    745 	int level = IPSEC_LEVEL_BYPASS;
    746 
    747 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
    748 		sizeof(level));
    749 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
    750 		sizeof(level));
    751 #ifdef IP_AUTH_TRANS_LEVEL
    752 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
    753 		sizeof(level));
    754 #else
    755 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
    756 		sizeof(level));
    757 #endif
    758 #ifdef IP_AUTH_NETWORK_LEVEL
    759 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
    760 		sizeof(level));
    761 #endif
    762     }
    763 #endif /*IPSEC_POLICY_IPSEC*/
    764 #endif /*IPSEC*/
    765 
    766 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
    767 	if (lsrr > 0) {
    768 		u_char optlist[MAX_IPOPTLEN];
    769 
    770 		/* final hop */
    771 		gwlist[lsrr] = to->sin_addr.s_addr;
    772 		++lsrr;
    773 
    774 		/* force 4 byte alignment */
    775 		optlist[0] = IPOPT_NOP;
    776 		/* loose source route option */
    777 		optlist[1] = IPOPT_LSRR;
    778 		i = lsrr * sizeof(gwlist[0]);
    779 		optlist[2] = i + 3;
    780 		/* Pointer to LSRR addresses */
    781 		optlist[3] = IPOPT_MINOFF;
    782 		memcpy(optlist + 4, gwlist, i);
    783 
    784 		if ((prog_setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
    785 		    i + sizeof(gwlist[0]))) < 0)
    786 			err(1, "IP_OPTIONS");
    787 	}
    788 #endif
    789 
    790 #ifdef SO_SNDBUF
    791 	if (prog_setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
    792 	    sizeof(packlen)) < 0)
    793 		err(1, "SO_SNDBUF");
    794 #endif
    795 #ifdef IP_HDRINCL
    796 	if (prog_setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
    797 	    sizeof(on)) < 0)
    798 		err(1, "IP_HDRINCL");
    799 #else
    800 #ifdef IP_TOS
    801 	if (settos && prog_setsockopt(sndsock, IPPROTO_IP, IP_TOS,
    802 	    &tos, sizeof(tos)) < 0)
    803 		err(1, "setsockopt tos %d", tos);
    804 #endif
    805 #endif
    806 	if (options & SO_DEBUG)
    807 		if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, &on,
    808 		    sizeof(on)) < 0)
    809 			err(1, "setsockopt debug %d", tos);
    810 	if (options & SO_DONTROUTE)
    811 		if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, &on,
    812 		    sizeof(on)) < 0)
    813 			err(1, "setsockopt dontroute %d", tos);
    814 
    815 	/* Get the interface address list */
    816 	n = ifaddrlist(&al, errbuf, sizeof errbuf);
    817 	al2 = al;
    818 	if (n < 0)
    819 		errx(1, "ifaddrlist (%s)", errbuf);
    820 	if (n == 0)
    821 		errx(1, "Can't find any network interfaces");
    822 
    823 	/* Look for a specific device */
    824 	if (device != NULL) {
    825 		for (i = n; i > 0; --i, ++al2)
    826 			if (strcmp(device, al2->device) == 0)
    827 				break;
    828 		if (i <= 0)
    829 			errx(1, "Can't find interface %s", device);
    830 	}
    831 
    832 	/* Determine our source address */
    833 	if (source == NULL) {
    834 		/*
    835 		 * If a device was specified, use the interface address.
    836 		 * Otherwise, use the first interface found.
    837 		 * Warn if there are more than one.
    838 		 */
    839 		setsin(from, al2->addr);
    840 		if (n > 1 && device == NULL && !find_local_ip(from, to)) {
    841 			warnx("Multiple interfaces found; using %s @ %s",
    842 			    inet_ntoa(from->sin_addr), al2->device);
    843 		}
    844 	} else {
    845 		hi = gethostinfo(source);
    846 		source = hi->name;
    847 		hi->name = NULL;
    848 		if (device == NULL) {
    849 			/*
    850 			 * Use the first interface found.
    851 			 * Warn if there are more than one.
    852 			 */
    853 			setsin(from, hi->addrs[0]);
    854 			if (hi->n > 1)
    855 				warnx("%s has multiple addresses; using %s",
    856 				    source, inet_ntoa(from->sin_addr));
    857 		} else {
    858 			/*
    859 			 * Make sure the source specified matches the
    860 			 * interface address.
    861 			 */
    862 			for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
    863 				if (*ap == al2->addr)
    864 					break;
    865 			if (i <= 0)
    866 				errx(1, "%s is not on interface %s",
    867 				    source, device);
    868 			setsin(from, *ap);
    869 		}
    870 		freehostinfo(hi);
    871 	}
    872 
    873 	/*
    874 	 * If not root, make sure source address matches a local interface.
    875 	 * (The list of addresses produced by ifaddrlist() automatically
    876 	 * excludes interfaces that are marked down and/or loopback.)
    877 	 */
    878 	if (getuid())  {
    879 		al2 = al;
    880 		for (i = n; i > 0; --i, ++al2)
    881 			if (from->sin_addr.s_addr == al2->addr)
    882 			    break;
    883 		if (i <= 0)
    884 			errx(1, "%s is not a valid local address "
    885 			    "and you are not superuser.",
    886 			    inet_ntoa(from->sin_addr));
    887 	}
    888 
    889 	outip->ip_src = from->sin_addr;
    890 #ifndef IP_HDRINCL
    891 	if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0)
    892 		err(1, "bind");
    893 #endif
    894 
    895 	if (as_path) {
    896 		asn = as_setup(as_server);
    897 		if (asn == NULL) {
    898 			warnx("as_setup failed, AS# lookups disabled");
    899 			(void)fflush(stderr);
    900 			as_path = 0;
    901 		}
    902 	}
    903 
    904 	setuid(getuid());
    905 	Fprintf(stderr, "%s to %s (%s)",
    906 	    prog, hostname, inet_ntoa(to->sin_addr));
    907 	if (source)
    908 		Fprintf(stderr, " from %s", source);
    909 	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
    910 	(void)fflush(stderr);
    911 
    912 	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
    913 		u_int32_t lastaddr = 0;
    914 		int got_there = 0;
    915 		int unreachable = 0;
    916 
    917 again:
    918 		printed_ttl = 0;
    919 		for (probe = 0; probe < nprobes; ++probe) {
    920 			int cc;
    921 			struct timeval t1, t2;
    922 			struct ip *ip;
    923 			(void)gettimeofday(&t1, NULL);
    924 			if (!useicmp && htons(port + seq + 1) == 0)
    925 				seq++;
    926 			send_probe(++seq, ttl, &t1);
    927 			while ((cc = wait_for_reply(s, from, &t1)) != 0) {
    928 				(void)gettimeofday(&t2, NULL);
    929 				/*
    930 				 * Since we'll be receiving all ICMP
    931 				 * messages to this host above, we may
    932 				 * never end up with cc=0, so we need
    933 				 * an additional termination check.
    934 				 */
    935 				if (t2.tv_sec - t1.tv_sec > waittime) {
    936 					cc = 0;
    937 					break;
    938 				}
    939 				i = packet_ok(packet, cc, from, seq);
    940 				/* Skip short packet */
    941 				if (i == 0)
    942 					continue;
    943 				if (from->sin_addr.s_addr != lastaddr) {
    944 					print(packet, cc, from);
    945 					lastaddr = from->sin_addr.s_addr;
    946 				}
    947 				ip = (struct ip *)packet;
    948 				Printf("  %.3f ms", deltaT(&t1, &t2));
    949 				if (ttl_flag)
    950 					Printf(" (ttl = %d)", ip->ip_ttl);
    951 				if (i == -2) {
    952 #ifndef ARCHAIC
    953 					if (ip->ip_ttl <= 1)
    954 						Printf(" !");
    955 #endif
    956 					++got_there;
    957 					break;
    958 				}
    959 
    960 				/* time exceeded in transit */
    961 				if (i == -1)
    962 					break;
    963 				code = i - 1;
    964 				switch (code) {
    965 
    966 				case ICMP_UNREACH_PORT:
    967 #ifndef ARCHAIC
    968 					if (ip->ip_ttl <= 1)
    969 						Printf(" !");
    970 #endif
    971 					++got_there;
    972 					break;
    973 
    974 				case ICMP_UNREACH_NET:
    975 					++unreachable;
    976 					Printf(" !N");
    977 					break;
    978 
    979 				case ICMP_UNREACH_HOST:
    980 					++unreachable;
    981 					Printf(" !H");
    982 					break;
    983 
    984 				case ICMP_UNREACH_PROTOCOL:
    985 					++got_there;
    986 					Printf(" !P");
    987 					break;
    988 
    989 				case ICMP_UNREACH_NEEDFRAG:
    990 					if (mtudisc) {
    991 						frag_err();
    992 						goto again;
    993 					} else {
    994 						++unreachable;
    995 						Printf(" !F");
    996 					}
    997 					break;
    998 
    999 				case ICMP_UNREACH_SRCFAIL:
   1000 					++unreachable;
   1001 					Printf(" !S");
   1002 					break;
   1003 
   1004 /* rfc1716 */
   1005 #ifndef ICMP_UNREACH_FILTER_PROHIB
   1006 #define ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohibited filter */
   1007 #endif
   1008 				case ICMP_UNREACH_FILTER_PROHIB:
   1009 					++unreachable;
   1010 					Printf(" !X");
   1011 					break;
   1012 
   1013 				default:
   1014 					++unreachable;
   1015 					Printf(" !<%d>", code);
   1016 					break;
   1017 				}
   1018 				break;
   1019 			}
   1020 			if (cc == 0)
   1021 				Printf(" *");
   1022 			else if (cc && probe == nprobes - 1 && Mflag)
   1023 				decode_extensions(packet, cc);
   1024 			(void)fflush(stdout);
   1025 		}
   1026 		putchar('\n');
   1027 		if (got_there ||
   1028 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
   1029 			break;
   1030 	}
   1031 
   1032 	if (as_path)
   1033 		as_shutdown(asn);
   1034 
   1035 	exit(0);
   1036 }
   1037 
   1038 static ssize_t
   1039 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
   1040 {
   1041 	struct pollfd set[1];
   1042 	struct timeval now, wait;
   1043 	ssize_t cc = 0;
   1044 	socklen_t fromlen = sizeof(*fromp);
   1045 	int retval;
   1046 
   1047 	set[0].fd = sock;
   1048 	set[0].events = POLLIN;
   1049 
   1050 	wait.tv_sec = tp->tv_sec + waittime;
   1051 	wait.tv_usec = tp->tv_usec;
   1052 	(void)gettimeofday(&now, NULL);
   1053 	tvsub(&wait, &now);
   1054 
   1055 	if (wait.tv_sec < 0) {
   1056 		wait.tv_sec = 0;
   1057 		wait.tv_usec = 0;
   1058 	}
   1059 
   1060 	retval = prog_poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
   1061 	if (retval < 0)
   1062 		/* If we continue, we probably just flood the remote host. */
   1063 		err(1, "poll");
   1064 	if (retval > 0)  {
   1065 		cc = prog_recvfrom(s, (char *)packet, sizeof(packet), 0,
   1066 			    (struct sockaddr *)fromp, &fromlen);
   1067 	}
   1068 
   1069 	return cc;
   1070 }
   1071 
   1072 static void
   1073 decode_extensions(unsigned char *buf, int ip_len)
   1074 {
   1075         struct icmp_ext_cmn_hdr *cmn_hdr;
   1076         struct icmp_ext_obj_hdr *obj_hdr;
   1077         union {
   1078                 struct mpls_header mpls;
   1079                 uint32_t mpls_h;
   1080         } mpls;
   1081         size_t datalen, obj_len;
   1082         struct ip *ip;
   1083 
   1084         ip = (struct ip *)buf;
   1085 
   1086         if (ip_len < (int)((ip->ip_hl << 2) + ICMP_EXT_OFFSET +
   1087 	    sizeof(struct icmp_ext_cmn_hdr))) {
   1088 		/*
   1089 		 * No support for ICMP extensions on this host
   1090 		 */
   1091 		return;
   1092         }
   1093 
   1094         /*
   1095          * Move forward to the start of the ICMP extensions, if present
   1096          */
   1097         buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
   1098         cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
   1099 
   1100         if (cmn_hdr->version != ICMP_EXT_VERSION) {
   1101 		/*
   1102 		 * Unknown version
   1103 		 */
   1104 		return;
   1105         }
   1106 
   1107         datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
   1108 
   1109         /*
   1110          * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
   1111          * done by sender.
   1112          *
   1113         * If the checksum is ok, we'll get 0, as the checksum is calculated
   1114          * with the checksum field being 0'd.
   1115          */
   1116         if (ntohs(cmn_hdr->checksum) &&
   1117             in_cksum((u_short *)cmn_hdr, datalen)) {
   1118 
   1119             return;
   1120         }
   1121 
   1122         buf += sizeof(*cmn_hdr);
   1123         datalen -= sizeof(*cmn_hdr);
   1124 
   1125         while (datalen >= sizeof(struct icmp_ext_obj_hdr)) {
   1126 		obj_hdr = (struct icmp_ext_obj_hdr *)buf;
   1127 		obj_len = ntohs(obj_hdr->length);
   1128 
   1129 		/*
   1130 		 * Sanity check the length field
   1131 		 */
   1132 		if (obj_len > datalen)
   1133 			return;
   1134 
   1135 		datalen -= obj_len;
   1136 
   1137 		/*
   1138 		 * Move past the object header
   1139 		 */
   1140 		buf += sizeof(struct icmp_ext_obj_hdr);
   1141 		obj_len -= sizeof(struct icmp_ext_obj_hdr);
   1142 
   1143 		switch (obj_hdr->class_num) {
   1144 		case MPLS_STACK_ENTRY_CLASS:
   1145 			switch (obj_hdr->c_type) {
   1146 			case MPLS_STACK_ENTRY_C_TYPE:
   1147 				while (obj_len >= sizeof(uint32_t)) {
   1148 					mpls.mpls_h = ntohl(*(uint32_t *)buf);
   1149 
   1150 					buf += sizeof(uint32_t);
   1151 					obj_len -= sizeof(uint32_t);
   1152 
   1153 					printf(" [MPLS: Label %d Exp %d]",
   1154 					    mpls.mpls.label, mpls.mpls.exp);
   1155 				}
   1156 				if (obj_len > 0) {
   1157 					/*
   1158 					 * Something went wrong, and we're at
   1159 					 * a unknown offset into the packet,
   1160 					 * ditch the rest of it.
   1161 					 */
   1162 					return;
   1163 				}
   1164 				break;
   1165 			default:
   1166 				/*
   1167 				 * Unknown object, skip past it
   1168 				 */
   1169 				buf += ntohs(obj_hdr->length) -
   1170 				    sizeof(struct icmp_ext_obj_hdr);
   1171 				break;
   1172 			}
   1173 			break;
   1174 
   1175 		default:
   1176 			/*
   1177 			 * Unknown object, skip past it
   1178 			 */
   1179 			buf += ntohs(obj_hdr->length) -
   1180 			    sizeof(struct icmp_ext_obj_hdr);
   1181 			break;
   1182 		}
   1183 	}
   1184 }
   1185 
   1186 static void
   1187 dump_packet(void)
   1188 {
   1189 	u_char *p;
   1190 	int i;
   1191 
   1192 	Fprintf(stderr, "packet data:");
   1193 
   1194 #ifdef __hpux
   1195 	for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
   1196 	    i < packlen - (sizeof(*outip) + optlen); i++)
   1197 #else
   1198 	for (p = (u_char *)outip, i = 0; i < packlen; i++)
   1199 #endif
   1200 	{
   1201 		if ((i % 24) == 0)
   1202 			Fprintf(stderr, "\n ");
   1203 		Fprintf(stderr, " %02x", *p++);
   1204 	}
   1205 	Fprintf(stderr, "\n");
   1206 }
   1207 
   1208 void
   1209 send_probe(int seq, int ttl, struct timeval *tp)
   1210 {
   1211 	int cc;
   1212 	struct udpiphdr * ui;
   1213 	int oldmtu = packlen;
   1214 
   1215 again:
   1216 #ifdef BYTESWAP_IP_LEN
   1217 	outip->ip_len = htons(packlen);
   1218 #else
   1219 	outip->ip_len = packlen;
   1220 #endif
   1221 	outip->ip_ttl = ttl;
   1222 #ifndef __hpux
   1223 	outip->ip_id = htons(ident + seq);
   1224 #endif
   1225 
   1226 	/*
   1227 	 * In most cases, the kernel will recalculate the ip checksum.
   1228 	 * But we must do it anyway so that the udp checksum comes out
   1229 	 * right.
   1230 	 */
   1231 	if (docksum) {
   1232 		outip->ip_sum =
   1233 		    in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
   1234 		if (outip->ip_sum == 0)
   1235 			outip->ip_sum = 0xffff;
   1236 	}
   1237 
   1238 	/* Payload */
   1239 	outsetup.seq = seq;
   1240 	outsetup.ttl = ttl;
   1241 	outsetup.tv.tv32_sec = htonl(tp->tv_sec);
   1242 	outsetup.tv.tv32_usec = htonl(tp->tv_usec);
   1243 	memcpy(outmark,&outsetup,sizeof(outsetup));
   1244 
   1245 	if (useicmp)
   1246 		outicmp->icmp_seq = htons(seq);
   1247 	else
   1248 		outudp->uh_dport = htons(port + seq);
   1249 
   1250 	/* (We can only do the checksum if we know our ip address) */
   1251 	if (docksum) {
   1252 		if (useicmp) {
   1253 			outicmp->icmp_cksum = 0;
   1254 			outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
   1255 			    packlen - (sizeof(*outip) + optlen));
   1256 			if (outicmp->icmp_cksum == 0)
   1257 				outicmp->icmp_cksum = 0xffff;
   1258 		} else {
   1259 			u_int16_t sum;
   1260 			struct {
   1261 				struct in_addr src;
   1262 				struct in_addr dst;
   1263 				u_int8_t zero;
   1264 				u_int8_t protocol;
   1265 				u_int16_t len;
   1266 			} __packed phdr;
   1267 
   1268 			/* Checksum */
   1269 			ui = (struct udpiphdr *)outip;
   1270 			memset(&phdr, 0, sizeof(phdr));
   1271 			phdr.src = ui->ui_src;
   1272 			phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
   1273 			phdr.protocol = ui->ui_pr;
   1274 			phdr.len = outudp->uh_ulen;
   1275 			outudp->uh_sum = 0;
   1276 			sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
   1277 			sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
   1278 			outudp->uh_sum = ~sum;
   1279 			if (outudp->uh_sum == 0)
   1280 				outudp->uh_sum = 0xffff;
   1281 		}
   1282 	}
   1283 
   1284 	/* XXX undocumented debugging hack */
   1285 	if (verbose > 1) {
   1286 		const u_int16_t *sp;
   1287 		int nshorts, i;
   1288 
   1289 		sp = (u_int16_t *)outip;
   1290 		nshorts = (u_int)packlen / sizeof(u_int16_t);
   1291 		i = 0;
   1292 		Printf("[ %d bytes", packlen);
   1293 		while (--nshorts >= 0) {
   1294 			if ((i++ % 8) == 0)
   1295 				Printf("\n\t");
   1296 			Printf(" %04x", ntohs(*sp++));
   1297 		}
   1298 		if (packlen & 1) {
   1299 			if ((i % 8) == 0)
   1300 				Printf("\n\t");
   1301 			Printf(" %02x", *(const u_char *)sp);
   1302 		}
   1303 		Printf("]\n");
   1304 	}
   1305 
   1306 #if !defined(IP_HDRINCL) && defined(IP_TTL)
   1307 	if (prog_setsockopt(sndsock, IPPROTO_IP, IP_TTL,
   1308 	    (char *)&ttl, sizeof(ttl)) < 0)
   1309 		err(1, "setsockopt ttl %d", ttl);
   1310 #endif
   1311 	if (dump)
   1312 		dump_packet();
   1313 
   1314 #ifdef __hpux
   1315 	cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
   1316 	    packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
   1317 	if (cc > 0)
   1318 		cc += sizeof(*outip) + optlen;
   1319 #else
   1320 	cc = prog_sendto(sndsock, (char *)outip,
   1321 	    packlen, 0, &whereto, sizeof(whereto));
   1322 #endif
   1323 	if (cc < 0 || cc != packlen)  {
   1324 		if (cc < 0) {
   1325 			/*
   1326 			 * An errno of EMSGSIZE means we're writing too big a
   1327 			 * datagram for the interface.  We have to just
   1328 			 * decrease the packet size until we find one that
   1329 			 * works.
   1330 			 *
   1331 			 * XXX maybe we should try to read the outgoing if's
   1332 			 * mtu?
   1333 			 */
   1334 			if (errno == EMSGSIZE) {
   1335 				packlen = *mtuptr++;
   1336 				resize_packet();
   1337 				goto again;
   1338 			} else
   1339 				warn("sendto");
   1340 		}
   1341 
   1342 		Printf("%s: wrote %s %d chars, ret=%d\n",
   1343 		    prog, hostname, packlen, cc);
   1344 		(void)fflush(stdout);
   1345 	}
   1346 	if (oldmtu != packlen) {
   1347 		Printf("message too big, "
   1348 		    "trying new MTU = %d\n", packlen);
   1349 		printed_ttl = 0;
   1350 	}
   1351 	if (!printed_ttl) {
   1352 		Printf("%2d ", ttl);
   1353 		printed_ttl = 1;
   1354 	}
   1355 
   1356 }
   1357 
   1358 static double
   1359 deltaT(struct timeval *t1p, struct timeval *t2p)
   1360 {
   1361 	double dt;
   1362 
   1363 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
   1364 	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
   1365 	return dt;
   1366 }
   1367 
   1368 /*
   1369  * Convert an ICMP "type" field to a printable string.
   1370  */
   1371 static const char *
   1372 pr_type(u_char t)
   1373 {
   1374 	static const char *ttab[] = {
   1375 	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
   1376 	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
   1377 	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
   1378 	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
   1379 	"Info Reply"
   1380 	};
   1381 
   1382 	if (t > 16)
   1383 		return "OUT-OF-RANGE";
   1384 
   1385 	return ttab[t];
   1386 }
   1387 
   1388 static int
   1389 packet_ok(u_char *buf, ssize_t cc, struct sockaddr_in *from, int seq)
   1390 {
   1391 	struct icmp *icp;
   1392 	u_char type, code;
   1393 	int hlen;
   1394 #ifndef ARCHAIC
   1395 	struct ip *ip;
   1396 
   1397 	ip = (struct ip *) buf;
   1398 	hlen = ip->ip_hl << 2;
   1399 	if (cc < hlen + ICMP_MINLEN) {
   1400 		if (verbose)
   1401 			Printf("packet too short (%zd bytes) from %s\n", cc,
   1402 				inet_ntoa(from->sin_addr));
   1403 		return 0;
   1404 	}
   1405 	cc -= hlen;
   1406 	icp = (struct icmp *)(buf + hlen);
   1407 #else
   1408 	icp = (struct icmp *)buf;
   1409 #endif
   1410 	type = icp->icmp_type;
   1411 	code = icp->icmp_code;
   1412 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
   1413 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
   1414 		struct ip *hip;
   1415 		struct udphdr *up;
   1416 		struct icmp *hicmp;
   1417 
   1418 		hip = &icp->icmp_ip;
   1419 		hlen = hip->ip_hl << 2;
   1420 
   1421 		nextmtu = ntohs(icp->icmp_nextmtu);	/* for frag_err() */
   1422 
   1423 		if (useicmp) {
   1424 			/* XXX */
   1425 			if (type == ICMP_ECHOREPLY &&
   1426 			    icp->icmp_id == htons(ident) &&
   1427 			    icp->icmp_seq == htons(seq))
   1428 				return -2;
   1429 
   1430 			hicmp = (struct icmp *)((u_char *)hip + hlen);
   1431 			/* XXX 8 is a magic number */
   1432 			if (hlen + 8 <= cc &&
   1433 			    hip->ip_p == IPPROTO_ICMP &&
   1434 			    hicmp->icmp_id == htons(ident) &&
   1435 			    hicmp->icmp_seq == htons(seq))
   1436 				return type == ICMP_TIMXCEED ? -1 : code + 1;
   1437 		} else {
   1438 			up = (struct udphdr *)((u_char *)hip + hlen);
   1439 			/* XXX 8 is a magic number */
   1440 			if (hlen + 12 <= cc &&
   1441 			    hip->ip_p == IPPROTO_UDP &&
   1442 			    up->uh_sport == htons(ident) &&
   1443 			    up->uh_dport == htons(port + seq))
   1444 				return type == ICMP_TIMXCEED ? -1 : code + 1;
   1445 		}
   1446 	}
   1447 #ifndef ARCHAIC
   1448 	if (verbose) {
   1449 		int i;
   1450 		u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
   1451 
   1452 		Printf("\n%zd bytes from %s to ", cc, inet_ntoa(from->sin_addr));
   1453 		Printf("%s: icmp type %d (%s) code %d\n",
   1454 		    inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
   1455 		for (i = 4; i < cc ; i += sizeof(*lp))
   1456 			Printf("%2d: x%8.8x\n", i, *lp++);
   1457 	}
   1458 #endif
   1459 	return(0);
   1460 }
   1461 
   1462 static void
   1463 resize_packet(void)
   1464 {
   1465 	if (useicmp) {
   1466 		outicmp->icmp_cksum = 0;
   1467 		outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
   1468 		    packlen - (sizeof(*outip) + optlen));
   1469 		if (outicmp->icmp_cksum == 0)
   1470 			outicmp->icmp_cksum = 0xffff;
   1471 	} else {
   1472 		outudp->uh_ulen =
   1473 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
   1474 	}
   1475 }
   1476 
   1477 static void
   1478 print(u_char *buf, int cc, struct sockaddr_in *from)
   1479 {
   1480 	struct ip *ip;
   1481 	int hlen;
   1482 	char addr[INET_ADDRSTRLEN];
   1483 
   1484 	ip = (struct ip *) buf;
   1485 	hlen = ip->ip_hl << 2;
   1486 	cc -= hlen;
   1487 
   1488 	strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
   1489 
   1490 	if (as_path)
   1491 		Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
   1492 
   1493 	if (nflag)
   1494 		Printf(" %s", addr);
   1495 	else
   1496 		Printf(" %s (%s)", inetname(from->sin_addr), addr);
   1497 
   1498 	if (verbose)
   1499 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
   1500 }
   1501 
   1502 static u_int16_t
   1503 in_cksum(u_int16_t *addr, int len)
   1504 {
   1505 
   1506 	return ~in_cksum2(0, addr, len);
   1507 }
   1508 
   1509 /*
   1510  * Checksum routine for Internet Protocol family headers (C Version)
   1511  */
   1512 static u_int16_t
   1513 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
   1514 {
   1515 	int nleft = len;
   1516 	u_int16_t *w = addr;
   1517 	union {
   1518 		u_int16_t w;
   1519 		u_int8_t b[2];
   1520 	} answer;
   1521 	int32_t sum = seed;
   1522 
   1523 	/*
   1524 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
   1525 	 *  we add sequential 16 bit words to it, and at the end, fold
   1526 	 *  back all the carry bits from the top 16 bits into the lower
   1527 	 *  16 bits.
   1528 	 */
   1529 	while (nleft > 1)  {
   1530 		sum += *w++;
   1531 		nleft -= 2;
   1532 	}
   1533 
   1534 	/* mop up an odd byte, if necessary */
   1535 	if (nleft == 1) {
   1536 		answer.b[0] = *(u_char *)w;
   1537 		answer.b[1] = 0;
   1538 		sum += answer.w;
   1539 	}
   1540 
   1541 	/*
   1542 	 * add back carry outs from top 16 bits to low 16 bits
   1543 	 */
   1544 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
   1545 	sum += (sum >> 16);			/* add carry */
   1546 	answer.w = sum;				/* truncate to 16 bits */
   1547 	return answer.w;
   1548 }
   1549 
   1550 /*
   1551  * Subtract 2 timeval structs:  out = out - in.
   1552  * Out is assumed to be >= in.
   1553  */
   1554 static void
   1555 tvsub(struct timeval *out, struct timeval *in)
   1556 {
   1557 
   1558 	if ((out->tv_usec -= in->tv_usec) < 0)   {
   1559 		--out->tv_sec;
   1560 		out->tv_usec += 1000000;
   1561 	}
   1562 	out->tv_sec -= in->tv_sec;
   1563 }
   1564 
   1565 /*
   1566  * Construct an Internet address representation.
   1567  * If the nflag has been supplied, give
   1568  * numeric value, otherwise try for symbolic name.
   1569  */
   1570 static char *
   1571 inetname(struct in_addr in)
   1572 {
   1573 	char *cp;
   1574 	struct hostent *hp;
   1575 	static int first = 1;
   1576 	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
   1577 
   1578 	if (first && !nflag) {
   1579 		int rv;
   1580 
   1581 		first = 0;
   1582 		rv = gethostname(domain, sizeof domain);
   1583 		if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
   1584 			(void)strlcpy(domain, cp + 1, sizeof(domain));
   1585 		} else
   1586 			domain[0] = '\0';
   1587 	}
   1588 	if (!nflag && in.s_addr != INADDR_ANY) {
   1589 		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
   1590 		if (hp != NULL) {
   1591 			if ((cp = strchr(hp->h_name, '.')) != NULL &&
   1592 			    strcmp(cp + 1, domain) == 0)
   1593 				*cp = '\0';
   1594 			(void)strlcpy(line, hp->h_name, sizeof(line));
   1595 			return line;
   1596 		}
   1597 	}
   1598 	return inet_ntoa(in);
   1599 }
   1600 
   1601 static struct hostinfo *
   1602 gethostinfo(char *hname)
   1603 {
   1604 	int n;
   1605 	struct hostent *hp;
   1606 	struct hostinfo *hi;
   1607 	char **p;
   1608 	u_int32_t *ap;
   1609 	struct in_addr addr;
   1610 
   1611 	hi = calloc(1, sizeof(*hi));
   1612 	if (hi == NULL)
   1613 		err(1, "calloc");
   1614 	if (inet_aton(hname, &addr) != 0) {
   1615 		hi->name = strdup(hname);
   1616 		if (!hi->name)
   1617 			err(1, "strdup");
   1618 		hi->n = 1;
   1619 		hi->addrs = calloc(1, sizeof(hi->addrs[0]));
   1620 		if (hi->addrs == NULL)
   1621 			err(1, "calloc");
   1622 		hi->addrs[0] = addr.s_addr;
   1623 		return hi;
   1624 	}
   1625 
   1626 	hp = gethostbyname(hname);
   1627 	if (hp == NULL)
   1628 		errx(1, "unknown host %s", hname);
   1629 	if (hp->h_addrtype != AF_INET || hp->h_length != 4)
   1630 		errx(1, "bad host %s", hname);
   1631 	hi->name = strdup(hp->h_name);
   1632 	if (!hi->name)
   1633 		err(1, "strdup");
   1634 	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
   1635 		continue;
   1636 	hi->n = n;
   1637 	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
   1638 	if (hi->addrs == NULL)
   1639 		err(1, "calloc");
   1640 	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
   1641 		memcpy(ap, *p, sizeof(*ap));
   1642 	return hi;
   1643 }
   1644 
   1645 static void
   1646 freehostinfo(struct hostinfo *hi)
   1647 {
   1648 	if (hi->name != NULL) {
   1649 		free(hi->name);
   1650 		hi->name = NULL;
   1651 	}
   1652 	free(hi->addrs);
   1653 	free(hi);
   1654 }
   1655 
   1656 static void
   1657 getaddr(u_int32_t *ap, char *hname)
   1658 {
   1659 	struct hostinfo *hi;
   1660 
   1661 	hi = gethostinfo(hname);
   1662 	*ap = hi->addrs[0];
   1663 	freehostinfo(hi);
   1664 }
   1665 
   1666 static void
   1667 setsin(struct sockaddr_in *sin, u_int32_t addr)
   1668 {
   1669 
   1670 	memset(sin, 0, sizeof(*sin));
   1671 #ifdef HAVE_SOCKADDR_SA_LEN
   1672 	sin->sin_len = sizeof(*sin);
   1673 #endif
   1674 	sin->sin_family = AF_INET;
   1675 	sin->sin_addr.s_addr = addr;
   1676 }
   1677 
   1678 /* String to value with optional min and max. Handles decimal and hex. */
   1679 static int
   1680 str2val(const char *str, const char *what, int mi, int ma)
   1681 {
   1682 	const char *cp;
   1683 	long val;
   1684 	char *ep;
   1685 
   1686 	errno = 0;
   1687 	ep = NULL;
   1688 	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
   1689 		cp = str + 2;
   1690 		val = strtol(cp, &ep, 16);
   1691 	} else
   1692 		val = strtol(str, &ep, 10);
   1693 	if (errno || str[0] == '\0' || *ep != '\0')
   1694 		errx(1, "\"%s\" bad value for %s", str, what);
   1695 	if (val < mi && mi >= 0) {
   1696 		if (mi == 0)
   1697 			errx(1, "%s must be >= %d", what, mi);
   1698 		else
   1699 			errx(1, "%s must be > %d", what, mi - 1);
   1700 	}
   1701 	if (val > ma && ma >= 0)
   1702 		errx(1, "%s must be <= %d", what, ma);
   1703 	return (int)val;
   1704 }
   1705 
   1706 __dead void
   1707 usage(void)
   1708 {
   1709 	extern char version[];
   1710 
   1711 	Fprintf(stderr, "Version %s\n", version);
   1712 	Fprintf(stderr, "Usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
   1713 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
   1714 [-w waittime] [-A as_server] host [packetlen]\n",
   1715 	    getprogname());
   1716 	exit(1);
   1717 }
   1718 
   1719 /*
   1720  * Received ICMP unreachable (fragmentation required and DF set).
   1721  * If the ICMP error was from a "new" router, it'll contain the next-hop
   1722  * MTU that we should use next.  Otherwise we'll just keep going in the
   1723  * mtus[] table, trying until we hit a valid MTU.
   1724  */
   1725 
   1726 
   1727 void
   1728 frag_err()
   1729 {
   1730         int i;
   1731 
   1732         if (nextmtu > 0 && nextmtu < packlen) {
   1733                 Printf("\nfragmentation required and DF set, "
   1734 		     "next hop MTU = %d\n",
   1735                         nextmtu);
   1736                 packlen = nextmtu;
   1737                 for (i = 0; mtus[i] > 0; i++) {
   1738                         if (mtus[i] < nextmtu) {
   1739                                 mtuptr = &mtus[i];    /* next one to try */
   1740                                 break;
   1741                         }
   1742                 }
   1743         } else {
   1744                 Printf("\nfragmentation required and DF set. ");
   1745 		if (nextmtu)
   1746 			Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
   1747 			    nextmtu, packlen);
   1748                 packlen = *mtuptr++;
   1749 		Printf("Trying new MTU = %d\n", packlen);
   1750         }
   1751 	resize_packet();
   1752 }
   1753 
   1754 int
   1755 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
   1756 {
   1757 	int sock;
   1758 	struct sockaddr_in help;
   1759 	socklen_t help_len;
   1760 
   1761 	sock = prog_socket(AF_INET, SOCK_DGRAM, 0);
   1762 	if (sock < 0) return 0;
   1763 
   1764 	help.sin_family = AF_INET;
   1765 	/*
   1766 	 * At this point the port number doesn't matter
   1767 	 * since it only has to be greater than zero.
   1768 	 */
   1769 	help.sin_port = 42;
   1770 	help.sin_addr.s_addr = to->sin_addr.s_addr;
   1771 	if (prog_connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
   1772 		(void)prog_close(sock);
   1773 		return 0;
   1774 	}
   1775 
   1776 	help_len = sizeof(help);
   1777 	if (prog_getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
   1778 	    help_len != sizeof(help) ||
   1779 	    help.sin_addr.s_addr == INADDR_ANY) {
   1780 		(void)prog_close(sock);
   1781 		return 0;
   1782 	}
   1783 
   1784 	(void)prog_close(sock);
   1785 	setsin(from, help.sin_addr.s_addr);
   1786 	return 1;
   1787 }
   1788 
   1789 #ifdef IPSEC
   1790 #ifdef IPSEC_POLICY_IPSEC
   1791 static int
   1792 setpolicy(int so, const char *policy)
   1793 {
   1794 	char *buf;
   1795 
   1796 	buf = ipsec_set_policy(policy, strlen(policy));
   1797 	if (buf == NULL) {
   1798 		warnx("%s", ipsec_strerror());
   1799 		return -1;
   1800 	}
   1801 	(void)prog_setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
   1802 		buf, ipsec_get_policylen(buf));
   1803 
   1804 	free(buf);
   1805 
   1806 	return 0;
   1807 }
   1808 #endif
   1809 #endif
   1810 
   1811