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