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