xref: /openbsd-src/usr.sbin/traceroute/traceroute.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: traceroute.c,v 1.132 2014/06/05 14:49:11 florian Exp $	*/
2 /*	$NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*-
34  * Copyright (c) 1990, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * This code is derived from software contributed to Berkeley by
38  * Van Jacobson.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  */
64 
65 /*
66  * traceroute host  - trace the route ip packets follow going to "host".
67  *
68  * Attempt to trace the route an ip packet would follow to some
69  * internet host.  We find out intermediate hops by launching probe
70  * packets with a small ttl (time to live) then listening for an
71  * icmp "time exceeded" reply from a gateway.  We start our probes
72  * with a ttl of one and increase by one until we get an icmp "port
73  * unreachable" (which means we got to "host") or hit a max (which
74  * defaults to 64 hops & can be changed with the -m flag).  Three
75  * probes (change with -q flag) are sent at each ttl setting and a
76  * line is printed showing the ttl, address of the gateway and
77  * round trip time of each probe.  If the probe answers come from
78  * different gateways, the address of each responding system will
79  * be printed.  If there is no response within a 5 sec. timeout
80  * interval (changed with the -w flag), a "*" is printed for that
81  * probe.
82  *
83  * Probe packets are UDP format.  We don't want the destination
84  * host to process them so the destination port is set to an
85  * unlikely value (if some clod on the destination is using that
86  * value, it can be changed with the -p flag).
87  *
88  * A sample use might be:
89  *
90  *     [yak 71]% traceroute nis.nsf.net.
91  *     traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
92  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
93  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
94  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
95  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
96  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
97  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
98  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
99  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
100  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
101  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
102  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
103  *
104  * Note that lines 2 & 3 are the same.  This is due to a buggy
105  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
106  * packets with a zero ttl.
107  *
108  * A more interesting example is:
109  *
110  *     [yak 72]% traceroute allspice.lcs.mit.edu.
111  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
112  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
113  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
114  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
115  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
116  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
117  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
118  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
119  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
120  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
121  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
122  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
123  *     12  * * *
124  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
125  *     14  * * *
126  *     15  * * *
127  *     16  * * *
128  *     17  * * *
129  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
130  *
131  * (I start to see why I'm having so much trouble with mail to
132  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
133  * either don't send ICMP "time exceeded" messages or send them
134  * with a ttl too small to reach us.  14 - 17 are running the
135  * MIT C Gateway code that doesn't send "time exceeded"s.  God
136  * only knows what's going on with 12.
137  *
138  * The silent gateway 12 in the above may be the result of a bug in
139  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
140  * sends an unreachable message using whatever ttl remains in the
141  * original datagram.  Since, for gateways, the remaining ttl is
142  * zero, the icmp "time exceeded" is guaranteed to not make it back
143  * to us.  The behavior of this bug is slightly more interesting
144  * when it appears on the destination system:
145  *
146  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
147  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
148  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
149  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
150  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
151  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
152  *      7  * * *
153  *      8  * * *
154  *      9  * * *
155  *     10  * * *
156  *     11  * * *
157  *     12  * * *
158  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
159  *
160  * Notice that there are 12 "gateways" (13 is the final
161  * destination) and exactly the last half of them are "missing".
162  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
163  * is using the ttl from our arriving datagram as the ttl in its
164  * icmp reply.  So, the reply will time out on the return path
165  * (with no notice sent to anyone since icmp's aren't sent for
166  * icmp's) until we probe with a ttl that's at least twice the path
167  * length.  I.e., rip is really only 7 hops away.  A reply that
168  * returns with a ttl of 1 is a clue this problem exists.
169  * Traceroute prints a "!" after the time if the ttl is <= 1.
170  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
171  * non-standard (HPUX) software, expect to see this problem
172  * frequently and/or take care picking the target host of your
173  * probes.
174  *
175  * Other possible annotations after the time are !H, !N, !P (got a host,
176  * network or protocol unreachable, respectively), !S or !F (source
177  * route failed or fragmentation needed -- neither of these should
178  * ever occur and the associated gateway is busted if you see one).  If
179  * almost all the probes result in some kind of unreachable, traceroute
180  * will give up and exit.
181  *
182  * Notes
183  * -----
184  * This program must be run by root or be setuid.  (I suggest that
185  * you *don't* make it setuid -- casual use could result in a lot
186  * of unnecessary traffic on our poor, congested nets.)
187  *
188  * This program requires a kernel mod that does not appear in any
189  * system available from Berkeley:  A raw ip socket using proto
190  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
191  * opposed to data to be wrapped in a ip datagram).  See the README
192  * file that came with the source to this program for a description
193  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
194  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
195  * MODIFIED TO RUN THIS PROGRAM.
196  *
197  * The udp port usage may appear bizarre (well, ok, it is bizarre).
198  * The problem is that an icmp message only contains 8 bytes of
199  * data from the original datagram.  8 bytes is the size of a udp
200  * header so, if we want to associate replies with the original
201  * datagram, the necessary information must be encoded into the
202  * udp header (the ip id could be used but there's no way to
203  * interlock with the kernel's assignment of ip id's and, anyway,
204  * it would have taken a lot more kernel hacking to allow this
205  * code to set the ip id).  So, to allow two or more users to
206  * use traceroute simultaneously, we use this task's pid as the
207  * source port (the high bit is set to move the port number out
208  * of the "likely" range).  To keep track of which probe is being
209  * replied to (so times and/or hop counts don't get confused by a
210  * reply that was delayed in transit), we increment the destination
211  * port number before each probe.
212  *
213  * Don't use this as a coding example.  I was trying to find a
214  * routing problem and this code sort-of popped out after 48 hours
215  * without sleep.  I was amazed it ever compiled, much less ran.
216  *
217  * I stole the idea for this program from Steve Deering.  Since
218  * the first release, I've learned that had I attended the right
219  * IETF working group meetings, I also could have stolen it from Guy
220  * Almes or Matt Mathis.  I don't know (or care) who came up with
221  * the idea first.  I envy the originators' perspicacity and I'm
222  * glad they didn't keep the idea a secret.
223  *
224  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
225  * enhancements to the original distribution.
226  *
227  * I've hacked up a round-trip-route version of this that works by
228  * sending a loose-source-routed udp datagram through the destination
229  * back to yourself.  Unfortunately, SO many gateways botch source
230  * routing, the thing is almost worthless.  Maybe one day...
231  *
232  *  -- Van Jacobson (van@helios.ee.lbl.gov)
233  *     Tue Dec 20 03:50:13 PST 1988
234  */
235 
236 #include <sys/param.h>
237 #include <sys/time.h>
238 #include <sys/socket.h>
239 #include <sys/uio.h>
240 #include <sys/file.h>
241 #include <sys/ioctl.h>
242 #include <sys/sysctl.h>
243 
244 #include <netinet/in_systm.h>
245 #include <netinet/in.h>
246 #include <netinet/ip.h>
247 #include <netinet/ip_icmp.h>
248 #include <netinet/ip_var.h>
249 #include <netinet/ip6.h>
250 #include <netinet/icmp6.h>
251 #include <netinet/udp.h>
252 
253 #define DUMMY_PORT 10010
254 
255 #include <arpa/inet.h>
256 #include <arpa/nameser.h>
257 
258 #include <netmpls/mpls.h>
259 
260 #include <ctype.h>
261 #include <err.h>
262 #include <poll.h>
263 #include <errno.h>
264 #include <netdb.h>
265 #include <stdio.h>
266 #include <stdlib.h>
267 #include <string.h>
268 #include <unistd.h>
269 
270 #define MAX_LSRR		((MAX_IPOPTLEN - 4) / 4)
271 
272 #define MPLS_LABEL(m)		((m & MPLS_LABEL_MASK) >> MPLS_LABEL_OFFSET)
273 #define MPLS_EXP(m)		((m & MPLS_EXP_MASK) >> MPLS_EXP_OFFSET)
274 
275 /*
276  * Format of the data in a (udp) probe packet.
277  */
278 struct packetdata {
279 	u_char seq;		/* sequence number of this packet */
280 	u_int8_t ttl;		/* ttl packet left with */
281 	u_char pad[2];
282 	u_int32_t sec;		/* time packet left */
283 	u_int32_t usec;
284 } __packed;
285 
286 struct in_addr gateway[MAX_LSRR + 1];
287 int lsrrlen = 0;
288 int32_t sec_perturb;
289 int32_t usec_perturb;
290 
291 u_char packet[512], *outpacket;	/* last inbound (icmp) packet */
292 
293 int wait_for_reply(int, struct msghdr *);
294 void dump_packet(void);
295 void build_probe4(int, u_int8_t, int);
296 void build_probe6(int, u_int8_t, int, struct sockaddr *);
297 void send_probe(int, u_int8_t, int, struct sockaddr *);
298 struct udphdr *get_udphdr(struct ip6_hdr *, u_char *);
299 int packet_ok(int, struct msghdr *, int, int, int);
300 int packet_ok4(struct msghdr *, int, int, int);
301 int packet_ok6(struct msghdr *, int, int, int);
302 void icmp_code(int, int, int *, int *);
303 void icmp4_code(int, int *, int *);
304 void icmp6_code(int, int *, int *);
305 void dump_packet(void);
306 void print_exthdr(u_char *, int);
307 void check_tos(struct ip*);
308 void print(struct sockaddr *, int, const char *);
309 const char *inetname(struct sockaddr*);
310 void print_asn(struct sockaddr_storage *);
311 u_short in_cksum(u_short *, int);
312 char *pr_type(u_int8_t);
313 int map_tos(char *, int *);
314 double deltaT(struct timeval *, struct timeval *);
315 void usage(void);
316 
317 int rcvsock;			/* receive (icmp) socket file descriptor */
318 int sndsock;			/* send (udp) socket file descriptor */
319 
320 struct msghdr rcvmhdr;
321 struct iovec rcviov[2];
322 
323 int rcvhlim;
324 struct in6_pktinfo *rcvpktinfo;
325 
326 int datalen;			/* How much data */
327 int headerlen;			/* How long packet's header is */
328 
329 char *source = 0;
330 char *hostname;
331 
332 int nprobes = 3;
333 u_int8_t max_ttl = IPDEFTTL;
334 u_int8_t first_ttl = 1;
335 u_short ident;
336 u_int16_t srcport;
337 u_int16_t port = 32768+666;	/* start udp dest port # for probe packets */
338 u_char	proto = IPPROTO_UDP;
339 u_int8_t  icmp_type = ICMP_ECHO; /* default ICMP code/type */
340 #define ICMP_CODE 0;
341 int options;			/* socket options */
342 int verbose;
343 int waittime = 5;		/* time to wait for response (in seconds) */
344 int nflag;			/* print addresses numerically */
345 int dump;
346 int xflag;			/* show ICMP extension header */
347 int tflag;			/* tos flag was set */
348 int Aflag;			/* lookup ASN */
349 int last_tos;
350 int v6flag;
351 
352 extern char *__progname;
353 
354 int
355 main(int argc, char *argv[])
356 {
357 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
358 	int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
359 	int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0, error, packetlen;
360 	int rcvcmsglen, rcvsock4, rcvsock6, sndsock4, sndsock6;
361 	int v4sock_errno, v6sock_errno;
362 	struct addrinfo hints, *res;
363 	size_t size;
364 	static u_char *rcvcmsgbuf;
365 	struct sockaddr_in from4, to4;
366 	struct sockaddr_in6 from6, to6;
367 	struct sockaddr *from, *to;
368 	struct hostent *hp;
369 	u_int32_t tmprnd;
370 	struct ip *ip = NULL;
371 	u_int8_t ttl;
372 	char *ep, hbuf[NI_MAXHOST], *dest;
373 	const char *errstr;
374 	long l;
375 	uid_t uid;
376 	u_int rtableid;
377 	socklen_t len;
378 
379 	rcvsock4 = rcvsock6 = sndsock4 = sndsock6 = -1;
380 	v4sock_errno = v6sock_errno = 0;
381 
382 	if ((rcvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
383 		v6sock_errno = errno;
384 	else if ((sndsock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
385 		v6sock_errno = errno;
386 
387 	if ((rcvsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
388 		v4sock_errno = errno;
389 	else if ((sndsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
390 		v4sock_errno = errno;
391 
392 	/* revoke privs */
393 	uid = getuid();
394 	if (setresuid(uid, uid, uid) == -1)
395 		err(1, "setresuid");
396 
397 	if (strcmp("traceroute6", __progname) == 0) {
398 		v6flag = 1;
399 		if (v6sock_errno != 0)
400 			errc(5, v6sock_errno, rcvsock6 < 0 ? "socket(ICMPv6)" :
401 			    "socket(SOCK_DGRAM)");
402 		rcvsock = rcvsock6;
403 		sndsock = sndsock6;
404 		if (rcvsock4 >= 0)
405 			close(rcvsock4);
406 		if (sndsock4 >= 0)
407 			close(sndsock4);
408 	} else {
409 		if (v4sock_errno != 0)
410 			errc(5, v4sock_errno, rcvsock4 < 0 ? "icmp socket" :
411 			    "raw socket");
412 		rcvsock = rcvsock4;
413 		sndsock = sndsock4;
414 		if (rcvsock6 >= 0)
415 			close(rcvsock6);
416 		if (sndsock6 >= 0)
417 			close(sndsock6);
418 	}
419 
420 	if (v6flag) {
421 		mib[1] = PF_INET6;
422 		mib[2] = IPPROTO_IPV6;
423 		mib[3] = IPV6CTL_DEFHLIM;
424 		/* specify to tell receiving interface */
425 		if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
426 		    sizeof(on)) < 0)
427 			err(1, "setsockopt(IPV6_RECVPKTINFO)");
428 
429 		/* specify to tell hoplimit field of received IP6 hdr */
430 		if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
431 		    sizeof(on)) < 0)
432 			err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
433 	}
434 
435 	size = sizeof(i);
436 	if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0) == -1)
437 		err(1, "sysctl");
438 	max_ttl = i;
439 
440 	while ((ch = getopt(argc, argv, v6flag ? "AcDdf:Ilm:np:q:Ss:w:vV:" :
441 	    "AcDdf:g:Ilm:nP:p:q:Ss:t:V:vw:x")) != -1)
442 		switch (ch) {
443 		case 'A':
444 			Aflag++;
445 			break;
446 		case 'c':
447 			incflag = 0;
448 			break;
449 		case 'd':
450 			options |= SO_DEBUG;
451 			break;
452 		case 'D':
453 			dump = 1;
454 			break;
455 		case 'f':
456 			errno = 0;
457 			ep = NULL;
458 			l = strtol(optarg, &ep, 10);
459 			if (errno || !*optarg || *ep || l < 1 || l > max_ttl)
460 				errx(1, "min ttl must be 1 to %u.", max_ttl);
461 			first_ttl = (u_int8_t)l;
462 			break;
463 		case 'g':
464 			if (lsrr >= MAX_LSRR)
465 				errx(1, "too many gateways; max %d", MAX_LSRR);
466 			if (inet_aton(optarg, &gateway[lsrr]) == 0) {
467 				hp = gethostbyname(optarg);
468 				if (hp == 0)
469 					errx(1, "unknown host %s", optarg);
470 				memcpy(&gateway[lsrr], hp->h_addr,
471 				    hp->h_length);
472 			}
473 			if (++lsrr == 1)
474 				lsrrlen = 4;
475 			lsrrlen += 4;
476 			break;
477 		case 'I':
478 			if (protoset)
479 				errx(1, "protocol already set with -P");
480 			protoset = 1;
481 			proto = IPPROTO_ICMP;
482 			break;
483 		case 'l':
484 			ttl_flag++;
485 			break;
486 		case 'm':
487 			errno = 0;
488 			ep = NULL;
489 			l = strtol(optarg, &ep, 10);
490 			if (errno || !*optarg || *ep || l < first_ttl ||
491 			    l > MAXTTL)
492 				errx(1, "max ttl must be %u to %u.", first_ttl,
493 				    MAXTTL);
494 			max_ttl = (u_int8_t)l;
495 			break;
496 		case 'n':
497 			nflag++;
498 			break;
499 		case 'p':
500 			errno = 0;
501 			ep = NULL;
502 			l = strtol(optarg, &ep, 10);
503 			if (errno || !*optarg || *ep || l <= 0 || l >= 65536)
504 				errx(1, "port must be >0, <65536.");
505 			port = (u_int16_t)l;
506 			break;
507 		case 'P':
508 			if (protoset)
509 				errx(1, "protocol already set with -I");
510 			protoset = 1;
511 			errno = 0;
512 			ep = NULL;
513 			l = strtol(optarg, &ep, 10);
514 			if (errno || !*optarg || *ep || l < 1 ||
515 			    l >= IPPROTO_MAX) {
516 				struct protoent *pent;
517 
518 				pent = getprotobyname(optarg);
519 				if (pent)
520 					proto = pent->p_proto;
521 				else
522 					errx(1, "proto must be >=1, or a "
523 					    "name.");
524 			} else
525 				proto = (int)l;
526 			break;
527 		case 'q':
528 			errno = 0;
529 			ep = NULL;
530 			l = strtol(optarg, &ep, 10);
531 			if (errno || !*optarg || *ep || l < 1 || l > INT_MAX)
532 				errx(1, "nprobes must be >0.");
533 			nprobes = (int)l;
534 			break;
535 		case 's':
536 			/*
537 			 * set the ip source address of the outbound
538 			 * probe (e.g., on a multi-homed host).
539 			 */
540 			source = optarg;
541 			break;
542 		case 'S':
543 			sump = 1;
544 			break;
545 		case 't':
546 			if (!map_tos(optarg, &tos)) {
547 			errno = 0;
548 				errstr = NULL;
549 				if (strlen(optarg) > 1 && optarg[0] == '0' &&
550 				    optarg[1] == 'x')
551 					tos = (int)strtol(optarg, NULL, 16);
552 				else
553 					tos = (int)strtonum(optarg, 0, 255,
554 					    &errstr);
555 				if (tos < 0 || tos > 255 || errstr || errno)
556 					errx(1, "illegal tos value %s",
557 					    optarg);
558 			}
559 			tflag = 1;
560 			last_tos = tos;
561 			break;
562 		case 'v':
563 			verbose++;
564 			break;
565 		case 'V':
566 			rtableid = (unsigned int)strtonum(optarg, 0,
567 			    RT_TABLEID_MAX, &errstr);
568 			if (errstr)
569 				errx(1, "rtable value is %s: %s",
570 				    errstr, optarg);
571 			if (setsockopt(sndsock, SOL_SOCKET, SO_RTABLE,
572 			    &rtableid, sizeof(rtableid)) == -1)
573 				err(1, "setsockopt SO_RTABLE");
574 			if (setsockopt(rcvsock, SOL_SOCKET, SO_RTABLE,
575 			    &rtableid, sizeof(rtableid)) == -1)
576 				err(1, "setsockopt SO_RTABLE");
577 			break;
578 		case 'w':
579 			errno = 0;
580 			ep = NULL;
581 			l = strtol(optarg, &ep, 10);
582 			if (errno || !*optarg || *ep || l <= 1 || l > INT_MAX)
583 				errx(1, "wait must be >1 sec.");
584 			waittime = (int)l;
585 			break;
586 		case 'x':
587 			xflag = 1;
588 			break;
589 		default:
590 			usage();
591 		}
592 	argc -= optind;
593 	argv += optind;
594 
595 	if (argc < 1 || argc > 2)
596 		usage();
597 
598 	setvbuf(stdout, NULL, _IOLBF, 0);
599 
600 	ident = (getpid() & 0xffff) | 0x8000;
601 	tmprnd = arc4random();
602 	sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :
603 	    (tmprnd & 0x7ff);
604 	usec_perturb = arc4random();
605 
606 	(void) memset(&to4, 0, sizeof(to4));
607 	(void) memset(&to6, 0, sizeof(to6));
608 
609 	if (inet_aton(*argv, &to4.sin_addr) != 0) {
610 		hostname = *argv;
611 		if ((dest = strdup(inet_ntoa(to4.sin_addr))) == NULL)
612 			errx(1, "malloc");
613 	} else
614 		dest = *argv;
615 
616 	memset(&hints, 0, sizeof(hints));
617 	hints.ai_family = v6flag ? PF_INET6 : PF_INET;
618 	hints.ai_socktype = SOCK_RAW;
619 	hints.ai_protocol = 0;
620 	hints.ai_flags = AI_CANONNAME;
621 	if ((error = getaddrinfo(dest, NULL, &hints, &res)))
622 		errx(1, "%s", gai_strerror(error));
623 
624 	switch (res->ai_family) {
625 	case AF_INET:
626 		if (res->ai_addrlen != sizeof(to4))
627 		    errx(1, "size of sockaddr mismatch");
628 
629 		to = (struct sockaddr *)&to4;
630 		from = (struct sockaddr *)&from4;
631 		break;
632 	case AF_INET6:
633 		if (res->ai_addrlen != sizeof(to6))
634 			errx(1, "size of sockaddr mismatch");
635 
636 		to = (struct sockaddr *)&to6;
637 		from = (struct sockaddr *)&from6;
638 		break;
639 	default:
640 		errx(1, "unsupported AF: %d", res->ai_family);
641 		break;
642 	}
643 
644 	memcpy(to, res->ai_addr, res->ai_addrlen);
645 
646 	if (!hostname) {
647 		hostname = res->ai_canonname ? strdup(res->ai_canonname) : dest;
648 		if (!hostname)
649 			errx(1, "malloc");
650 	}
651 
652 	if (res->ai_next) {
653 		if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
654 		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
655 			strlcpy(hbuf, "?", sizeof(hbuf));
656 		warnx("Warning: %s has multiple "
657 		    "addresses; using %s\n", hostname, hbuf);
658 	}
659 	freeaddrinfo(res);
660 
661 	if (*++argv) {
662 		errno = 0;
663 		ep = NULL;
664 		l = strtol(*argv, &ep, 10);
665 		if (errno || !*argv || *ep || l < 0 || l > INT_MAX)
666 			errx(1, "datalen out of range");
667 		datalen = (int)l;
668 	}
669 
670 	switch (to->sa_family) {
671 	case AF_INET:
672 		switch (proto) {
673 		case IPPROTO_UDP:
674 			headerlen = (sizeof(struct ip) + lsrrlen +
675 			    sizeof(struct udphdr) + sizeof(struct packetdata));
676 			break;
677 		case IPPROTO_ICMP:
678 			headerlen = (sizeof(struct ip) + lsrrlen +
679 			    sizeof(struct icmp) + sizeof(struct packetdata));
680 			break;
681 		default:
682 			headerlen = (sizeof(struct ip) + lsrrlen +
683 			    sizeof(struct packetdata));
684 		}
685 
686 		if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
687 			errx(1, "packet size must be 0 to %d.",
688 			    IP_MAXPACKET - headerlen);
689 
690 		datalen += headerlen;
691 
692 		if ((outpacket = calloc(1, datalen)) == NULL)
693 			err(1, "calloc");
694 
695 		rcviov[0].iov_base = (caddr_t)packet;
696 		rcviov[0].iov_len = sizeof(packet);
697 		rcvmhdr.msg_name = (caddr_t)&from4;
698 		rcvmhdr.msg_namelen = sizeof(from4);
699 		rcvmhdr.msg_iov = rcviov;
700 		rcvmhdr.msg_iovlen = 1;
701 		rcvmhdr.msg_control = NULL;
702 		rcvmhdr.msg_controllen = 0;
703 
704 		ip = (struct ip *)outpacket;
705 		if (lsrr != 0) {
706 			u_char *p = (u_char *)(ip + 1);
707 
708 			*p++ = IPOPT_NOP;
709 			*p++ = IPOPT_LSRR;
710 			*p++ = lsrrlen - 1;
711 			*p++ = IPOPT_MINOFF;
712 			gateway[lsrr] = to4.sin_addr;
713 			for (i = 1; i <= lsrr; i++) {
714 				memcpy(p, &gateway[i], sizeof(struct in_addr));
715 				p += sizeof(struct in_addr);
716 			}
717 			ip->ip_dst = gateway[0];
718 		} else
719 			ip->ip_dst = to4.sin_addr;
720 		ip->ip_off = htons(0);
721 		ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;
722 		ip->ip_p = proto;
723 		ip->ip_v = IPVERSION;
724 		ip->ip_tos = tos;
725 
726 		if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
727 		    sizeof(on)) < 0)
728 			err(6, "IP_HDRINCL");
729 
730 		if (source) {
731 			(void) memset(&from4, 0, sizeof(from4));
732 			from4.sin_family = AF_INET;
733 			if (inet_aton(source, &from4.sin_addr) == 0)
734 				errx(1, "unknown host %s", source);
735 			ip->ip_src = from4.sin_addr;
736 			if (getuid() != 0 &&
737 			    (ntohl(from4.sin_addr.s_addr) & 0xff000000U) ==
738 			    0x7f000000U && (ntohl(to4.sin_addr.s_addr) &
739 			    0xff000000U) != 0x7f000000U)
740 				errx(1, "source is on 127/8, destination is"
741 				    " not");
742 			if (getuid() && bind(sndsock, (struct sockaddr *)&from4,
743 			    sizeof(from4)) < 0)
744 				err(1, "bind");
745 		}
746 		packetlen = datalen;
747 		break;
748 	case AF_INET6:
749 		/*
750 		 * packetlen is the size of the complete IP packet sent and
751 		 * reported in the first line of output.
752 		 * For IPv4 this is equal to datalen since we are constructing
753 		 * a raw packet.
754 		 * For IPv6 we need to always add the size of the IP6 header
755 		 * and for UDP packets the size of the UDP header since they
756 		 * are prepended to the packet by the kernel
757 		 */
758 		packetlen = sizeof(struct ip6_hdr);
759 		switch (proto) {
760 		case IPPROTO_UDP:
761 			headerlen = sizeof(struct packetdata);
762 			packetlen += sizeof(struct udphdr);
763 			break;
764 		case IPPROTO_ICMP:
765 			headerlen = sizeof(struct icmp6_hdr) +
766 			    sizeof(struct packetdata);
767 			break;
768 		default:
769 			errx(1, "Unsupported proto: %hhu", proto);
770 			break;
771 		}
772 
773 		if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
774 			errx(1, "packet size must be 0 to %d.",
775 			    IP_MAXPACKET - headerlen);
776 
777 		datalen += headerlen;
778 		packetlen += datalen;
779 
780 		if ((outpacket = calloc(1, datalen)) == NULL)
781 			err(1, "calloc");
782 
783 		/* initialize msghdr for receiving packets */
784 		rcviov[0].iov_base = (caddr_t)packet;
785 		rcviov[0].iov_len = sizeof(packet);
786 		rcvmhdr.msg_name = (caddr_t)&from6;
787 		rcvmhdr.msg_namelen = sizeof(from6);
788 		rcvmhdr.msg_iov = rcviov;
789 		rcvmhdr.msg_iovlen = 1;
790 		rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
791 		    CMSG_SPACE(sizeof(int));
792 
793 		if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL)
794 			errx(1, "malloc");
795 		rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
796 		rcvmhdr.msg_controllen = rcvcmsglen;
797 
798 		/*
799 		 * Send UDP or ICMP
800 		 */
801 		if (proto == IPPROTO_ICMP) {
802 			close(sndsock);
803 			sndsock = rcvsock;
804 		}
805 
806 		/*
807 		 * Source selection
808 		 */
809 		memset(&from6, 0, sizeof(from6));
810 		if (source) {
811 			memset(&hints, 0, sizeof(hints));
812 			hints.ai_family = AF_INET6;
813 			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
814 			hints.ai_flags = AI_NUMERICHOST;
815 			if ((error = getaddrinfo(source, "0", &hints, &res)))
816 				errx(1, "%s: %s", source, gai_strerror(error));
817 			if (res->ai_addrlen != sizeof(from6))
818 				errx(1, "size of sockaddr mismatch");
819 			memcpy(&from6, res->ai_addr, res->ai_addrlen);
820 			freeaddrinfo(res);
821 		} else {
822 			struct sockaddr_in6 nxt;
823 			int dummy;
824 
825 			nxt = to6;
826 			nxt.sin6_port = htons(DUMMY_PORT);
827 			if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
828 				err(1, "socket");
829 			if (connect(dummy, (struct sockaddr *)&nxt,
830 			    nxt.sin6_len) < 0)
831 				err(1, "connect");
832 			len = sizeof(from6);
833 			if (getsockname(dummy, (struct sockaddr *)&from6,
834 			    &len) < 0)
835 				err(1, "getsockname");
836 			close(dummy);
837 		}
838 
839 		from6.sin6_port = htons(0);
840 		if (bind(sndsock, (struct sockaddr *)&from6, from6.sin6_len) <
841 		    0)
842 			err(1, "bind sndsock");
843 
844 		len = sizeof(from6);
845 		if (getsockname(sndsock, (struct sockaddr *)&from6, &len) < 0)
846 			err(1, "getsockname");
847 		srcport = ntohs(from6.sin6_port);
848 		break;
849 	default:
850 		errx(1, "unsupported AF: %d", to->sa_family);
851 		break;
852 	}
853 
854 	if (options & SO_DEBUG) {
855 		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
856 		    (char *)&on, sizeof(on));
857 		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
858 		    (char *)&on, sizeof(on));
859 	}
860 
861 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
862 	    sizeof(datalen)) < 0)
863 		err(6, "SO_SNDBUF");
864 
865 	if (getnameinfo(to, to->sa_len, hbuf,
866 	    sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
867 		strlcpy(hbuf, "(invalid)", sizeof(hbuf));
868 	fprintf(stderr, "%s to %s (%s)", __progname, hostname, hbuf);
869 	if (source)
870 		fprintf(stderr, " from %s", source);
871 	fprintf(stderr, ", %u hops max, %d byte packets\n", max_ttl, packetlen);
872 	(void) fflush(stderr);
873 
874 	if (first_ttl > 1)
875 		printf("Skipping %u intermediate hops\n", first_ttl - 1);
876 
877 	for (ttl = first_ttl; ttl && ttl <= max_ttl; ++ttl) {
878 		int got_there = 0, unreachable = 0, timeout = 0, loss;
879 		in_addr_t lastaddr = 0;
880 		struct in6_addr lastaddr6;
881 
882 		printf("%2u ", ttl);
883 		memset(&lastaddr6, 0, sizeof(lastaddr6));
884 		for (probe = 0, loss = 0; probe < nprobes; ++probe) {
885 			int cc;
886 			struct timeval t1, t2;
887 
888 			(void) gettimeofday(&t1, NULL);
889 			send_probe(++seq, ttl, incflag, to);
890 			while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
891 				(void) gettimeofday(&t2, NULL);
892 				i = packet_ok(to->sa_family, &rcvmhdr, cc, seq,
893 				    incflag);
894 				/* Skip short packet */
895 				if (i == 0)
896 					continue;
897 				if (to->sa_family == AF_INET) {
898 					ip = (struct ip *)packet;
899 					if (from4.sin_addr.s_addr != lastaddr) {
900 						print(from,
901 						    cc - (ip->ip_hl << 2),
902 						    inet_ntop(AF_INET,
903 						    &ip->ip_dst, hbuf,
904 						    sizeof(hbuf)));
905 						lastaddr =
906 						    from4.sin_addr.s_addr;
907 					}
908 				} else if (to->sa_family == AF_INET6) {
909 					if (!IN6_ARE_ADDR_EQUAL(
910 					    &from6.sin6_addr, &lastaddr6)) {
911 						print(from, cc, rcvpktinfo ?
912 						    inet_ntop( AF_INET6,
913 						    &rcvpktinfo->ipi6_addr,
914 						    hbuf, sizeof(hbuf)) : "?");
915 						lastaddr6 = from6.sin6_addr;
916 					}
917 				} else
918 					errx(1, "unsupported AF: %d",
919 					    to->sa_family);
920 
921 				printf("  %g ms", deltaT(&t1, &t2));
922 				if (ttl_flag)
923 					printf(" (%u)", v6flag ? rcvhlim :
924 					    ip->ip_ttl);
925 				if (to->sa_family == AF_INET) {
926 					if (i == -2) {
927 						if (ip->ip_ttl <= 1)
928 							printf(" !");
929 						++got_there;
930 						break;
931 					}
932 
933 					if (tflag)
934 						check_tos(ip);
935 				}
936 
937 				/* time exceeded in transit */
938 				if (i == -1)
939 					break;
940 				icmp_code(to->sa_family, i - 1, &got_there,
941 				    &unreachable);
942 				break;
943 			}
944 			if (cc == 0) {
945 				printf(" *");
946 				timeout++;
947 				loss++;
948 			} else if (cc && probe == nprobes - 1 &&
949 			    (xflag || verbose))
950 				print_exthdr(packet, cc);
951 			(void) fflush(stdout);
952 		}
953 		if (sump)
954 			printf(" (%d%% loss)", (loss * 100) / nprobes);
955 		putchar('\n');
956 		if (got_there ||
957 		    (unreachable && (unreachable + timeout) >= nprobes))
958 			break;
959 	}
960 	exit(0);
961 }
962 
963 void
964 print_exthdr(u_char *buf, int cc)
965 {
966 	struct icmp_ext_hdr exthdr;
967 	struct icmp_ext_obj_hdr objhdr;
968 	struct ip *ip;
969 	struct icmp *icp;
970 	int hlen, first;
971 	u_int32_t label;
972 	u_int16_t off, olen;
973 	u_int8_t type;
974 
975 	ip = (struct ip *)buf;
976 	hlen = ip->ip_hl << 2;
977 	if (cc < hlen + ICMP_MINLEN)
978 		return;
979 	icp = (struct icmp *)(buf + hlen);
980 	cc -= hlen + ICMP_MINLEN;
981 	buf += hlen + ICMP_MINLEN;
982 
983 	type = icp->icmp_type;
984 	if (type != ICMP_TIMXCEED && type != ICMP_UNREACH &&
985 	    type != ICMP_PARAMPROB)
986 		/* Wrong ICMP type for extension */
987 		return;
988 
989 	off = icp->icmp_length * sizeof(u_int32_t);
990 	if (off == 0)
991 		/*
992 		 * rfc 4884 Section 5.5: traceroute MUST try to parse
993 		 * broken ext headers. Again IETF bent over to please
994 		 * idotic corporations.
995 		 */
996 		off = ICMP_EXT_OFFSET;
997 	else if (off < ICMP_EXT_OFFSET)
998 		/* rfc 4884 requires an offset of at least 128 bytes */
999 		return;
1000 
1001 	/* make sure that at least one extension is present */
1002 	if (cc < off + sizeof(exthdr) + sizeof(objhdr))
1003 		/* Not enough space for ICMP extensions */
1004 		return;
1005 
1006 	cc -= off;
1007 	buf += off;
1008 	memcpy(&exthdr, buf, sizeof(exthdr));
1009 
1010 	/* verify version */
1011 	if ((exthdr.ieh_version & ICMP_EXT_HDR_VMASK) != ICMP_EXT_HDR_VERSION)
1012 		return;
1013 
1014 	/* verify checksum */
1015 	if (exthdr.ieh_cksum && in_cksum((u_short *)buf, cc))
1016 		return;
1017 
1018 	buf += sizeof(exthdr);
1019 	cc -= sizeof(exthdr);
1020 
1021 	while (cc > sizeof(objhdr)) {
1022 		memcpy(&objhdr, buf, sizeof(objhdr));
1023 		olen = ntohs(objhdr.ieo_length);
1024 
1025 		/* Sanity check the length field */
1026 		if (olen < sizeof(objhdr) || olen > cc)
1027 			return;
1028 
1029 		cc -= olen;
1030 
1031 		/* Move past the object header */
1032 		buf += sizeof(objhdr);
1033 		olen -= sizeof(objhdr);
1034 
1035 		switch (objhdr.ieo_cnum) {
1036 		case ICMP_EXT_MPLS:
1037 			/* RFC 4950: ICMP Extensions for MPLS */
1038 			switch (objhdr.ieo_ctype) {
1039 			case 1:
1040 				first = 0;
1041 				while (olen >= sizeof(u_int32_t)) {
1042 					memcpy(&label, buf, sizeof(u_int32_t));
1043 					label = htonl(label);
1044 					buf += sizeof(u_int32_t);
1045 					olen -= sizeof(u_int32_t);
1046 
1047 					if (first == 0) {
1048 						printf(" [MPLS Label ");
1049 						first++;
1050 					} else
1051 						printf(", ");
1052 					printf("%d", MPLS_LABEL(label));
1053 					if (MPLS_EXP(label))
1054 						printf(" (Exp %x)",
1055 						    MPLS_EXP(label));
1056 				}
1057 				if (olen > 0) {
1058 					printf("|]");
1059 					return;
1060 				}
1061 				if (first != 0)
1062 					printf("]");
1063 				break;
1064 			default:
1065 				buf += olen;
1066 				break;
1067 			}
1068 			break;
1069 		case ICMP_EXT_IFINFO:
1070 		default:
1071 			buf += olen;
1072 			break;
1073 		}
1074 	}
1075 }
1076 
1077 void
1078 check_tos(struct ip *ip)
1079 {
1080 	struct icmp *icp;
1081 	struct ip *inner_ip;
1082 
1083 	icp = (struct icmp *) (((u_char *)ip)+(ip->ip_hl<<2));
1084 	inner_ip = (struct ip *) (((u_char *)icp)+8);
1085 
1086 	if (inner_ip->ip_tos != last_tos)
1087 		printf (" (TOS=%d!)", inner_ip->ip_tos);
1088 
1089 	last_tos = inner_ip->ip_tos;
1090 }
1091 
1092 int
1093 wait_for_reply(int sock, struct msghdr *mhdr)
1094 {
1095 	struct pollfd pfd[1];
1096 	int cc = 0;
1097 
1098 	pfd[0].fd = sock;
1099 	pfd[0].events = POLLIN;
1100 	pfd[0].revents = 0;
1101 
1102 	if (poll(pfd, 1, waittime * 1000) > 0)
1103 		cc = recvmsg(rcvsock, mhdr, 0);
1104 
1105 	return (cc);
1106 }
1107 
1108 void
1109 dump_packet(void)
1110 {
1111 	u_char *p;
1112 	int i;
1113 
1114 	fprintf(stderr, "packet data:");
1115 	for (p = outpacket, i = 0; i < datalen; i++) {
1116 		if ((i % 24) == 0)
1117 			fprintf(stderr, "\n ");
1118 		fprintf(stderr, " %02x", *p++);
1119 	}
1120 	fprintf(stderr, "\n");
1121 }
1122 
1123 void
1124 build_probe4(int seq, u_int8_t ttl, int iflag)
1125 {
1126 	struct ip *ip = (struct ip *)outpacket;
1127 	u_char *p = (u_char *)(ip + 1);
1128 	struct udphdr *up = (struct udphdr *)(p + lsrrlen);
1129 	struct icmp *icmpp = (struct icmp *)(p + lsrrlen);
1130 	struct packetdata *op;
1131 	struct timeval tv;
1132 
1133 	ip->ip_len = htons(datalen);
1134 	ip->ip_ttl = ttl;
1135 	ip->ip_id = htons(ident+seq);
1136 
1137 	switch (proto) {
1138 	case IPPROTO_ICMP:
1139 		icmpp->icmp_type = icmp_type;
1140 		icmpp->icmp_code = ICMP_CODE;
1141 		icmpp->icmp_seq = htons(seq);
1142 		icmpp->icmp_id = htons(ident);
1143 		op = (struct packetdata *)(icmpp + 1);
1144 		break;
1145 	case IPPROTO_UDP:
1146 		up->uh_sport = htons(ident);
1147 		if (iflag)
1148 			up->uh_dport = htons(port+seq);
1149 		else
1150 			up->uh_dport = htons(port);
1151 		up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
1152 		    lsrrlen));
1153 		up->uh_sum = 0;
1154 		op = (struct packetdata *)(up + 1);
1155 		break;
1156 	default:
1157 		op = (struct packetdata *)(ip + 1);
1158 		break;
1159 	}
1160 	op->seq = seq;
1161 	op->ttl = ttl;
1162 	(void) gettimeofday(&tv, NULL);
1163 
1164 	/*
1165 	 * We don't want hostiles snooping the net to get any useful
1166 	 * information about us. Send the timestamp in network byte order,
1167 	 * and perturb the timestamp enough that they won't know our
1168 	 * real clock ticker. We don't want to perturb the time by too
1169 	 * much: being off by a suspiciously large amount might indicate
1170 	 * OpenBSD.
1171 	 *
1172 	 * The timestamps in the packet are currently unused. If future
1173 	 * work wants to use them they will have to subtract out the
1174 	 * perturbation first.
1175 	 */
1176 	(void) gettimeofday(&tv, NULL);
1177 	op->sec = htonl(tv.tv_sec + sec_perturb);
1178 	op->usec = htonl((tv.tv_usec + usec_perturb) % 1000000);
1179 
1180 	if (proto == IPPROTO_ICMP && icmp_type == ICMP_ECHO) {
1181 		icmpp->icmp_cksum = 0;
1182 		icmpp->icmp_cksum = in_cksum((u_short *)icmpp,
1183 		    datalen - sizeof(struct ip) - lsrrlen);
1184 		if (icmpp->icmp_cksum == 0)
1185 			icmpp->icmp_cksum = 0xffff;
1186 	}
1187 }
1188 
1189 void
1190 build_probe6(int seq, u_int8_t hops, int iflag, struct sockaddr *to)
1191 {
1192 	struct timeval tv;
1193 	struct packetdata *op;
1194 	int i;
1195 
1196 	i = hops;
1197 	if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1198 	    (char *)&i, sizeof(i)) < 0)
1199 		warn("setsockopt IPV6_UNICAST_HOPS");
1200 
1201 	if (iflag)
1202 		((struct sockaddr_in6*)to)->sin6_port = htons(port + seq);
1203 	else
1204 		((struct sockaddr_in6*)to)->sin6_port = htons(port);
1205 	(void) gettimeofday(&tv, NULL);
1206 
1207 	if (proto == IPPROTO_ICMP) {
1208 		struct icmp6_hdr *icp = (struct icmp6_hdr *)outpacket;
1209 
1210 		icp->icmp6_type = ICMP6_ECHO_REQUEST;
1211 		icp->icmp6_code = 0;
1212 		icp->icmp6_cksum = 0;
1213 		icp->icmp6_id = ident;
1214 		icp->icmp6_seq = htons(seq);
1215 		op = (struct packetdata *)(outpacket +
1216 		    sizeof(struct icmp6_hdr));
1217 	} else
1218 		op = (struct packetdata *)outpacket;
1219 	op->seq = seq;
1220 	op->ttl = hops;
1221 	op->sec = htonl(tv.tv_sec);
1222 	op->usec = htonl(tv.tv_usec);
1223 }
1224 
1225 void
1226 send_probe(int seq, u_int8_t ttl, int iflag, struct sockaddr *to)
1227 {
1228 	int i;
1229 
1230 	switch (to->sa_family) {
1231 	case AF_INET:
1232 		build_probe4(seq, ttl, iflag);
1233 		break;
1234 	case AF_INET6:
1235 		build_probe6(seq, ttl, iflag, to);
1236 		break;
1237 	default:
1238 		errx(1, "unsupported AF: %d", to->sa_family);
1239 		break;
1240 	}
1241 
1242 	if (dump)
1243 		dump_packet();
1244 
1245 	i = sendto(sndsock, outpacket, datalen, 0, to, to->sa_len);
1246 	if (i < 0 || i != datalen)  {
1247 		if (i < 0)
1248 			warn("sendto");
1249 		printf("%s: wrote %s %d chars, ret=%d\n", __progname, hostname,
1250 		    datalen, i);
1251 		(void) fflush(stdout);
1252 	}
1253 }
1254 
1255 double
1256 deltaT(struct timeval *t1p, struct timeval *t2p)
1257 {
1258 	double dt;
1259 
1260 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1261 	    (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1262 	return (dt);
1263 }
1264 
1265 static char *ttab[] = {
1266 	"Echo Reply",
1267 	"ICMP 1",
1268 	"ICMP 2",
1269 	"Dest Unreachable",
1270 	"Source Quench",
1271 	"Redirect",
1272 	"ICMP 6",
1273 	"ICMP 7",
1274 	"Echo",
1275 	"Router Advert",
1276 	"Router Solicit",
1277 	"Time Exceeded",
1278 	"Param Problem",
1279 	"Timestamp",
1280 	"Timestamp Reply",
1281 	"Info Request",
1282 	"Info Reply",
1283 	"Mask Request",
1284 	"Mask Reply"
1285 };
1286 
1287 /*
1288  * Convert an ICMP "type" field to a printable string.
1289  */
1290 char *
1291 pr_type(u_int8_t t)
1292 {
1293 	if (t > 18)
1294 		return ("OUT-OF-RANGE");
1295 	return (ttab[t]);
1296 }
1297 
1298 int
1299 packet_ok(int af, struct msghdr *mhdr, int cc, int seq, int iflag)
1300 {
1301 	switch (af) {
1302 	case AF_INET:
1303 		return packet_ok4(mhdr, cc, seq, iflag);
1304 		break;
1305 	case AF_INET6:
1306 		return packet_ok6(mhdr, cc, seq, iflag);
1307 		break;
1308 	default:
1309 		errx(1, "unsupported AF: %d", af);
1310 		break;
1311 	}
1312 }
1313 
1314 int
1315 packet_ok4(struct msghdr *mhdr, int cc,int seq, int iflag)
1316 {
1317 	struct sockaddr_in *from = (struct sockaddr_in *)mhdr->msg_name;
1318 	struct icmp *icp;
1319 	u_char code;
1320 	char *buf = (char *)mhdr->msg_iov[0].iov_base;
1321 	u_int8_t type;
1322 	int hlen;
1323 	struct ip *ip;
1324 
1325 	ip = (struct ip *) buf;
1326 	hlen = ip->ip_hl << 2;
1327 	if (cc < hlen + ICMP_MINLEN) {
1328 		if (verbose)
1329 			printf("packet too short (%d bytes) from %s\n", cc,
1330 			    inet_ntoa(from->sin_addr));
1331 		return (0);
1332 	}
1333 	cc -= hlen;
1334 	icp = (struct icmp *)(buf + hlen);
1335 	type = icp->icmp_type;
1336 	code = icp->icmp_code;
1337 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1338 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1339 		struct ip *hip;
1340 		struct udphdr *up;
1341 		struct icmp *icmpp;
1342 
1343 		hip = &icp->icmp_ip;
1344 		hlen = hip->ip_hl << 2;
1345 
1346 		switch (proto) {
1347 		case IPPROTO_ICMP:
1348 			if (icmp_type == ICMP_ECHO &&
1349 			    type == ICMP_ECHOREPLY &&
1350 			    icp->icmp_id == htons(ident) &&
1351 			    icp->icmp_seq == htons(seq))
1352 				return (-2); /* we got there */
1353 
1354 			icmpp = (struct icmp *)((u_char *)hip + hlen);
1355 			if (hlen + 8 <= cc && hip->ip_p == IPPROTO_ICMP &&
1356 			    icmpp->icmp_id == htons(ident) &&
1357 			    icmpp->icmp_seq == htons(seq))
1358 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1359 			break;
1360 
1361 		case IPPROTO_UDP:
1362 			up = (struct udphdr *)((u_char *)hip + hlen);
1363 			if (hlen + 12 <= cc && hip->ip_p == proto &&
1364 			    up->uh_sport == htons(ident) &&
1365 			    ((iflag && up->uh_dport == htons(port + seq)) ||
1366 			    (!iflag && up->uh_dport == htons(port))))
1367 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1368 			break;
1369 		default:
1370 			/* this is some odd, user specified proto,
1371 			 * how do we check it?
1372 			 */
1373 			if (hip->ip_p == proto)
1374 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1375 		}
1376 	}
1377 	if (verbose) {
1378 		int i;
1379 		in_addr_t *lp = (in_addr_t *)&icp->icmp_ip;
1380 
1381 		printf("\n%d bytes from %s", cc, inet_ntoa(from->sin_addr));
1382 		printf(" to %s", inet_ntoa(ip->ip_dst));
1383 		printf(": icmp type %u (%s) code %d\n", type, pr_type(type),
1384 		    icp->icmp_code);
1385 		for (i = 4; i < cc ; i += sizeof(in_addr_t))
1386 			printf("%2d: x%8.8lx\n", i, (unsigned long)*lp++);
1387 	}
1388 	return (0);
1389 }
1390 
1391 int
1392 packet_ok6(struct msghdr *mhdr, int cc, int seq, int iflag)
1393 {
1394 	struct icmp6_hdr *icp;
1395 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1396 	u_char type, code;
1397 	char *buf = (char *)mhdr->msg_iov[0].iov_base;
1398 	struct cmsghdr *cm;
1399 	int *hlimp;
1400 	char hbuf[NI_MAXHOST];
1401 	int useicmp = (proto == IPPROTO_ICMP);
1402 
1403 	if (cc < sizeof(struct icmp6_hdr)) {
1404 		if (verbose) {
1405 			if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1406 			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1407 				strlcpy(hbuf, "invalid", sizeof(hbuf));
1408 			printf("data too short (%d bytes) from %s\n", cc, hbuf);
1409 		}
1410 		return(0);
1411 	}
1412 	icp = (struct icmp6_hdr *)buf;
1413 	/* get optional information via advanced API */
1414 	rcvpktinfo = NULL;
1415 	hlimp = NULL;
1416 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1417 	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1418 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1419 		    cm->cmsg_type == IPV6_PKTINFO &&
1420 		    cm->cmsg_len ==
1421 		    CMSG_LEN(sizeof(struct in6_pktinfo)))
1422 			rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1423 
1424 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1425 		    cm->cmsg_type == IPV6_HOPLIMIT &&
1426 		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1427 			hlimp = (int *)CMSG_DATA(cm);
1428 	}
1429 	if (rcvpktinfo == NULL || hlimp == NULL) {
1430 		warnx("failed to get received hop limit or packet info");
1431 		rcvhlim = 0;	/*XXX*/
1432 	} else
1433 		rcvhlim = *hlimp;
1434 
1435 	type = icp->icmp6_type;
1436 	code = icp->icmp6_code;
1437 	if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT)
1438 	    || type == ICMP6_DST_UNREACH) {
1439 		struct ip6_hdr *hip;
1440 		struct udphdr *up;
1441 
1442 		hip = (struct ip6_hdr *)(icp + 1);
1443 		if ((up = get_udphdr(hip, (u_char *)(buf + cc))) == NULL) {
1444 			if (verbose)
1445 				warnx("failed to get upper layer header");
1446 			return(0);
1447 		}
1448 		if (useicmp &&
1449 		    ((struct icmp6_hdr *)up)->icmp6_id == ident &&
1450 		    ((struct icmp6_hdr *)up)->icmp6_seq == htons(seq))
1451 			return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1);
1452 		else if (!useicmp &&
1453 		    up->uh_sport == htons(srcport) &&
1454 		    ((iflag && up->uh_dport == htons(port + seq)) ||
1455 		    (!iflag && up->uh_dport == htons(port))))
1456 			return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1);
1457 	} else if (useicmp && type == ICMP6_ECHO_REPLY) {
1458 		if (icp->icmp6_id == ident &&
1459 		    icp->icmp6_seq == htons(seq))
1460 			return (ICMP6_DST_UNREACH_NOPORT + 1);
1461 	}
1462 	if (verbose) {
1463 		char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1464 		u_int8_t *p;
1465 		int i;
1466 
1467 		if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1468 		    sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1469 			strlcpy(sbuf, "invalid", sizeof(sbuf));
1470 		printf("\n%d bytes from %s to %s", cc, sbuf,
1471 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1472 		    dbuf, sizeof(dbuf)) : "?");
1473 		printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
1474 		    icp->icmp6_code);
1475 		p = (u_int8_t *)(icp + 1);
1476 #define WIDTH	16
1477 		for (i = 0; i < cc; i++) {
1478 			if (i % WIDTH == 0)
1479 				printf("%04x:", i);
1480 			if (i % 4 == 0)
1481 				printf(" ");
1482 			printf("%02x", p[i]);
1483 			if (i % WIDTH == WIDTH - 1)
1484 				printf("\n");
1485 		}
1486 		if (cc % WIDTH != 0)
1487 			printf("\n");
1488 	}
1489 	return(0);
1490 }
1491 
1492 void
1493 print(struct sockaddr *from, int cc, const char *to)
1494 {
1495 	char hbuf[NI_MAXHOST];
1496 	if (getnameinfo(from, from->sa_len,
1497 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1498 		strlcpy(hbuf, "invalid", sizeof(hbuf));
1499 	if (nflag)
1500 		printf(" %s", hbuf);
1501 	else
1502 		printf(" %s (%s)", inetname(from), hbuf);
1503 
1504 	if (Aflag)
1505 		print_asn((struct sockaddr_storage *)from);
1506 
1507 	if (verbose)
1508 		printf(" %d bytes to %s", cc, to);
1509 }
1510 
1511 /*
1512  * Increment pointer until find the UDP or ICMP header.
1513  */
1514 struct udphdr *
1515 get_udphdr(struct ip6_hdr *ip6, u_char *lim)
1516 {
1517 	u_char *cp = (u_char *)ip6, nh;
1518 	int hlen;
1519 	int useicmp = (proto == IPPROTO_ICMP);
1520 
1521 	if (cp + sizeof(*ip6) >= lim)
1522 		return(NULL);
1523 
1524 	nh = ip6->ip6_nxt;
1525 	cp += sizeof(struct ip6_hdr);
1526 
1527 	while (lim - cp >= 8) {
1528 		switch (nh) {
1529 		case IPPROTO_ESP:
1530 		case IPPROTO_TCP:
1531 			return(NULL);
1532 		case IPPROTO_ICMPV6:
1533 			return(useicmp ? (struct udphdr *)cp : NULL);
1534 		case IPPROTO_UDP:
1535 			return(useicmp ? NULL : (struct udphdr *)cp);
1536 		case IPPROTO_FRAGMENT:
1537 			hlen = sizeof(struct ip6_frag);
1538 			nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1539 			break;
1540 		case IPPROTO_AH:
1541 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1542 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1543 			break;
1544 		default:
1545 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1546 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1547 			break;
1548 		}
1549 
1550 		cp += hlen;
1551 	}
1552 
1553 	return(NULL);
1554 }
1555 
1556 void
1557 icmp_code(int af, int code, int *got_there, int *unreachable)
1558 {
1559 	switch (af) {
1560 	case AF_INET:
1561 		icmp4_code(code, got_there, unreachable);
1562 		break;
1563 	case AF_INET6:
1564 		icmp6_code(code, got_there, unreachable);
1565 		break;
1566 	default:
1567 		errx(1, "unsupported AF: %d", af);
1568 		break;
1569 	}
1570 }
1571 
1572 void
1573 icmp4_code(int code, int *got_there, int *unreachable)
1574 {
1575 	struct ip *ip = (struct ip *)packet;
1576 
1577 	switch (code) {
1578 	case ICMP_UNREACH_PORT:
1579 		if (ip->ip_ttl <= 1)
1580 			printf(" !");
1581 		++(*got_there);
1582 		break;
1583 	case ICMP_UNREACH_NET:
1584 		++(*unreachable);
1585 		printf(" !N");
1586 		break;
1587 	case ICMP_UNREACH_HOST:
1588 		++(*unreachable);
1589 		printf(" !H");
1590 		break;
1591 	case ICMP_UNREACH_PROTOCOL:
1592 		++(*got_there);
1593 		printf(" !P");
1594 		break;
1595 	case ICMP_UNREACH_NEEDFRAG:
1596 		++(*unreachable);
1597 		printf(" !F");
1598 		break;
1599 	case ICMP_UNREACH_SRCFAIL:
1600 		++(*unreachable);
1601 		printf(" !S");
1602 		break;
1603 	case ICMP_UNREACH_FILTER_PROHIB:
1604 		++(*unreachable);
1605 		printf(" !X");
1606 		break;
1607 	case ICMP_UNREACH_NET_PROHIB: /*misuse*/
1608 		++(*unreachable);
1609 		printf(" !A");
1610 		break;
1611 	case ICMP_UNREACH_HOST_PROHIB:
1612 		++(*unreachable);
1613 		printf(" !C");
1614 		break;
1615 	case ICMP_UNREACH_NET_UNKNOWN:
1616 	case ICMP_UNREACH_HOST_UNKNOWN:
1617 		++(*unreachable);
1618 		printf(" !U");
1619 		break;
1620 	case ICMP_UNREACH_ISOLATED:
1621 		++(*unreachable);
1622 		printf(" !I");
1623 		break;
1624 	case ICMP_UNREACH_TOSNET:
1625 	case ICMP_UNREACH_TOSHOST:
1626 		++(*unreachable);
1627 		printf(" !T");
1628 		break;
1629 	default:
1630 		++(*unreachable);
1631 		printf(" !<%d>", code);
1632 		break;
1633 	}
1634 }
1635 
1636 void
1637 icmp6_code(int code, int *got_there, int *unreachable)
1638 {
1639 	switch (code) {
1640 	case ICMP6_DST_UNREACH_NOROUTE:
1641 		++(*unreachable);
1642 		printf(" !N");
1643 		break;
1644 	case ICMP6_DST_UNREACH_ADMIN:
1645 		++(*unreachable);
1646 		printf(" !P");
1647 		break;
1648 	case ICMP6_DST_UNREACH_NOTNEIGHBOR:
1649 		++(*unreachable);
1650 		printf(" !S");
1651 		break;
1652 	case ICMP6_DST_UNREACH_ADDR:
1653 		++(*unreachable);
1654 		printf(" !A");
1655 		break;
1656 	case ICMP6_DST_UNREACH_NOPORT:
1657 		if (rcvhlim >= 0 && rcvhlim <= 1)
1658 			printf(" !");
1659 		++(*got_there);
1660 		break;
1661 	default:
1662 		++(*unreachable);
1663 		printf(" !<%d>", code);
1664 		break;
1665 	}
1666 }
1667 
1668 /*
1669  * Checksum routine for Internet Protocol family headers (C Version)
1670  */
1671 u_short
1672 in_cksum(u_short *addr, int len)
1673 {
1674 	u_short *w = addr, answer;
1675 	int nleft = len, sum = 0;
1676 
1677 	/*
1678 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1679 	 *  we add sequential 16 bit words to it, and at the end, fold
1680 	 *  back all the carry bits from the top 16 bits into the lower
1681 	 *  16 bits.
1682 	 */
1683 	while (nleft > 1)  {
1684 		sum += *w++;
1685 		nleft -= 2;
1686 	}
1687 
1688 	/* mop up an odd byte, if necessary */
1689 	if (nleft == 1)
1690 		sum += *(u_char *)w;
1691 
1692 	/*
1693 	 * add back carry outs from top 16 bits to low 16 bits
1694 	 */
1695 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1696 	sum += (sum >> 16);			/* add carry */
1697 	answer = ~sum;				/* truncate to 16 bits */
1698 	return (answer);
1699 }
1700 
1701 /*
1702  * Construct an Internet address representation.
1703  */
1704 const char *
1705 inetname(struct sockaddr *sa)
1706 {
1707 	static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1708 	static int first = 1;
1709 	char *cp;
1710 
1711 	if (first) {
1712 		first = 0;
1713 		if (gethostname(domain, sizeof(domain)) == 0 &&
1714 		    (cp = strchr(domain, '.')) != NULL)
1715 			(void) strlcpy(domain, cp + 1, sizeof(domain));
1716 		else
1717 			domain[0] = 0;
1718 	}
1719 	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1720 	    NI_NAMEREQD) == 0) {
1721 		if ((cp = strchr(line, '.')) != NULL && strcmp(cp + 1,
1722 		    domain) == 0)
1723 			*cp = '\0';
1724 		return (line);
1725 	}
1726 
1727 	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1728 	    NI_NUMERICHOST) != 0)
1729 		return ("invalid");
1730 	return (line);
1731 }
1732 
1733 void
1734 print_asn(struct sockaddr_storage *ss)
1735 {
1736 	struct rrsetinfo *answers = NULL;
1737 	int counter;
1738 	const u_char *uaddr;
1739 	char qbuf[MAXDNAME];
1740 
1741 	switch (ss->ss_family) {
1742 	case AF_INET:
1743 		uaddr = (const u_char *)&((struct sockaddr_in *) ss)->sin_addr;
1744 		if (snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u."
1745 		    "origin.asn.cymru.com",
1746 		    (uaddr[3] & 0xff), (uaddr[2] & 0xff),
1747 		    (uaddr[1] & 0xff), (uaddr[0] & 0xff)) >= sizeof (qbuf))
1748 			return;
1749 		break;
1750 	case AF_INET6:
1751 		uaddr = (const u_char *)&((struct sockaddr_in6 *) ss)->sin6_addr;
1752 		if (snprintf(qbuf, sizeof qbuf,
1753 		    "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
1754 		    "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
1755 		    "origin6.asn.cymru.com",
1756 		    (uaddr[15] & 0x0f), ((uaddr[15] >>4)& 0x0f),
1757 		    (uaddr[14] & 0x0f), ((uaddr[14] >>4)& 0x0f),
1758 		    (uaddr[13] & 0x0f), ((uaddr[13] >>4)& 0x0f),
1759 		    (uaddr[12] & 0x0f), ((uaddr[12] >>4)& 0x0f),
1760 		    (uaddr[11] & 0x0f), ((uaddr[11] >>4)& 0x0f),
1761 		    (uaddr[10] & 0x0f), ((uaddr[10] >>4)& 0x0f),
1762 		    (uaddr[9] & 0x0f), ((uaddr[9] >>4)& 0x0f),
1763 		    (uaddr[8] & 0x0f), ((uaddr[8] >>4)& 0x0f),
1764 		    (uaddr[7] & 0x0f), ((uaddr[7] >>4)& 0x0f),
1765 		    (uaddr[6] & 0x0f), ((uaddr[6] >>4)& 0x0f),
1766 		    (uaddr[5] & 0x0f), ((uaddr[5] >>4)& 0x0f),
1767 		    (uaddr[4] & 0x0f), ((uaddr[4] >>4)& 0x0f),
1768 		    (uaddr[3] & 0x0f), ((uaddr[3] >>4)& 0x0f),
1769 		    (uaddr[2] & 0x0f), ((uaddr[2] >>4)& 0x0f),
1770 		    (uaddr[1] & 0x0f), ((uaddr[1] >>4)& 0x0f),
1771 		    (uaddr[0] & 0x0f), ((uaddr[0] >>4)& 0x0f)) >= sizeof (qbuf))
1772 			return;
1773 		break;
1774 	default:
1775 		return;
1776 	}
1777 
1778 	if (getrrsetbyname(qbuf, C_IN, T_TXT, 0, &answers) != 0)
1779 		return;
1780 	for (counter = 0; counter < answers->rri_nrdatas; counter++) {
1781 		char *p, *as = answers->rri_rdatas[counter].rdi_data;
1782 		as++; /* skip first byte, it contains length */
1783 		if ((p = strchr(as,'|'))) {
1784 			printf(counter ? ", " : " [");
1785 			p[-1] = 0;
1786 			printf("AS%s", as);
1787 		}
1788 	}
1789 	if (counter)
1790 		printf("]");
1791 
1792 	freerrset(answers);
1793 }
1794 
1795 int
1796 map_tos(char *s, int *val)
1797 {
1798 	/* DiffServ Codepoints and other TOS mappings */
1799 	const struct toskeywords {
1800 		const char	*keyword;
1801 		int		 val;
1802 	} *t, toskeywords[] = {
1803 		{ "af11",		IPTOS_DSCP_AF11 },
1804 		{ "af12",		IPTOS_DSCP_AF12 },
1805 		{ "af13",		IPTOS_DSCP_AF13 },
1806 		{ "af21",		IPTOS_DSCP_AF21 },
1807 		{ "af22",		IPTOS_DSCP_AF22 },
1808 		{ "af23",		IPTOS_DSCP_AF23 },
1809 		{ "af31",		IPTOS_DSCP_AF31 },
1810 		{ "af32",		IPTOS_DSCP_AF32 },
1811 		{ "af33",		IPTOS_DSCP_AF33 },
1812 		{ "af41",		IPTOS_DSCP_AF41 },
1813 		{ "af42",		IPTOS_DSCP_AF42 },
1814 		{ "af43",		IPTOS_DSCP_AF43 },
1815 		{ "critical",		IPTOS_PREC_CRITIC_ECP },
1816 		{ "cs0",		IPTOS_DSCP_CS0 },
1817 		{ "cs1",		IPTOS_DSCP_CS1 },
1818 		{ "cs2",		IPTOS_DSCP_CS2 },
1819 		{ "cs3",		IPTOS_DSCP_CS3 },
1820 		{ "cs4",		IPTOS_DSCP_CS4 },
1821 		{ "cs5",		IPTOS_DSCP_CS5 },
1822 		{ "cs6",		IPTOS_DSCP_CS6 },
1823 		{ "cs7",		IPTOS_DSCP_CS7 },
1824 		{ "ef",			IPTOS_DSCP_EF },
1825 		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
1826 		{ "lowdelay",		IPTOS_LOWDELAY },
1827 		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
1828 		{ "reliability",	IPTOS_RELIABILITY },
1829 		{ "throughput",		IPTOS_THROUGHPUT },
1830 		{ NULL,			-1 },
1831 	};
1832 
1833 	for (t = toskeywords; t->keyword != NULL; t++) {
1834 		if (strcmp(s, t->keyword) == 0) {
1835 			*val = t->val;
1836 			return (1);
1837 		}
1838 	}
1839 
1840 	return (0);
1841 }
1842 
1843 void
1844 usage(void)
1845 {
1846 	if (v6flag) {
1847 		fprintf(stderr, "usage: traceroute6 [-AcDdIlnSv] [-f first_hop] "
1848 		    "[-m max_hop] [-p port]\n"
1849 		    "\t[-q nqueries] [-s src_addr] [-V rtable] [-w waittime] "
1850 		    "host\n\t[datalen]\n");
1851 	} else {
1852 		fprintf(stderr,
1853 		    "usage: %s [-AcDdIlnSvx] [-f first_ttl] [-g gateway_addr] "
1854 		    "[-m max_ttl]\n"
1855 		    "\t[-P proto] [-p port] [-q nqueries] [-s src_addr]\n"
1856 		    "\t[-t toskeyword] "
1857 		    "[-V rtable] [-w waittime] host [datalen]\n",
1858 		    __progname);
1859 	}
1860 	exit(1);
1861 }
1862