Home | History | Annotate | Line # | Download | only in traceroute
traceroute.c revision 1.69.4.2
      1 /*	traceroute.c,v 1.69.4.1 2008/01/09 02:02:35 matt 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\n\
     31 The Regents of the University of California.  All rights reserved.\n");
     32 __RCSID("traceroute.c,v 1.69.4.1 2008/01/09 02:02:35 matt 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 <errno.h>
    226 #ifdef HAVE_MALLOC_H
    227 #include <malloc.h>
    228 #endif
    229 #include <memory.h>
    230 #include <netdb.h>
    231 #include <stdio.h>
    232 #include <stdlib.h>
    233 #include <string.h>
    234 #include <unistd.h>
    235 #include <poll.h>
    236 #ifdef IPSEC
    237 #include <net/route.h>
    238 #include <netinet6/ipsec.h>
    239 #endif
    240 
    241 #include "gnuc.h"
    242 #ifdef HAVE_OS_PROTO_H
    243 #include "os-proto.h"
    244 #endif
    245 
    246 #include "ifaddrlist.h"
    247 #include "as.h"
    248 
    249 /* Maximum number of gateways (include room for one noop) */
    250 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
    251 
    252 #ifndef MAXHOSTNAMELEN
    253 #define MAXHOSTNAMELEN	64
    254 #endif
    255 
    256 #define Fprintf (void)fprintf
    257 #define Printf (void)printf
    258 
    259 /* Host name and address list */
    260 struct hostinfo {
    261 	char *name;
    262 	int n;
    263 	u_int32_t *addrs;
    264 };
    265 
    266 /* Data section of the probe packet */
    267 struct outdata {
    268 	u_char seq;		/* sequence number of this packet */
    269 	u_char ttl;		/* ttl packet left with */
    270 	struct timeval tv;	/* time packet left */
    271 };
    272 
    273 /*
    274  * Support for ICMP extensions
    275  *
    276  * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
    277  */
    278 #define ICMP_EXT_OFFSET    8 /* ICMP type, code, checksum, unused */ + \
    279                          128 /* original datagram */
    280 #define ICMP_EXT_VERSION 2
    281 /*
    282  * ICMP extensions, common header
    283  */
    284 struct icmp_ext_cmn_hdr {
    285 #if BYTE_ORDER == BIG_ENDIAN
    286 	unsigned char   version:4;
    287 	unsigned char   reserved1:4;
    288 #else
    289 	unsigned char   reserved1:4;
    290 	unsigned char   version:4;
    291 #endif
    292 	unsigned char   reserved2;
    293 	unsigned short  checksum;
    294 };
    295 
    296 /*
    297  * ICMP extensions, object header
    298  */
    299 struct icmp_ext_obj_hdr {
    300     u_short length;
    301     u_char  class_num;
    302 #define MPLS_STACK_ENTRY_CLASS 1
    303     u_char  c_type;
    304 #define MPLS_STACK_ENTRY_C_TYPE 1
    305 };
    306 
    307 struct mpls_header {
    308 #if BYTE_ORDER == BIG_ENDIAN
    309 	 uint32_t	label:20;
    310 	 unsigned char  exp:3;
    311 	 unsigned char  s:1;
    312 	 unsigned char  ttl:8;
    313 #else
    314 	 unsigned char  ttl:8;
    315 	 unsigned char  s:1;
    316 	 unsigned char  exp:3;
    317 	 uint32_t	label:20;
    318 #endif
    319 };
    320 
    321 u_char	packet[512];		/* last inbound (icmp) packet */
    322 
    323 struct ip *outip;		/* last output (udp) packet */
    324 struct udphdr *outudp;		/* last output (udp) packet */
    325 void *outmark;			/* packed location of struct outdata */
    326 struct outdata outsetup;	/* setup and copy for alignment */
    327 
    328 struct icmp *outicmp;		/* last output (icmp) packet */
    329 
    330 /* loose source route gateway list (including room for final destination) */
    331 u_int32_t gwlist[NGATEWAYS + 1];
    332 
    333 int s;				/* receive (icmp) socket file descriptor */
    334 int sndsock;			/* send (udp/icmp) socket file descriptor */
    335 
    336 struct sockaddr whereto;	/* Who to try to reach */
    337 struct sockaddr_in wherefrom;	/* Who we are */
    338 int packlen;			/* total length of packet */
    339 int minpacket;			/* min ip packet size */
    340 int maxpacket = 32 * 1024;	/* max ip packet size */
    341 int printed_ttl = 0;
    342 
    343 const char *prog;
    344 char *source;
    345 char *hostname;
    346 char *device;
    347 
    348 int nprobes = 3;
    349 int max_ttl = 30;
    350 int first_ttl = 1;
    351 u_int16_t ident;
    352 in_port_t port = 32768 + 666;	/* start udp dest port # for probe packets */
    353 
    354 int options;			/* socket options */
    355 int verbose;
    356 int waittime = 5;		/* time to wait for response (in seconds) */
    357 int nflag;			/* print addresses numerically */
    358 int dump;
    359 int Mflag;			/* show MPLS labels if any */
    360 int as_path;			/* print as numbers for each hop */
    361 char *as_server = NULL;
    362 void *asn;
    363 int useicmp = 0;		/* use icmp echo instead of udp packets */
    364 #ifdef CANT_HACK_CKSUM
    365 int docksum = 0;		/* don't calculate checksums */
    366 #else
    367 int docksum = 1;		/* calculate checksums */
    368 #endif
    369 int optlen;			/* length of ip options */
    370 
    371 int mtus[] = {
    372         17914,
    373          8166,
    374          4464,
    375          4352,
    376          2048,
    377          2002,
    378          1536,
    379          1500,
    380          1492,
    381 	 1480,
    382 	 1280,
    383          1006,
    384           576,
    385           552,
    386           544,
    387           512,
    388           508,
    389           296,
    390            68,
    391             0
    392 };
    393 int *mtuptr = &mtus[0];
    394 int mtudisc = 0;
    395 int nextmtu;   /* from ICMP error, set by packet_ok(), might be 0 */
    396 
    397 extern int optind;
    398 extern int opterr;
    399 extern char *optarg;
    400 
    401 /* Forwards */
    402 double	deltaT(struct timeval *, struct timeval *);
    403 void	freehostinfo(struct hostinfo *);
    404 void	getaddr(u_int32_t *, char *);
    405 struct	hostinfo *gethostinfo(char *);
    406 u_int16_t in_cksum(u_int16_t *, int);
    407 u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
    408 char	*inetname(struct in_addr);
    409 int	main(int, char **);
    410 int	packet_ok(u_char *, int, struct sockaddr_in *, int);
    411 char	*pr_type(u_char);
    412 void	print(u_char *, int, struct sockaddr_in *);
    413 void	resize_packet(void);
    414 void	dump_packet(void);
    415 void	send_probe(int, int, struct timeval *);
    416 void	setsin(struct sockaddr_in *, u_int32_t);
    417 int	str2val(const char *, const char *, int, int);
    418 void	tvsub(struct timeval *, struct timeval *);
    419 __dead	void usage(void);
    420 int	wait_for_reply(int, struct sockaddr_in *, struct timeval *);
    421 void	decode_extensions(unsigned char *buf, int ip_len);
    422 void	frag_err(void);
    423 int	find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
    424 #ifdef IPSEC
    425 #ifdef IPSEC_POLICY_IPSEC
    426 int	setpolicy(int so, char *policy);
    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 ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
    454 		Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
    455 		exit(1);
    456 	}
    457 
    458 	/*
    459 	 * XXX 'useicmp' will always be zero here. I think the HP-UX users
    460 	 * running our traceroute code will forgive us.
    461 	 */
    462 #ifndef __hpux
    463 	sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    464 #else
    465 	sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
    466 	    useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
    467 #endif
    468 	if (sndsock < 0) {
    469 		Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
    470 		exit(1);
    471 	}
    472 
    473 	/* Revert to non-privileged user after opening sockets */
    474 	setuid(getuid());
    475 
    476 	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
    477 	    NULL, 0);
    478 
    479 	opterr = 0;
    480 	while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
    481 		switch (op) {
    482 
    483 		case 'a':
    484 			as_path = 1;
    485 			break;
    486 
    487 		case 'A':
    488 			as_path = 1;
    489 			as_server = optarg;
    490 			break;
    491 
    492 		case 'd':
    493 			options |= SO_DEBUG;
    494 			break;
    495 
    496 		case 'D':
    497 			dump = 1;
    498 			break;
    499 
    500 		case 'f':
    501 			first_ttl = str2val(optarg, "first ttl", 1, 255);
    502 			break;
    503 
    504 		case 'F':
    505 			off = IP_DF;
    506 			break;
    507 
    508 		case 'g':
    509 			if (lsrr >= NGATEWAYS) {
    510 				Fprintf(stderr,
    511 				    "%s: No more than %d gateways\n",
    512 				    prog, NGATEWAYS);
    513 				exit(1);
    514 			}
    515 			getaddr(gwlist + lsrr, optarg);
    516 			++lsrr;
    517 			break;
    518 
    519 		case 'i':
    520 			device = optarg;
    521 			break;
    522 
    523 		case 'I':
    524 			++useicmp;
    525 			break;
    526 
    527 		case 'l':
    528 			++ttl_flag;
    529 			break;
    530 
    531 		case 'm':
    532 			max_ttl = str2val(optarg, "max ttl", 1, 255);
    533 			break;
    534 
    535 		case 'M':
    536 			Mflag = 1;
    537 			break;
    538 
    539 		case 'n':
    540 			++nflag;
    541 			break;
    542 
    543 		case 'p':
    544 			port = str2val(optarg, "port", 1, -1);
    545 			break;
    546 
    547 		case 'q':
    548 			nprobes = str2val(optarg, "nprobes", 1, -1);
    549 			break;
    550 
    551 		case 'r':
    552 			options |= SO_DONTROUTE;
    553 			break;
    554 
    555 		case 's':
    556 			/*
    557 			 * set the ip source address of the outbound
    558 			 * probe (e.g., on a multi-homed host).
    559 			 */
    560 			source = optarg;
    561 			break;
    562 
    563 		case 't':
    564 			tos = str2val(optarg, "tos", 0, 255);
    565 			++settos;
    566 			break;
    567 
    568 		case 'v':
    569 			++verbose;
    570 			break;
    571 
    572 		case 'x':
    573 			docksum = (docksum == 0);
    574 			break;
    575 
    576 		case 'w':
    577 			waittime = str2val(optarg, "wait time", 2, 24 * 3600);
    578 			break;
    579 
    580 		case 'P':
    581 			off = IP_DF;
    582 			mtudisc = 1;
    583 			break;
    584 
    585 		default:
    586 			usage();
    587 		}
    588 
    589 	if (first_ttl > max_ttl) {
    590 		Fprintf(stderr,
    591 		    "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
    592 		    prog, first_ttl, max_ttl);
    593 		exit(1);
    594 	}
    595 
    596 	if (!docksum)
    597 		Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog);
    598 
    599 	if (lsrr > 0)
    600 		optlen = (lsrr + 1) * sizeof(gwlist[0]);
    601 	minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
    602 	if (useicmp)
    603 		minpacket += 8;			/* XXX magic number */
    604 	else
    605 		minpacket += sizeof(*outudp);
    606 	if (packlen == 0)
    607 		packlen = minpacket;		/* minimum sized packet */
    608 	else if (minpacket > packlen || packlen > maxpacket) {
    609 		Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
    610 		    prog, minpacket, maxpacket);
    611 		exit(1);
    612 	}
    613 
    614 	if (mtudisc)
    615 		packlen = *mtuptr++;
    616 
    617 	/* Process destination and optional packet size */
    618 	switch (argc - optind) {
    619 
    620 	case 2:
    621 		packlen = str2val(argv[optind + 1],
    622 		    "packet length", minpacket, -1);
    623 		/* Fall through */
    624 
    625 	case 1:
    626 		hostname = argv[optind];
    627 		hi = gethostinfo(hostname);
    628 		setsin(to, hi->addrs[0]);
    629 		if (hi->n > 1)
    630 			Fprintf(stderr,
    631 		    "%s: Warning: %s has multiple addresses; using %s\n",
    632 				prog, hostname, inet_ntoa(to->sin_addr));
    633 		hostname = hi->name;
    634 		hi->name = NULL;
    635 		freehostinfo(hi);
    636 		break;
    637 
    638 	default:
    639 		usage();
    640 	}
    641 
    642 #ifdef HAVE_SETLINEBUF
    643 	setlinebuf (stdout);
    644 #else
    645 	setvbuf(stdout, NULL, _IOLBF, 0);
    646 #endif
    647 
    648 	outip = (struct ip *)malloc((unsigned)packlen);
    649 	if (outip == NULL) {
    650 		Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
    651 		exit(1);
    652 	}
    653 	memset((char *)outip, 0, packlen);
    654 
    655 	outip->ip_v = IPVERSION;
    656 	if (settos)
    657 		outip->ip_tos = tos;
    658 #ifdef BYTESWAP_IP_LEN
    659 	outip->ip_len = htons(packlen);
    660 #else
    661 	outip->ip_len = packlen;
    662 #endif
    663 	outip->ip_off = off;
    664 	outp = (u_char *)(outip + 1);
    665 #ifdef HAVE_RAW_OPTIONS
    666 	if (lsrr > 0) {
    667 		u_char *optlist;
    668 
    669 		optlist = outp;
    670 		outp += optlen;
    671 
    672 		/* final hop */
    673 		gwlist[lsrr] = to->sin_addr.s_addr;
    674 
    675 		outip->ip_dst.s_addr = gwlist[0];
    676 
    677 		/* force 4 byte alignment */
    678 		optlist[0] = IPOPT_NOP;
    679 		/* loose source route option */
    680 		optlist[1] = IPOPT_LSRR;
    681 		i = lsrr * sizeof(gwlist[0]);
    682 		optlist[2] = i + 3;
    683 		/* Pointer to LSRR addresses */
    684 		optlist[3] = IPOPT_MINOFF;
    685 		memcpy(optlist + 4, gwlist + 1, i);
    686 	} else
    687 #endif
    688 		outip->ip_dst = to->sin_addr;
    689 
    690 	outip->ip_hl = (outp - (u_char *)outip) >> 2;
    691 	ident = htons(arc4random() & 0xffff) | 0x8000;
    692 	if (useicmp) {
    693 		outip->ip_p = IPPROTO_ICMP;
    694 
    695 		outicmp = (struct icmp *)outp;
    696 		outicmp->icmp_type = ICMP_ECHO;
    697 		outicmp->icmp_id = htons(ident);
    698 
    699 		outmark = outp + 8;	/* XXX magic number */
    700 	} else {
    701 		outip->ip_p = IPPROTO_UDP;
    702 
    703 		outudp = (struct udphdr *)outp;
    704 		outudp->uh_sport = htons(ident);
    705 		outudp->uh_ulen =
    706 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
    707 		outmark = outudp + 1;
    708 	}
    709 
    710 	if (options & SO_DEBUG)
    711 		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
    712 		    sizeof(on));
    713 #ifdef IPSEC
    714 #ifdef IPSEC_POLICY_IPSEC
    715 	/*
    716 	 * do not raise error even if setsockopt fails, kernel may have ipsec
    717 	 * turned off.
    718 	 */
    719 	if (setpolicy(s, "in bypass") < 0)
    720 		exit(1);
    721 	if (setpolicy(s, "out bypass") < 0)
    722 		exit(1);
    723 #else
    724     {
    725 	int level = IPSEC_LEVEL_AVAIL;
    726 
    727 	(void)setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
    728 		sizeof(level));
    729 	(void)setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
    730 		sizeof(level));
    731 #ifdef IP_AUTH_TRANS_LEVEL
    732 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
    733 		sizeof(level));
    734 #else
    735 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
    736 		sizeof(level));
    737 #endif
    738 #ifdef IP_AUTH_NETWORK_LEVEL
    739 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
    740 		sizeof(level));
    741 #endif
    742     }
    743 #endif /*IPSEC_POLICY_IPSEC*/
    744 #endif /*IPSEC*/
    745 
    746 #ifdef IPSEC
    747 #ifdef IPSEC_POLICY_IPSEC
    748 	/*
    749 	 * do not raise error even if setsockopt fails, kernel may have ipsec
    750 	 * turned off.
    751 	 */
    752 	if (setpolicy(sndsock, "in bypass") < 0)
    753 		exit(1);
    754 	if (setpolicy(sndsock, "out bypass") < 0)
    755 		exit(1);
    756 #else
    757     {
    758 	int level = IPSEC_LEVEL_BYPASS;
    759 
    760 	(void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
    761 		sizeof(level));
    762 	(void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
    763 		sizeof(level));
    764 #ifdef IP_AUTH_TRANS_LEVEL
    765 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
    766 		sizeof(level));
    767 #else
    768 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
    769 		sizeof(level));
    770 #endif
    771 #ifdef IP_AUTH_NETWORK_LEVEL
    772 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
    773 		sizeof(level));
    774 #endif
    775     }
    776 #endif /*IPSEC_POLICY_IPSEC*/
    777 #endif /*IPSEC*/
    778 
    779 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
    780 	if (lsrr > 0) {
    781 		u_char optlist[MAX_IPOPTLEN];
    782 
    783 		/* final hop */
    784 		gwlist[lsrr] = to->sin_addr.s_addr;
    785 		++lsrr;
    786 
    787 		/* force 4 byte alignment */
    788 		optlist[0] = IPOPT_NOP;
    789 		/* loose source route option */
    790 		optlist[1] = IPOPT_LSRR;
    791 		i = lsrr * sizeof(gwlist[0]);
    792 		optlist[2] = i + 3;
    793 		/* Pointer to LSRR addresses */
    794 		optlist[3] = IPOPT_MINOFF;
    795 		memcpy(optlist + 4, gwlist, i);
    796 
    797 		if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
    798 		    i + sizeof(gwlist[0]))) < 0) {
    799 			Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
    800 			    prog, strerror(errno));
    801 			exit(1);
    802 		    }
    803 	}
    804 #endif
    805 
    806 #ifdef SO_SNDBUF
    807 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
    808 	    sizeof(packlen)) < 0) {
    809 		Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
    810 		exit(1);
    811 	}
    812 #endif
    813 #ifdef IP_HDRINCL
    814 	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
    815 	    sizeof(on)) < 0) {
    816 		Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
    817 		exit(1);
    818 	}
    819 #else
    820 #ifdef IP_TOS
    821 	if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
    822 	    (char *)&tos, sizeof(tos)) < 0) {
    823 		Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
    824 		    prog, tos, strerror(errno));
    825 		exit(1);
    826 	}
    827 #endif
    828 #endif
    829 	if (options & SO_DEBUG)
    830 		(void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
    831 		    sizeof(on));
    832 	if (options & SO_DONTROUTE)
    833 		(void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
    834 		    sizeof(on));
    835 
    836 	/* Get the interface address list */
    837 	n = ifaddrlist(&al, errbuf, sizeof errbuf);
    838 	al2 = al;
    839 	if (n < 0) {
    840 		Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
    841 		exit(1);
    842 	}
    843 	if (n == 0) {
    844 		Fprintf(stderr,
    845 		    "%s: Can't find any network interfaces\n", prog);
    846 		exit(1);
    847 	}
    848 
    849 	/* Look for a specific device */
    850 	if (device != NULL) {
    851 		for (i = n; i > 0; --i, ++al2)
    852 			if (strcmp(device, al2->device) == 0)
    853 				break;
    854 		if (i <= 0) {
    855 			Fprintf(stderr, "%s: Can't find interface %s\n",
    856 			    prog, device);
    857 			exit(1);
    858 		}
    859 	}
    860 
    861 	/* Determine our source address */
    862 	if (source == NULL) {
    863 		/*
    864 		 * If a device was specified, use the interface address.
    865 		 * Otherwise, use the first interface found.
    866 		 * Warn if there are more than one.
    867 		 */
    868 		setsin(from, al2->addr);
    869 		if (n > 1 && device == NULL && !find_local_ip(from, to)) {
    870 			Fprintf(stderr,
    871 		    "%s: Warning: Multiple interfaces found; using %s @ %s\n",
    872 			    prog, inet_ntoa(from->sin_addr), al2->device);
    873 		}
    874 	} else {
    875 		hi = gethostinfo(source);
    876 		source = hi->name;
    877 		hi->name = NULL;
    878 		if (device == NULL) {
    879 			/*
    880 			 * Use the first interface found.
    881 			 * Warn if there are more than one.
    882 			 */
    883 			setsin(from, hi->addrs[0]);
    884 			if (hi->n > 1)
    885 				Fprintf(stderr,
    886 			"%s: Warning: %s has multiple addresses; using %s\n",
    887 				    prog, source, inet_ntoa(from->sin_addr));
    888 		} else {
    889 			/*
    890 			 * Make sure the source specified matches the
    891 			 * interface address.
    892 			 */
    893 			for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
    894 				if (*ap == al2->addr)
    895 					break;
    896 			if (i <= 0) {
    897 				Fprintf(stderr,
    898 				    "%s: %s is not on interface %s\n",
    899 				    prog, source, device);
    900 				exit(1);
    901 			}
    902 			setsin(from, *ap);
    903 		}
    904 		freehostinfo(hi);
    905 	}
    906 
    907 	/*
    908 	 * If not root, make sure source address matches a local interface.
    909 	 * (The list of addresses produced by ifaddrlist() automatically
    910 	 * excludes interfaces that are marked down and/or loopback.)
    911 	 */
    912 	if (getuid())  {
    913 		al2 = al;
    914 		for (i = n; i > 0; --i, ++al2)
    915 			if (from->sin_addr.s_addr == al2->addr)
    916 			    break;
    917 		if (i <= 0) {
    918 			Fprintf(stderr, "%s: %s is not a valid local address "
    919 			    "and you are not superuser.\n", prog,
    920 			    inet_ntoa(from->sin_addr));
    921 			exit(1);
    922 		}
    923 	}
    924 
    925 	outip->ip_src = from->sin_addr;
    926 #ifndef IP_HDRINCL
    927 	if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
    928 		Fprintf(stderr, "%s: bind: %s\n",
    929 		    prog, strerror(errno));
    930 		exit (1);
    931 	}
    932 #endif
    933 
    934 	if (as_path) {
    935 		asn = as_setup(as_server);
    936 		if (asn == NULL) {
    937 			Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n",
    938 				prog);
    939 			(void)fflush(stderr);
    940 			as_path = 0;
    941 		}
    942 	}
    943 
    944 	setuid(getuid());
    945 	Fprintf(stderr, "%s to %s (%s)",
    946 	    prog, hostname, inet_ntoa(to->sin_addr));
    947 	if (source)
    948 		Fprintf(stderr, " from %s", source);
    949 	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
    950 	(void)fflush(stderr);
    951 
    952 	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
    953 		u_int32_t lastaddr = 0;
    954 		int got_there = 0;
    955 		int unreachable = 0;
    956 
    957 again:
    958 		printed_ttl = 0;
    959 		for (probe = 0; probe < nprobes; ++probe) {
    960 			int cc;
    961 			struct timeval t1, t2;
    962 			struct ip *ip;
    963 			(void)gettimeofday(&t1, NULL);
    964 			if (!useicmp && htons(port + seq + 1) == 0)
    965 				seq++;
    966 			send_probe(++seq, ttl, &t1);
    967 			while ((cc = wait_for_reply(s, from, &t1)) != 0) {
    968 				(void)gettimeofday(&t2, NULL);
    969 				/*
    970 				 * Since we'll be receiving all ICMP
    971 				 * messages to this host above, we may
    972 				 * never end up with cc=0, so we need
    973 				 * an additional termination check.
    974 				 */
    975 				if (t2.tv_sec - t1.tv_sec > waittime) {
    976 					cc = 0;
    977 					break;
    978 				}
    979 				i = packet_ok(packet, cc, from, seq);
    980 				/* Skip short packet */
    981 				if (i == 0)
    982 					continue;
    983 				if (from->sin_addr.s_addr != lastaddr) {
    984 					print(packet, cc, from);
    985 					lastaddr = from->sin_addr.s_addr;
    986 				}
    987 				ip = (struct ip *)packet;
    988 				Printf("  %.3f ms", deltaT(&t1, &t2));
    989 				if (ttl_flag)
    990 					Printf(" (ttl = %d)", ip->ip_ttl);
    991 				if (i == -2) {
    992 #ifndef ARCHAIC
    993 					if (ip->ip_ttl <= 1)
    994 						Printf(" !");
    995 #endif
    996 					++got_there;
    997 					break;
    998 				}
    999 
   1000 				/* time exceeded in transit */
   1001 				if (i == -1)
   1002 					break;
   1003 				code = i - 1;
   1004 				switch (code) {
   1005 
   1006 				case ICMP_UNREACH_PORT:
   1007 #ifndef ARCHAIC
   1008 					if (ip->ip_ttl <= 1)
   1009 						Printf(" !");
   1010 #endif
   1011 					++got_there;
   1012 					break;
   1013 
   1014 				case ICMP_UNREACH_NET:
   1015 					++unreachable;
   1016 					Printf(" !N");
   1017 					break;
   1018 
   1019 				case ICMP_UNREACH_HOST:
   1020 					++unreachable;
   1021 					Printf(" !H");
   1022 					break;
   1023 
   1024 				case ICMP_UNREACH_PROTOCOL:
   1025 					++got_there;
   1026 					Printf(" !P");
   1027 					break;
   1028 
   1029 				case ICMP_UNREACH_NEEDFRAG:
   1030 					if (mtudisc) {
   1031 						frag_err();
   1032 						goto again;
   1033 					} else {
   1034 						++unreachable;
   1035 						Printf(" !F");
   1036 					}
   1037 					break;
   1038 
   1039 				case ICMP_UNREACH_SRCFAIL:
   1040 					++unreachable;
   1041 					Printf(" !S");
   1042 					break;
   1043 
   1044 /* rfc1716 */
   1045 #ifndef ICMP_UNREACH_FILTER_PROHIB
   1046 #define ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohibited filter */
   1047 #endif
   1048 				case ICMP_UNREACH_FILTER_PROHIB:
   1049 					++unreachable;
   1050 					Printf(" !X");
   1051 					break;
   1052 
   1053 				default:
   1054 					++unreachable;
   1055 					Printf(" !<%d>", code);
   1056 					break;
   1057 				}
   1058 				break;
   1059 			}
   1060 			if (cc == 0)
   1061 				Printf(" *");
   1062 			else if (cc && probe == nprobes - 1 && Mflag)
   1063 				decode_extensions(packet, cc);
   1064 			(void)fflush(stdout);
   1065 		}
   1066 		putchar('\n');
   1067 		if (got_there ||
   1068 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
   1069 			break;
   1070 	}
   1071 
   1072 	if (as_path)
   1073 		as_shutdown(asn);
   1074 
   1075 	exit(0);
   1076 }
   1077 
   1078 int
   1079 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
   1080 {
   1081 	struct pollfd set[1];
   1082 	struct timeval now, wait;
   1083 	int cc = 0;
   1084 	socklen_t fromlen = sizeof(*fromp);
   1085 	int retval;
   1086 
   1087 	set[0].fd = sock;
   1088 	set[0].events = POLLIN;
   1089 
   1090 	wait.tv_sec = tp->tv_sec + waittime;
   1091 	wait.tv_usec = tp->tv_usec;
   1092 	(void)gettimeofday(&now, NULL);
   1093 	tvsub(&wait, &now);
   1094 
   1095 	if (wait.tv_sec < 0) {
   1096 		wait.tv_sec = 0;
   1097 		wait.tv_usec = 0;
   1098 	}
   1099 
   1100 	retval = poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
   1101 	if (retval < 0)  {
   1102 		/* If we continue, we probably just flood the remote host. */
   1103 		Fprintf(stderr, "%s: poll: %s\n", prog, strerror(errno));
   1104 		exit(1);
   1105 	}
   1106 	if (retval > 0)  {
   1107 		cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
   1108 			    (struct sockaddr *)fromp, &fromlen);
   1109 	}
   1110 
   1111 	return(cc);
   1112 }
   1113 
   1114 void
   1115 decode_extensions(unsigned char *buf, int ip_len)
   1116 {
   1117         struct icmp_ext_cmn_hdr *cmn_hdr;
   1118         struct icmp_ext_obj_hdr *obj_hdr;
   1119         union {
   1120                 struct mpls_header mpls;
   1121                 uint32_t mpls_h;
   1122         } mpls;
   1123         int datalen, obj_len;
   1124         struct ip *ip;
   1125 
   1126         ip = (struct ip *)buf;
   1127 
   1128         if (ip_len <= sizeof(struct ip) + ICMP_EXT_OFFSET) {
   1129 		/*
   1130 		 * No support for ICMP extensions on this host
   1131 		 */
   1132 		return;
   1133         }
   1134 
   1135         /*
   1136          * Move forward to the start of the ICMP extensions, if present
   1137          */
   1138         buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
   1139         cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
   1140 
   1141         if (cmn_hdr->version != ICMP_EXT_VERSION) {
   1142 		/*
   1143 		 * Unknown version
   1144 		 */
   1145 		return;
   1146         }
   1147 
   1148         datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
   1149 
   1150         /*
   1151          * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
   1152          * done by sender.
   1153          *
   1154         * If the checksum is ok, we'll get 0, as the checksum is calculated
   1155          * with the checksum field being 0'd.
   1156          */
   1157         if (ntohs(cmn_hdr->checksum) &&
   1158             in_cksum((u_short *)cmn_hdr, datalen)) {
   1159 
   1160             return;
   1161         }
   1162 
   1163         buf += sizeof(*cmn_hdr);
   1164         datalen -= sizeof(*cmn_hdr);
   1165 
   1166         while (datalen > 0) {
   1167 		obj_hdr = (struct icmp_ext_obj_hdr *)buf;
   1168 		obj_len = ntohs(obj_hdr->length);
   1169 
   1170 		/*
   1171 		 * Sanity check the length field
   1172 		 */
   1173 		if (obj_len > datalen) {
   1174 			return;
   1175 		}
   1176 
   1177 		datalen -= obj_len;
   1178 
   1179 		/*
   1180 		 * Move past the object header
   1181 		 */
   1182 		buf += sizeof(struct icmp_ext_obj_hdr);
   1183 		obj_len -= sizeof(struct icmp_ext_obj_hdr);
   1184 
   1185 		switch (obj_hdr->class_num) {
   1186 		case MPLS_STACK_ENTRY_CLASS:
   1187 			switch (obj_hdr->c_type) {
   1188 			case MPLS_STACK_ENTRY_C_TYPE:
   1189 				while (obj_len >= sizeof(uint32_t)) {
   1190 					mpls.mpls_h = ntohl(*(uint32_t *)buf);
   1191 
   1192 					buf += sizeof(uint32_t);
   1193 					obj_len -= sizeof(uint32_t);
   1194 
   1195 					printf(" [MPLS: Label %d Exp %d]",
   1196 					    mpls.mpls.label, mpls.mpls.exp);
   1197 				}
   1198 				if (obj_len > 0) {
   1199 					/*
   1200 					 * Something went wrong, and we're at
   1201 					 * a unknown offset into the packet,
   1202 					 * ditch the rest of it.
   1203 					 */
   1204 					return;
   1205 				}
   1206 				break;
   1207 			default:
   1208 				/*
   1209 				 * Unknown object, skip past it
   1210 				 */
   1211 				buf += ntohs(obj_hdr->length) -
   1212 				    sizeof(struct icmp_ext_obj_hdr);
   1213 				break;
   1214 			}
   1215 			break;
   1216 
   1217 		default:
   1218 			/*
   1219 			 * Unknown object, skip past it
   1220 			 */
   1221 			buf += ntohs(obj_hdr->length) -
   1222 			    sizeof(struct icmp_ext_obj_hdr);
   1223 			break;
   1224 		}
   1225 	}
   1226 }
   1227 
   1228 void
   1229 dump_packet()
   1230 {
   1231 	u_char *p;
   1232 	int i;
   1233 
   1234 	Fprintf(stderr, "packet data:");
   1235 
   1236 #ifdef __hpux
   1237 	for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
   1238 	    i < packlen - (sizeof(*outip) + optlen); i++)
   1239 #else
   1240 	for (p = (u_char *)outip, i = 0; i < packlen; i++)
   1241 #endif
   1242 	{
   1243 		if ((i % 24) == 0)
   1244 			Fprintf(stderr, "\n ");
   1245 		Fprintf(stderr, " %02x", *p++);
   1246 	}
   1247 	Fprintf(stderr, "\n");
   1248 }
   1249 
   1250 void
   1251 send_probe(int seq, int ttl, struct timeval *tp)
   1252 {
   1253 	int cc;
   1254 	struct udpiphdr * ui;
   1255 	int oldmtu = packlen;
   1256 
   1257 again:
   1258 #ifdef BYTESWAP_IP_LEN
   1259 	outip->ip_len = htons(packlen);
   1260 #else
   1261 	outip->ip_len = packlen;
   1262 #endif
   1263 	outip->ip_ttl = ttl;
   1264 #ifndef __hpux
   1265 	outip->ip_id = htons(ident + seq);
   1266 #endif
   1267 
   1268 	/*
   1269 	 * In most cases, the kernel will recalculate the ip checksum.
   1270 	 * But we must do it anyway so that the udp checksum comes out
   1271 	 * right.
   1272 	 */
   1273 	if (docksum) {
   1274 		outip->ip_sum =
   1275 		    in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
   1276 		if (outip->ip_sum == 0)
   1277 			outip->ip_sum = 0xffff;
   1278 	}
   1279 
   1280 	/* Payload */
   1281 	outsetup.seq = seq;
   1282 	outsetup.ttl = ttl;
   1283 	outsetup.tv  = *tp;
   1284 	memcpy(outmark,&outsetup,sizeof(outsetup));
   1285 
   1286 	if (useicmp)
   1287 		outicmp->icmp_seq = htons(seq);
   1288 	else
   1289 		outudp->uh_dport = htons(port + seq);
   1290 
   1291 	/* (We can only do the checksum if we know our ip address) */
   1292 	if (docksum) {
   1293 		if (useicmp) {
   1294 			outicmp->icmp_cksum = 0;
   1295 			outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
   1296 			    packlen - (sizeof(*outip) + optlen));
   1297 			if (outicmp->icmp_cksum == 0)
   1298 				outicmp->icmp_cksum = 0xffff;
   1299 		} else {
   1300 			u_int16_t sum;
   1301 			struct {
   1302 				struct in_addr src;
   1303 				struct in_addr dst;
   1304 				u_int8_t zero;
   1305 				u_int8_t protocol;
   1306 				u_int16_t len;
   1307 			} __packed phdr;
   1308 
   1309 			/* Checksum */
   1310 			ui = (struct udpiphdr *)outip;
   1311 			memset(&phdr, 0, sizeof(phdr));
   1312 			phdr.src = ui->ui_src;
   1313 			phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
   1314 			phdr.protocol = ui->ui_pr;
   1315 			phdr.len = outudp->uh_ulen;
   1316 			outudp->uh_sum = 0;
   1317 			sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
   1318 			sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
   1319 			outudp->uh_sum = ~sum;
   1320 			if (outudp->uh_sum == 0)
   1321 				outudp->uh_sum = 0xffff;
   1322 		}
   1323 	}
   1324 
   1325 	/* XXX undocumented debugging hack */
   1326 	if (verbose > 1) {
   1327 		const u_int16_t *sp;
   1328 		int nshorts, i;
   1329 
   1330 		sp = (u_int16_t *)outip;
   1331 		nshorts = (u_int)packlen / sizeof(u_int16_t);
   1332 		i = 0;
   1333 		Printf("[ %d bytes", packlen);
   1334 		while (--nshorts >= 0) {
   1335 			if ((i++ % 8) == 0)
   1336 				Printf("\n\t");
   1337 			Printf(" %04x", ntohs(*sp++));
   1338 		}
   1339 		if (packlen & 1) {
   1340 			if ((i % 8) == 0)
   1341 				Printf("\n\t");
   1342 			Printf(" %02x", *(u_char *)sp);
   1343 		}
   1344 		Printf("]\n");
   1345 	}
   1346 
   1347 #if !defined(IP_HDRINCL) && defined(IP_TTL)
   1348 	if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
   1349 	    (char *)&ttl, sizeof(ttl)) < 0) {
   1350 		Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
   1351 		    prog, ttl, strerror(errno));
   1352 		exit(1);
   1353 	}
   1354 #endif
   1355 	if (dump)
   1356 		dump_packet();
   1357 
   1358 #ifdef __hpux
   1359 	cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
   1360 	    packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
   1361 	if (cc > 0)
   1362 		cc += sizeof(*outip) + optlen;
   1363 #else
   1364 	cc = sendto(sndsock, (char *)outip,
   1365 	    packlen, 0, &whereto, sizeof(whereto));
   1366 #endif
   1367 	if (cc < 0 || cc != packlen)  {
   1368 		if (cc < 0) {
   1369 			/*
   1370 			 * An errno of EMSGSIZE means we're writing too big a
   1371 			 * datagram for the interface.  We have to just
   1372 			 * decrease the packet size until we find one that
   1373 			 * works.
   1374 			 *
   1375 			 * XXX maybe we should try to read the outgoing if's
   1376 			 * mtu?
   1377 			 */
   1378 			if (errno == EMSGSIZE) {
   1379 				packlen = *mtuptr++;
   1380 				resize_packet();
   1381 				goto again;
   1382 			} else
   1383 				Fprintf(stderr, "%s: sendto: %s\n",
   1384 				    prog, strerror(errno));
   1385 		}
   1386 
   1387 		Printf("%s: wrote %s %d chars, ret=%d\n",
   1388 		    prog, hostname, packlen, cc);
   1389 		(void)fflush(stdout);
   1390 	}
   1391 	if (oldmtu != packlen) {
   1392 		Printf("message too big, "
   1393 		    "trying new MTU = %d\n", packlen);
   1394 		printed_ttl = 0;
   1395 	}
   1396 	if (!printed_ttl) {
   1397 		Printf("%2d ", ttl);
   1398 		printed_ttl = 1;
   1399 	}
   1400 
   1401 }
   1402 
   1403 double
   1404 deltaT(struct timeval *t1p, struct timeval *t2p)
   1405 {
   1406 	double dt;
   1407 
   1408 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
   1409 	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
   1410 	return (dt);
   1411 }
   1412 
   1413 /*
   1414  * Convert an ICMP "type" field to a printable string.
   1415  */
   1416 char *
   1417 pr_type(u_char t)
   1418 {
   1419 	static char *ttab[] = {
   1420 	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
   1421 	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
   1422 	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
   1423 	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
   1424 	"Info Reply"
   1425 	};
   1426 
   1427 	if (t > 16)
   1428 		return("OUT-OF-RANGE");
   1429 
   1430 	return(ttab[t]);
   1431 }
   1432 
   1433 int
   1434 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
   1435 {
   1436 	struct icmp *icp;
   1437 	u_char type, code;
   1438 	int hlen;
   1439 #ifndef ARCHAIC
   1440 	struct ip *ip;
   1441 
   1442 	ip = (struct ip *) buf;
   1443 	hlen = ip->ip_hl << 2;
   1444 	if (cc < hlen + ICMP_MINLEN) {
   1445 		if (verbose)
   1446 			Printf("packet too short (%d bytes) from %s\n", cc,
   1447 				inet_ntoa(from->sin_addr));
   1448 		return (0);
   1449 	}
   1450 	cc -= hlen;
   1451 	icp = (struct icmp *)(buf + hlen);
   1452 #else
   1453 	icp = (struct icmp *)buf;
   1454 #endif
   1455 	type = icp->icmp_type;
   1456 	code = icp->icmp_code;
   1457 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
   1458 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
   1459 		struct ip *hip;
   1460 		struct udphdr *up;
   1461 		struct icmp *hicmp;
   1462 
   1463 		hip = &icp->icmp_ip;
   1464 		hlen = hip->ip_hl << 2;
   1465 
   1466 		nextmtu = ntohs(icp->icmp_nextmtu);	/* for frag_err() */
   1467 
   1468 		if (useicmp) {
   1469 			/* XXX */
   1470 			if (type == ICMP_ECHOREPLY &&
   1471 			    icp->icmp_id == htons(ident) &&
   1472 			    icp->icmp_seq == htons(seq))
   1473 				return (-2);
   1474 
   1475 			hicmp = (struct icmp *)((u_char *)hip + hlen);
   1476 			/* XXX 8 is a magic number */
   1477 			if (hlen + 8 <= cc &&
   1478 			    hip->ip_p == IPPROTO_ICMP &&
   1479 			    hicmp->icmp_id == htons(ident) &&
   1480 			    hicmp->icmp_seq == htons(seq))
   1481 				return (type == ICMP_TIMXCEED ? -1 : code + 1);
   1482 		} else {
   1483 			up = (struct udphdr *)((u_char *)hip + hlen);
   1484 			/* XXX 8 is a magic number */
   1485 			if (hlen + 12 <= cc &&
   1486 			    hip->ip_p == IPPROTO_UDP &&
   1487 			    up->uh_sport == htons(ident) &&
   1488 			    up->uh_dport == htons(port + seq))
   1489 				return (type == ICMP_TIMXCEED ? -1 : code + 1);
   1490 		}
   1491 	}
   1492 #ifndef ARCHAIC
   1493 	if (verbose) {
   1494 		int i;
   1495 		u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
   1496 
   1497 		Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
   1498 		Printf("%s: icmp type %d (%s) code %d\n",
   1499 		    inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
   1500 		for (i = 4; i < cc ; i += sizeof(*lp))
   1501 			Printf("%2d: x%8.8x\n", i, *lp++);
   1502 	}
   1503 #endif
   1504 	return(0);
   1505 }
   1506 
   1507 void resize_packet(void)
   1508 {
   1509 	if (useicmp) {
   1510 		outicmp->icmp_cksum = 0;
   1511 		outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
   1512 		    packlen - (sizeof(*outip) + optlen));
   1513 		if (outicmp->icmp_cksum == 0)
   1514 			outicmp->icmp_cksum = 0xffff;
   1515 	} else {
   1516 		outudp->uh_ulen =
   1517 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
   1518 	}
   1519 }
   1520 
   1521 void
   1522 print(u_char *buf, int cc, struct sockaddr_in *from)
   1523 {
   1524 	struct ip *ip;
   1525 	int hlen;
   1526 
   1527 	ip = (struct ip *) buf;
   1528 	hlen = ip->ip_hl << 2;
   1529 	cc -= hlen;
   1530 
   1531 	if (as_path)
   1532 		Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
   1533 
   1534 	if (nflag)
   1535 		Printf(" %s", inet_ntoa(from->sin_addr));
   1536 	else
   1537 		Printf(" %s (%s)", inetname(from->sin_addr),
   1538 		    inet_ntoa(from->sin_addr));
   1539 
   1540 	if (verbose)
   1541 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
   1542 }
   1543 
   1544 u_int16_t
   1545 in_cksum(u_int16_t *addr, int len)
   1546 {
   1547 
   1548 	return ~in_cksum2(0, addr, len);
   1549 }
   1550 
   1551 /*
   1552  * Checksum routine for Internet Protocol family headers (C Version)
   1553  */
   1554 u_int16_t
   1555 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
   1556 {
   1557 	int nleft = len;
   1558 	u_int16_t *w = addr;
   1559 	union {
   1560 		u_int16_t w;
   1561 		u_int8_t b[2];
   1562 	} answer;
   1563 	int32_t sum = seed;
   1564 
   1565 	/*
   1566 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
   1567 	 *  we add sequential 16 bit words to it, and at the end, fold
   1568 	 *  back all the carry bits from the top 16 bits into the lower
   1569 	 *  16 bits.
   1570 	 */
   1571 	while (nleft > 1)  {
   1572 		sum += *w++;
   1573 		nleft -= 2;
   1574 	}
   1575 
   1576 	/* mop up an odd byte, if necessary */
   1577 	if (nleft == 1) {
   1578 		answer.b[0] = *(u_char *)w;
   1579 		answer.b[1] = 0;
   1580 		sum += answer.w;
   1581 	}
   1582 
   1583 	/*
   1584 	 * add back carry outs from top 16 bits to low 16 bits
   1585 	 */
   1586 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
   1587 	sum += (sum >> 16);			/* add carry */
   1588 	answer.w = sum;				/* truncate to 16 bits */
   1589 	return (answer.w);
   1590 }
   1591 
   1592 /*
   1593  * Subtract 2 timeval structs:  out = out - in.
   1594  * Out is assumed to be >= in.
   1595  */
   1596 void
   1597 tvsub(struct timeval *out, struct timeval *in)
   1598 {
   1599 
   1600 	if ((out->tv_usec -= in->tv_usec) < 0)   {
   1601 		--out->tv_sec;
   1602 		out->tv_usec += 1000000;
   1603 	}
   1604 	out->tv_sec -= in->tv_sec;
   1605 }
   1606 
   1607 /*
   1608  * Construct an Internet address representation.
   1609  * If the nflag has been supplied, give
   1610  * numeric value, otherwise try for symbolic name.
   1611  */
   1612 char *
   1613 inetname(struct in_addr in)
   1614 {
   1615 	char *cp;
   1616 	struct hostent *hp;
   1617 	static int first = 1;
   1618 	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
   1619 
   1620 	if (first && !nflag) {
   1621 		int rv;
   1622 
   1623 		first = 0;
   1624 		rv = gethostname(domain, sizeof domain);
   1625 		if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
   1626 			(void)strlcpy(domain, cp + 1, sizeof(domain));
   1627 		} else
   1628 			domain[0] = '\0';
   1629 	}
   1630 	if (!nflag && in.s_addr != INADDR_ANY) {
   1631 		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
   1632 		if (hp != NULL) {
   1633 			if ((cp = strchr(hp->h_name, '.')) != NULL &&
   1634 			    strcmp(cp + 1, domain) == 0)
   1635 				*cp = '\0';
   1636 			(void)strlcpy(line, hp->h_name, sizeof(line));
   1637 			return (line);
   1638 		}
   1639 	}
   1640 	return (inet_ntoa(in));
   1641 }
   1642 
   1643 struct hostinfo *
   1644 gethostinfo(char *hostname)
   1645 {
   1646 	int n;
   1647 	struct hostent *hp;
   1648 	struct hostinfo *hi;
   1649 	char **p;
   1650 	u_int32_t *ap;
   1651 	struct in_addr addr;
   1652 
   1653 	hi = calloc(1, sizeof(*hi));
   1654 	if (hi == NULL) {
   1655 		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
   1656 		exit(1);
   1657 	}
   1658 	if (inet_aton(hostname, &addr) != 0) {
   1659 		hi->name = strdup(hostname);
   1660 		if (!hi->name) {
   1661 			Fprintf(stderr, "%s: strdup %s\n", prog,
   1662 			    strerror(errno));
   1663 			exit(1);
   1664 		}
   1665 		hi->n = 1;
   1666 		hi->addrs = calloc(1, sizeof(hi->addrs[0]));
   1667 		if (hi->addrs == NULL) {
   1668 			Fprintf(stderr, "%s: calloc %s\n",
   1669 			    prog, strerror(errno));
   1670 			exit(1);
   1671 		}
   1672 		hi->addrs[0] = addr.s_addr;
   1673 		return (hi);
   1674 	}
   1675 
   1676 	hp = gethostbyname(hostname);
   1677 	if (hp == NULL) {
   1678 		Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
   1679 		exit(1);
   1680 	}
   1681 	if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
   1682 		Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
   1683 		exit(1);
   1684 	}
   1685 	hi->name = strdup(hp->h_name);
   1686 	if (!hi->name) {
   1687 		Fprintf(stderr, "%s: strdup %s\n", prog, strerror(errno));
   1688 		exit(1);
   1689 	}
   1690 	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
   1691 		continue;
   1692 	hi->n = n;
   1693 	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
   1694 	if (hi->addrs == NULL) {
   1695 		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
   1696 		exit(1);
   1697 	}
   1698 	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
   1699 		memcpy(ap, *p, sizeof(*ap));
   1700 	return (hi);
   1701 }
   1702 
   1703 void
   1704 freehostinfo(struct hostinfo *hi)
   1705 {
   1706 	if (hi->name != NULL) {
   1707 		free(hi->name);
   1708 		hi->name = NULL;
   1709 	}
   1710 	free((char *)hi->addrs);
   1711 	free((char *)hi);
   1712 }
   1713 
   1714 void
   1715 getaddr(u_int32_t *ap, char *hostname)
   1716 {
   1717 	struct hostinfo *hi;
   1718 
   1719 	hi = gethostinfo(hostname);
   1720 	*ap = hi->addrs[0];
   1721 	freehostinfo(hi);
   1722 }
   1723 
   1724 void
   1725 setsin(struct sockaddr_in *sin, u_int32_t addr)
   1726 {
   1727 
   1728 	memset(sin, 0, sizeof(*sin));
   1729 #ifdef HAVE_SOCKADDR_SA_LEN
   1730 	sin->sin_len = sizeof(*sin);
   1731 #endif
   1732 	sin->sin_family = AF_INET;
   1733 	sin->sin_addr.s_addr = addr;
   1734 }
   1735 
   1736 /* String to value with optional min and max. Handles decimal and hex. */
   1737 int
   1738 str2val(const char *str, const char *what, int mi, int ma)
   1739 {
   1740 	const char *cp;
   1741 	long val;
   1742 	char *ep;
   1743 
   1744 	errno = 0;
   1745 	ep = NULL;
   1746 	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
   1747 		cp = str + 2;
   1748 		val = strtol(cp, &ep, 16);
   1749 	} else
   1750 		val = strtol(str, &ep, 10);
   1751 	if (errno || str[0] == '\0' || *ep != '\0') {
   1752 		Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
   1753 		    prog, str, what);
   1754 		exit(1);
   1755 	}
   1756 	if (val < mi && mi >= 0) {
   1757 		if (mi == 0)
   1758 			Fprintf(stderr, "%s: %s must be >= %d\n",
   1759 			    prog, what, mi);
   1760 		else
   1761 			Fprintf(stderr, "%s: %s must be > %d\n",
   1762 			    prog, what, mi - 1);
   1763 		exit(1);
   1764 	}
   1765 	if (val > ma && ma >= 0) {
   1766 		Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
   1767 		exit(1);
   1768 	}
   1769 	return ((int)val);
   1770 }
   1771 
   1772 __dead void
   1773 usage(void)
   1774 {
   1775 	extern char version[];
   1776 
   1777 	Fprintf(stderr, "Version %s\n", version);
   1778 	Fprintf(stderr, "usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
   1779 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
   1780 [-w waittime] [-A as_server] host [packetlen]\n",
   1781 	    prog);
   1782 	exit(1);
   1783 }
   1784 
   1785 /*
   1786  * Received ICMP unreachable (fragmentation required and DF set).
   1787  * If the ICMP error was from a "new" router, it'll contain the next-hop
   1788  * MTU that we should use next.  Otherwise we'll just keep going in the
   1789  * mtus[] table, trying until we hit a valid MTU.
   1790  */
   1791 
   1792 
   1793 void
   1794 frag_err()
   1795 {
   1796         int i;
   1797 
   1798         if (nextmtu > 0 && nextmtu < packlen) {
   1799                 Printf("\nfragmentation required and DF set, "
   1800 		     "next hop MTU = %d\n",
   1801                         nextmtu);
   1802                 packlen = nextmtu;
   1803                 for (i = 0; mtus[i] > 0; i++) {
   1804                         if (mtus[i] < nextmtu) {
   1805                                 mtuptr = &mtus[i];    /* next one to try */
   1806                                 break;
   1807                         }
   1808                 }
   1809         } else {
   1810                 Printf("\nfragmentation required and DF set. ");
   1811 		if (nextmtu)
   1812 			Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
   1813 			    nextmtu, packlen);
   1814                 packlen = *mtuptr++;
   1815 		Printf("Trying new MTU = %d\n", packlen);
   1816         }
   1817 	resize_packet();
   1818 }
   1819 
   1820 int
   1821 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
   1822 {
   1823 	int sock;
   1824 	struct sockaddr_in help;
   1825 	socklen_t help_len;
   1826 
   1827 	sock = socket(AF_INET, SOCK_DGRAM, 0);
   1828 	if (sock < 0) return (0);
   1829 
   1830 	help.sin_family = AF_INET;
   1831 	/*
   1832 	 * At this point the port number doesn't matter
   1833 	 * since it only has to be greater than zero.
   1834 	 */
   1835 	help.sin_port = 42;
   1836 	help.sin_addr.s_addr = to->sin_addr.s_addr;
   1837 	if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
   1838 		(void)close(sock);
   1839 		return (0);
   1840 	}
   1841 
   1842 	help_len = sizeof(help);
   1843 	if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
   1844 	    help_len != sizeof(help) ||
   1845 	    help.sin_addr.s_addr == INADDR_ANY) {
   1846 		(void)close(sock);
   1847 		return (0);
   1848 	}
   1849 
   1850 	(void)close(sock);
   1851 	setsin(from, help.sin_addr.s_addr);
   1852 	return (1);
   1853 }
   1854 
   1855 #ifdef IPSEC
   1856 #ifdef IPSEC_POLICY_IPSEC
   1857 int
   1858 setpolicy(so, policy)
   1859 	int so;
   1860 	char *policy;
   1861 {
   1862 	char *buf;
   1863 
   1864 	buf = ipsec_set_policy(policy, strlen(policy));
   1865 	if (buf == NULL) {
   1866 		Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror());
   1867 		return -1;
   1868 	}
   1869 	(void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
   1870 		buf, ipsec_get_policylen(buf));
   1871 
   1872 	free(buf);
   1873 
   1874 	return 0;
   1875 }
   1876 #endif
   1877 #endif
   1878 
   1879