xref: /openbsd/usr.sbin/traceroute/traceroute.c (revision 91f110e0)
1 /*	$OpenBSD: traceroute.c,v 1.95 2014/03/24 11:11:49 mpi Exp $	*/
2 /*	$NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $	*/
3 
4 /*-
5  * Copyright (c) 1990, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Van Jacobson.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 /*
37  * traceroute host  - trace the route ip packets follow going to "host".
38  *
39  * Attempt to trace the route an ip packet would follow to some
40  * internet host.  We find out intermediate hops by launching probe
41  * packets with a small ttl (time to live) then listening for an
42  * icmp "time exceeded" reply from a gateway.  We start our probes
43  * with a ttl of one and increase by one until we get an icmp "port
44  * unreachable" (which means we got to "host") or hit a max (which
45  * defaults to 64 hops & can be changed with the -m flag).  Three
46  * probes (change with -q flag) are sent at each ttl setting and a
47  * line is printed showing the ttl, address of the gateway and
48  * round trip time of each probe.  If the probe answers come from
49  * different gateways, the address of each responding system will
50  * be printed.  If there is no response within a 5 sec. timeout
51  * interval (changed with the -w flag), a "*" is printed for that
52  * probe.
53  *
54  * Probe packets are UDP format.  We don't want the destination
55  * host to process them so the destination port is set to an
56  * unlikely value (if some clod on the destination is using that
57  * value, it can be changed with the -p flag).
58  *
59  * A sample use might be:
60  *
61  *     [yak 71]% traceroute nis.nsf.net.
62  *     traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
63  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
64  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
65  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
66  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
67  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
68  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
69  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
70  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
71  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
72  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
73  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
74  *
75  * Note that lines 2 & 3 are the same.  This is due to a buggy
76  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
77  * packets with a zero ttl.
78  *
79  * A more interesting example is:
80  *
81  *     [yak 72]% traceroute allspice.lcs.mit.edu.
82  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
83  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
84  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
85  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
86  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
87  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
88  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
89  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
90  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
91  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
92  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
93  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
94  *     12  * * *
95  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
96  *     14  * * *
97  *     15  * * *
98  *     16  * * *
99  *     17  * * *
100  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
101  *
102  * (I start to see why I'm having so much trouble with mail to
103  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
104  * either don't send ICMP "time exceeded" messages or send them
105  * with a ttl too small to reach us.  14 - 17 are running the
106  * MIT C Gateway code that doesn't send "time exceeded"s.  God
107  * only knows what's going on with 12.
108  *
109  * The silent gateway 12 in the above may be the result of a bug in
110  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
111  * sends an unreachable message using whatever ttl remains in the
112  * original datagram.  Since, for gateways, the remaining ttl is
113  * zero, the icmp "time exceeded" is guaranteed to not make it back
114  * to us.  The behavior of this bug is slightly more interesting
115  * when it appears on the destination system:
116  *
117  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
118  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
119  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
120  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
121  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
122  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
123  *      7  * * *
124  *      8  * * *
125  *      9  * * *
126  *     10  * * *
127  *     11  * * *
128  *     12  * * *
129  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
130  *
131  * Notice that there are 12 "gateways" (13 is the final
132  * destination) and exactly the last half of them are "missing".
133  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
134  * is using the ttl from our arriving datagram as the ttl in its
135  * icmp reply.  So, the reply will time out on the return path
136  * (with no notice sent to anyone since icmp's aren't sent for
137  * icmp's) until we probe with a ttl that's at least twice the path
138  * length.  I.e., rip is really only 7 hops away.  A reply that
139  * returns with a ttl of 1 is a clue this problem exists.
140  * Traceroute prints a "!" after the time if the ttl is <= 1.
141  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
142  * non-standard (HPUX) software, expect to see this problem
143  * frequently and/or take care picking the target host of your
144  * probes.
145  *
146  * Other possible annotations after the time are !H, !N, !P (got a host,
147  * network or protocol unreachable, respectively), !S or !F (source
148  * route failed or fragmentation needed -- neither of these should
149  * ever occur and the associated gateway is busted if you see one).  If
150  * almost all the probes result in some kind of unreachable, traceroute
151  * will give up and exit.
152  *
153  * Notes
154  * -----
155  * This program must be run by root or be setuid.  (I suggest that
156  * you *don't* make it setuid -- casual use could result in a lot
157  * of unnecessary traffic on our poor, congested nets.)
158  *
159  * This program requires a kernel mod that does not appear in any
160  * system available from Berkeley:  A raw ip socket using proto
161  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
162  * opposed to data to be wrapped in a ip datagram).  See the README
163  * file that came with the source to this program for a description
164  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
165  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
166  * MODIFIED TO RUN THIS PROGRAM.
167  *
168  * The udp port usage may appear bizarre (well, ok, it is bizarre).
169  * The problem is that an icmp message only contains 8 bytes of
170  * data from the original datagram.  8 bytes is the size of a udp
171  * header so, if we want to associate replies with the original
172  * datagram, the necessary information must be encoded into the
173  * udp header (the ip id could be used but there's no way to
174  * interlock with the kernel's assignment of ip id's and, anyway,
175  * it would have taken a lot more kernel hacking to allow this
176  * code to set the ip id).  So, to allow two or more users to
177  * use traceroute simultaneously, we use this task's pid as the
178  * source port (the high bit is set to move the port number out
179  * of the "likely" range).  To keep track of which probe is being
180  * replied to (so times and/or hop counts don't get confused by a
181  * reply that was delayed in transit), we increment the destination
182  * port number before each probe.
183  *
184  * Don't use this as a coding example.  I was trying to find a
185  * routing problem and this code sort-of popped out after 48 hours
186  * without sleep.  I was amazed it ever compiled, much less ran.
187  *
188  * I stole the idea for this program from Steve Deering.  Since
189  * the first release, I've learned that had I attended the right
190  * IETF working group meetings, I also could have stolen it from Guy
191  * Almes or Matt Mathis.  I don't know (or care) who came up with
192  * the idea first.  I envy the originators' perspicacity and I'm
193  * glad they didn't keep the idea a secret.
194  *
195  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
196  * enhancements to the original distribution.
197  *
198  * I've hacked up a round-trip-route version of this that works by
199  * sending a loose-source-routed udp datagram through the destination
200  * back to yourself.  Unfortunately, SO many gateways botch source
201  * routing, the thing is almost worthless.  Maybe one day...
202  *
203  *  -- Van Jacobson (van@helios.ee.lbl.gov)
204  *     Tue Dec 20 03:50:13 PST 1988
205  */
206 
207 #include <sys/param.h>
208 #include <sys/time.h>
209 #include <sys/socket.h>
210 #include <sys/file.h>
211 #include <sys/ioctl.h>
212 #include <sys/sysctl.h>
213 
214 #include <netinet/in_systm.h>
215 #include <netinet/in.h>
216 #include <netinet/ip.h>
217 #include <netinet/ip_icmp.h>
218 #include <netinet/ip_var.h>
219 #include <netinet/udp.h>
220 
221 #include <arpa/inet.h>
222 #include <arpa/nameser.h>
223 
224 #include <netmpls/mpls.h>
225 
226 #include <ctype.h>
227 #include <err.h>
228 #include <errno.h>
229 #include <netdb.h>
230 #include <stdio.h>
231 #include <stdlib.h>
232 #include <string.h>
233 #include <unistd.h>
234 
235 #define MAX_LSRR		((MAX_IPOPTLEN - 4) / 4)
236 
237 #define MPLS_LABEL(m)		((m & MPLS_LABEL_MASK) >> MPLS_LABEL_OFFSET)
238 #define MPLS_EXP(m)		((m & MPLS_EXP_MASK) >> MPLS_EXP_OFFSET)
239 
240 /*
241  * Format of the data in a (udp) probe packet.
242  */
243 struct packetdata {
244 	u_char seq;		/* sequence number of this packet */
245 	u_int8_t ttl;		/* ttl packet left with */
246 	u_char pad[2];
247 	u_int32_t sec;		/* time packet left */
248 	u_int32_t usec;
249 } __packed;
250 
251 struct in_addr gateway[MAX_LSRR + 1];
252 int lsrrlen = 0;
253 int32_t sec_perturb;
254 int32_t usec_perturb;
255 
256 u_char packet[512], *outpacket;	/* last inbound (icmp) packet */
257 
258 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
259 void dump_packet(void);
260 void send_probe(int, u_int8_t, int, struct sockaddr_in *);
261 int packet_ok(u_char *, int, struct sockaddr_in *, int, int);
262 void dump_packet(void);
263 void print_exthdr(u_char *, int);
264 void print(struct sockaddr *, int, const char *);
265 const char *inetname(struct sockaddr*);
266 void print_asn(struct sockaddr_storage *);
267 u_short in_cksum(u_short *, int);
268 char *pr_type(u_int8_t);
269 int map_tos(char *, int *);
270 void usage(void);
271 
272 int rcvsock;			/* receive (icmp) socket file descriptor */
273 int sndsock;			/* send (udp) socket file descriptor */
274 
275 int datalen;			/* How much data */
276 int headerlen;			/* How long packet's header is */
277 
278 char *source = 0;
279 char *hostname;
280 
281 int nprobes = 3;
282 u_int8_t max_ttl = IPDEFTTL;
283 u_int8_t first_ttl = 1;
284 u_short ident;
285 u_int16_t port = 32768+666;	/* start udp dest port # for probe packets */
286 u_char	proto = IPPROTO_UDP;
287 u_int8_t  icmp_type = ICMP_ECHO; /* default ICMP code/type */
288 u_char  icmp_code = 0;
289 int options;			/* socket options */
290 int verbose;
291 int waittime = 5;		/* time to wait for response (in seconds) */
292 int nflag;			/* print addresses numerically */
293 int dump;
294 int xflag;			/* show ICMP extension header */
295 int tflag;			/* tos flag was set */
296 int Aflag;			/* lookup ASN */
297 
298 int
299 main(int argc, char *argv[])
300 {
301 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
302 	int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
303 	int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0;
304 	int last_tos, tos_returned;
305 	size_t size = sizeof(max_ttl);
306 	struct sockaddr_in from, to;
307 	struct hostent *hp;
308 	u_int32_t tmprnd;
309 	struct ip *ip, *inner_ip;
310 	struct icmp *icp;
311 	u_int8_t ttl;
312 	char *ep, hbuf[NI_MAXHOST];
313 	const char *errstr;
314 	long l;
315 	uid_t uid;
316 	u_int rtableid;
317 
318 	if ((rcvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
319 		err(5, "icmp socket");
320 	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
321 		err(5, "raw socket");
322 
323 	/* revoke privs */
324 	uid = getuid();
325 	if (setresuid(uid, uid, uid) == -1)
326 		err(1, "setresuid");
327 
328 	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
329 	    NULL, 0);
330 
331 	while ((ch = getopt(argc, argv, "AcDdf:g:Ilm:nP:p:q:Ss:t:V:vw:x"))
332 			!= -1)
333 		switch (ch) {
334 		case 'A':
335 			Aflag++;
336 			break;
337 		case 'c':
338 			incflag = 0;
339 			break;
340 		case 'd':
341 			options |= SO_DEBUG;
342 			break;
343 		case 'D':
344 			dump = 1;
345 			break;
346 		case 'f':
347 			errno = 0;
348 			ep = NULL;
349 			l = strtol(optarg, &ep, 10);
350 			if (errno || !*optarg || *ep || l < 1 || l > max_ttl)
351 				errx(1, "min ttl must be 1 to %u.", max_ttl);
352 			first_ttl = (u_int8_t)l;
353 			break;
354 		case 'g':
355 			if (lsrr >= MAX_LSRR)
356 				errx(1, "too many gateways; max %d", MAX_LSRR);
357 			if (inet_aton(optarg, &gateway[lsrr]) == 0) {
358 				hp = gethostbyname(optarg);
359 				if (hp == 0)
360 					errx(1, "unknown host %s", optarg);
361 				memcpy(&gateway[lsrr], hp->h_addr, hp->h_length);
362 			}
363 			if (++lsrr == 1)
364 				lsrrlen = 4;
365 			lsrrlen += 4;
366 			break;
367 		case 'I':
368 			if (protoset)
369 				errx(1, "protocol already set with -P");
370 			protoset = 1;
371 			proto = IPPROTO_ICMP;
372 			break;
373 		case 'l':
374 			ttl_flag++;
375 			break;
376 		case 'm':
377 			errno = 0;
378 			ep = NULL;
379 			l = strtol(optarg, &ep, 10);
380 			if (errno || !*optarg || *ep || l < first_ttl ||
381 			    l > MAXTTL)
382 				errx(1, "max ttl must be %u to %u.", first_ttl,
383 				    MAXTTL);
384 			max_ttl = (u_int8_t)l;
385 			break;
386 		case 'n':
387 			nflag++;
388 			break;
389 		case 'p':
390 			errno = 0;
391 			ep = NULL;
392 			l = strtol(optarg, &ep, 10);
393 			if (errno || !*optarg || *ep || l <= 0 || l >= 65536)
394 				errx(1, "port must be >0, <65536.");
395 			port = (u_int16_t)l;
396 			break;
397 		case 'P':
398 			if (protoset)
399 				errx(1, "protocol already set with -I");
400 			protoset = 1;
401 			errno = 0;
402 			ep = NULL;
403 			l = strtol(optarg, &ep, 10);
404 			if (errno || !*optarg || *ep || l < 1 ||
405 			    l >= IPPROTO_MAX) {
406 				struct protoent *pent;
407 
408 				pent = getprotobyname(optarg);
409 				if (pent)
410 					proto = pent->p_proto;
411 				else
412 					errx(1, "proto must be >=1, or a name.");
413 			} else
414 				proto = (int)l;
415 			break;
416 		case 'q':
417 			errno = 0;
418 			ep = NULL;
419 			l = strtol(optarg, &ep, 10);
420 			if (errno || !*optarg || *ep || l < 1 || l > INT_MAX)
421 				errx(1, "nprobes must be >0.");
422 			nprobes = (int)l;
423 			break;
424 		case 's':
425 			/*
426 			 * set the ip source address of the outbound
427 			 * probe (e.g., on a multi-homed host).
428 			 */
429 			source = optarg;
430 			break;
431 		case 'S':
432 			sump = 1;
433 			break;
434 		case 't':
435 			if (!map_tos(optarg, &tos)) {
436 			errno = 0;
437 				errstr = NULL;
438 				if (strlen(optarg) > 1 && optarg[0] == '0' &&
439 				    optarg[1] == 'x')
440 					tos = (int)strtol(optarg, NULL, 16);
441 				else
442 					tos = (int)strtonum(optarg, 0, 255,
443 					    &errstr);
444 				if (tos < 0 || tos > 255 || errstr || errno)
445 					errx(1, "illegal tos value %s",
446 					    optarg);
447 			}
448 			tflag = 1;
449 			last_tos = tos;
450 			break;
451 		case 'v':
452 			verbose++;
453 			break;
454 		case 'V':
455 			rtableid = (unsigned int)strtonum(optarg, 0,
456 			    RT_TABLEID_MAX, &errstr);
457 			if (errstr)
458 				errx(1, "rtable value is %s: %s",
459 				    errstr, optarg);
460 			if (setsockopt(sndsock, SOL_SOCKET, SO_RTABLE,
461 			    &rtableid, sizeof(rtableid)) == -1)
462 				err(1, "setsockopt SO_RTABLE");
463 			if (setsockopt(rcvsock, SOL_SOCKET, SO_RTABLE,
464 			    &rtableid, sizeof(rtableid)) == -1)
465 				err(1, "setsockopt SO_RTABLE");
466 			break;
467 		case 'w':
468 			errno = 0;
469 			ep = NULL;
470 			l = strtol(optarg, &ep, 10);
471 			if (errno || !*optarg || *ep || l <= 1 || l > INT_MAX)
472 				errx(1, "wait must be >1 sec.");
473 			waittime = (int)l;
474 			break;
475 		case 'x':
476 			xflag = 1;
477 			break;
478 		default:
479 			usage();
480 		}
481 	argc -= optind;
482 	argv += optind;
483 
484 	if (argc < 1 || argc > 2)
485 		usage();
486 
487 	setvbuf(stdout, NULL, _IOLBF, 0);
488 
489 	(void) memset(&to, 0, sizeof(struct sockaddr));
490 	to.sin_family = AF_INET;
491 	if (inet_aton(*argv, &to.sin_addr) != 0)
492 		hostname = *argv;
493 	else {
494 		hp = gethostbyname(*argv);
495 		if (hp == 0)
496 			errx(1, "unknown host %s", *argv);
497 		to.sin_family = hp->h_addrtype;
498 		memcpy(&to.sin_addr, hp->h_addr, hp->h_length);
499 		if ((hostname = strdup(hp->h_name)) == NULL)
500 			err(1, "malloc");
501 		if (hp->h_addr_list[1] != NULL)
502 			warnx("Warning: %s has multiple addresses; using %s",
503 			    hostname, inet_ntoa(to.sin_addr));
504 	}
505 	if (*++argv) {
506 		errno = 0;
507 		ep = NULL;
508 		l = strtol(*argv, &ep, 10);
509 		if (errno || !*argv || *ep || l < 0 || l > INT_MAX)
510 			errx(1, "datalen out of range");
511 		datalen = (int)l;
512 	}
513 
514 	switch (proto) {
515 	case IPPROTO_UDP:
516 		headerlen = (sizeof(struct ip) + lsrrlen +
517 		    sizeof(struct udphdr) + sizeof(struct packetdata));
518 		break;
519 	case IPPROTO_ICMP:
520 		headerlen = (sizeof(struct ip) + lsrrlen +
521 		    sizeof(struct icmp) + sizeof(struct packetdata));
522 		break;
523 	default:
524 		headerlen = (sizeof(struct ip) + lsrrlen +
525 		    sizeof(struct packetdata));
526 	}
527 
528 	if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
529 		errx(1, "packet size must be 0 to %d.",
530 		    IP_MAXPACKET - headerlen);
531 
532 	datalen += headerlen;
533 
534 	if ((outpacket = calloc(1, datalen)) == NULL)
535 		err(1, "calloc");
536 
537 	ip = (struct ip *)outpacket;
538 	if (lsrr != 0) {
539 		u_char *p = (u_char *)(ip + 1);
540 
541 		*p++ = IPOPT_NOP;
542 		*p++ = IPOPT_LSRR;
543 		*p++ = lsrrlen - 1;
544 		*p++ = IPOPT_MINOFF;
545 		gateway[lsrr] = to.sin_addr;
546 		for (i = 1; i <= lsrr; i++) {
547 			memcpy(p, &gateway[i], sizeof(struct in_addr));
548 			p += sizeof(struct in_addr);
549 		}
550 		ip->ip_dst = gateway[0];
551 	} else
552 		ip->ip_dst = to.sin_addr;
553 	ip->ip_off = htons(0);
554 	ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;
555 	ip->ip_p = proto;
556 	ip->ip_v = IPVERSION;
557 	ip->ip_tos = tos;
558 
559 	ident = (getpid() & 0xffff) | 0x8000;
560 	tmprnd = arc4random();
561 	sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :
562 	    (tmprnd & 0x7ff);
563 	usec_perturb = arc4random();
564 
565 	if (options & SO_DEBUG)
566 		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
567 		    (char *)&on, sizeof(on));
568 #ifdef SO_SNDBUF
569 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
570 	    sizeof(datalen)) < 0)
571 		err(6, "SO_SNDBUF");
572 #endif /* SO_SNDBUF */
573 #ifdef IP_HDRINCL
574 	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
575 	    sizeof(on)) < 0)
576 		err(6, "IP_HDRINCL");
577 #endif /* IP_HDRINCL */
578 	if (options & SO_DEBUG)
579 		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
580 		    (char *)&on, sizeof(on));
581 
582 	if (source) {
583 		(void) memset(&from, 0, sizeof(struct sockaddr));
584 		from.sin_family = AF_INET;
585 		if (inet_aton(source, &from.sin_addr) == 0)
586 			errx(1, "unknown host %s", source);
587 		ip->ip_src = from.sin_addr;
588 		if (getuid() != 0 &&
589 		    (ntohl(from.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U &&
590 		    (ntohl(to.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U)
591 			errx(1, "source is on 127/8, destination is not");
592 
593 		if (getuid() &&
594 		    bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
595 			err(1, "bind");
596 	}
597 
598 	fprintf(stderr, "traceroute to %s (%s)", hostname,
599 		inet_ntoa(to.sin_addr));
600 	if (source)
601 		fprintf(stderr, " from %s", source);
602 	fprintf(stderr, ", %u hops max, %d byte packets\n", max_ttl, datalen);
603 	(void) fflush(stderr);
604 
605 	if (first_ttl > 1)
606 		printf("Skipping %u intermediate hops\n", first_ttl - 1);
607 
608 	for (ttl = first_ttl; ttl && ttl <= max_ttl; ++ttl) {
609 		int got_there = 0, unreachable = 0, timeout = 0, loss;
610 		in_addr_t lastaddr = 0;
611 		quad_t dt;
612 
613 		printf("%2u ", ttl);
614 		for (probe = 0, loss = 0; probe < nprobes; ++probe) {
615 			int cc;
616 			struct timeval t1, t2;
617 			int code;
618 
619 			(void) gettimeofday(&t1, NULL);
620 			send_probe(++seq, ttl, incflag, &to);
621 			while ((cc = wait_for_reply(rcvsock, &from, &t1))) {
622 				(void) gettimeofday(&t2, NULL);
623 				if (t2.tv_sec - t1.tv_sec > waittime) {
624 					cc = 0;
625 					break;
626 				}
627 				i = packet_ok(packet, cc, &from, seq, incflag);
628 				/* Skip short packet */
629 				if (i == 0)
630 					continue;
631 				if (from.sin_addr.s_addr != lastaddr) {
632 					print((struct sockaddr *)&from,
633 					    (cc - (((struct ip*)packet)->ip_hl
634 					    <<2)), inet_ntop(AF_INET,
635 					    &((struct ip*)packet)->ip_dst,
636 					    hbuf, sizeof(hbuf)));
637 					lastaddr = from.sin_addr.s_addr;
638 				}
639 				dt = (quad_t)(t2.tv_sec - t1.tv_sec) * 1000000 +
640 				    (quad_t)(t2.tv_usec - t1.tv_usec);
641 				printf("  %u", (u_int)(dt / 1000));
642 				if (dt % 1000)
643 					printf(".%u", (u_int)(dt % 1000));
644 				printf(" ms");
645 				ip = (struct ip *)packet;
646 				if (ttl_flag)
647 					printf(" (%u)", ip->ip_ttl);
648 				if (i == -2) {
649 #ifndef ARCHAIC
650 					ip = (struct ip *)packet;
651 					if (ip->ip_ttl <= 1)
652 						printf(" !");
653 #endif
654 					++got_there;
655 					break;
656 				}
657 
658 				icp = (struct icmp *) (((u_char *)ip)+(ip->ip_hl<<2));
659 				inner_ip = (struct ip *) (((u_char *)icp)+8);
660 
661 				tos_returned = inner_ip->ip_tos;
662 
663 				if (tflag && (tos_returned != last_tos))
664 					printf (" (TOS=%d!)", tos_returned);
665 
666 				last_tos = tos_returned;
667 
668 				/* time exceeded in transit */
669 				if (i == -1)
670 					break;
671 				code = i - 1;
672 				switch (code) {
673 				case ICMP_UNREACH_PORT:
674 #ifndef ARCHAIC
675 					ip = (struct ip *)packet;
676 					if (ip->ip_ttl <= 1)
677 						printf(" !");
678 #endif /* ARCHAIC */
679 					++got_there;
680 					break;
681 				case ICMP_UNREACH_NET:
682 					++unreachable;
683 					printf(" !N");
684 					break;
685 				case ICMP_UNREACH_HOST:
686 					++unreachable;
687 					printf(" !H");
688 					break;
689 				case ICMP_UNREACH_PROTOCOL:
690 					++got_there;
691 					printf(" !P");
692 					break;
693 				case ICMP_UNREACH_NEEDFRAG:
694 					++unreachable;
695 					printf(" !F");
696 					break;
697 				case ICMP_UNREACH_SRCFAIL:
698 					++unreachable;
699 					printf(" !S");
700 					break;
701 				case ICMP_UNREACH_FILTER_PROHIB:
702 					++unreachable;
703 					printf(" !X");
704 					break;
705 				case ICMP_UNREACH_NET_PROHIB: /*misuse*/
706 					++unreachable;
707 					printf(" !A");
708 					break;
709 				case ICMP_UNREACH_HOST_PROHIB:
710 					++unreachable;
711 					printf(" !C");
712 					break;
713 				case ICMP_UNREACH_NET_UNKNOWN:
714 				case ICMP_UNREACH_HOST_UNKNOWN:
715 					++unreachable;
716 					printf(" !U");
717 					break;
718 				case ICMP_UNREACH_ISOLATED:
719 					++unreachable;
720 					printf(" !I");
721 					break;
722 				case ICMP_UNREACH_TOSNET:
723 				case ICMP_UNREACH_TOSHOST:
724 					++unreachable;
725 					printf(" !T");
726 					break;
727 				default:
728 					++unreachable;
729 					printf(" !<%d>", i - 1);
730 					break;
731 				}
732 				break;
733 			}
734 			if (cc == 0) {
735 				printf(" *");
736 				timeout++;
737 				loss++;
738 			} else if (cc && probe == nprobes - 1 &&
739 			    (xflag || verbose))
740 				print_exthdr(packet, cc);
741 			(void) fflush(stdout);
742 		}
743 		if (sump)
744 			printf(" (%d%% loss)", (loss * 100) / nprobes);
745 		putchar('\n');
746 		if (got_there ||
747 		    (unreachable && (unreachable + timeout) >= nprobes))
748 			break;
749 	}
750 	exit(0);
751 }
752 
753 void
754 print_exthdr(u_char *buf, int cc)
755 {
756 	struct icmp_ext_hdr exthdr;
757 	struct icmp_ext_obj_hdr objhdr;
758 	struct ip *ip;
759 	struct icmp *icp;
760 	int hlen, first;
761 	u_int32_t label;
762 	u_int16_t off, olen;
763 	u_int8_t type;
764 
765 	ip = (struct ip *)buf;
766 	hlen = ip->ip_hl << 2;
767 	if (cc < hlen + ICMP_MINLEN)
768 		return;
769 	icp = (struct icmp *)(buf + hlen);
770 	cc -= hlen + ICMP_MINLEN;
771 	buf += hlen + ICMP_MINLEN;
772 
773 	type = icp->icmp_type;
774 	if (type != ICMP_TIMXCEED && type != ICMP_UNREACH &&
775 	    type != ICMP_PARAMPROB)
776 		/* Wrong ICMP type for extension */
777 		return;
778 
779 	off = icp->icmp_length * sizeof(u_int32_t);
780 	if (off == 0)
781 		/*
782 		 * rfc 4884 Section 5.5: traceroute MUST try to parse
783 		 * broken ext headers. Again IETF bent over to please
784 		 * idotic corporations.
785 		 */
786 		off = ICMP_EXT_OFFSET;
787 	else if (off < ICMP_EXT_OFFSET)
788 		/* rfc 4884 requires an offset of at least 128 bytes */
789 		return;
790 
791 	/* make sure that at least one extension is present */
792 	if (cc < off + sizeof(exthdr) + sizeof(objhdr))
793 		/* Not enough space for ICMP extensions */
794 		return;
795 
796 	cc -= off;
797 	buf += off;
798 	memcpy(&exthdr, buf, sizeof(exthdr));
799 
800 	/* verify version */
801 	if ((exthdr.ieh_version & ICMP_EXT_HDR_VMASK) != ICMP_EXT_HDR_VERSION)
802 		return;
803 
804 	/* verify checksum */
805 	if (exthdr.ieh_cksum && in_cksum((u_short *)buf, cc))
806 		return;
807 
808 	buf += sizeof(exthdr);
809 	cc -= sizeof(exthdr);
810 
811 	while (cc > sizeof(objhdr)) {
812 		memcpy(&objhdr, buf, sizeof(objhdr));
813 		olen = ntohs(objhdr.ieo_length);
814 
815 		/* Sanity check the length field */
816 		if (olen < sizeof(objhdr) || olen > cc)
817 			return;
818 
819 		cc -= olen;
820 
821 		/* Move past the object header */
822 		buf += sizeof(objhdr);
823 		olen -= sizeof(objhdr);
824 
825 		switch (objhdr.ieo_cnum) {
826 		case ICMP_EXT_MPLS:
827 			/* RFC 4950: ICMP Extensions for MPLS */
828 			switch (objhdr.ieo_ctype) {
829 			case 1:
830 				first = 0;
831 				while (olen >= sizeof(u_int32_t)) {
832 					memcpy(&label, buf, sizeof(u_int32_t));
833 					label = htonl(label);
834 					buf += sizeof(u_int32_t);
835 					olen -= sizeof(u_int32_t);
836 
837 					if (first == 0) {
838 						printf(" [MPLS Label ");
839 						first++;
840 					} else
841 						printf(", ");
842 					printf("%d", MPLS_LABEL(label));
843 					if (MPLS_EXP(label))
844 						printf(" (Exp %x)",
845 						    MPLS_EXP(label));
846 				}
847 				if (olen > 0) {
848 					printf("|]");
849 					return;
850 				}
851 				if (first != 0)
852 					printf("]");
853 				break;
854 			default:
855 				buf += olen;
856 				break;
857 			}
858 			break;
859 		case ICMP_EXT_IFINFO:
860 		default:
861 			buf += olen;
862 			break;
863 		}
864 	}
865 }
866 
867 int
868 wait_for_reply(int sock, struct sockaddr_in *from, struct timeval *sent)
869 {
870 	socklen_t fromlen = sizeof (*from);
871 	struct timeval now, wait;
872 	int cc = 0, fdsn;
873 	fd_set *fdsp;
874 
875 	fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
876 	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
877 		err(1, "malloc");
878 	memset(fdsp, 0, fdsn);
879 	FD_SET(sock, fdsp);
880 	gettimeofday(&now, NULL);
881 	wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec;
882 	wait.tv_usec =  sent->tv_usec - now.tv_usec;
883 	if (wait.tv_usec < 0) {
884 		wait.tv_usec += 1000000;
885 		wait.tv_sec--;
886 	}
887 	if (wait.tv_sec < 0)
888 		timerclear(&wait);
889 
890 	if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
891 		cc = recvfrom(rcvsock, (char *)packet, sizeof(packet), 0,
892 		    (struct sockaddr *)from, &fromlen);
893 
894 	free(fdsp);
895 	return (cc);
896 }
897 
898 void
899 dump_packet(void)
900 {
901 	u_char *p;
902 	int i;
903 
904 	fprintf(stderr, "packet data:");
905 	for (p = outpacket, i = 0; i < datalen; i++) {
906 		if ((i % 24) == 0)
907 			fprintf(stderr, "\n ");
908 		fprintf(stderr, " %02x", *p++);
909 	}
910 	fprintf(stderr, "\n");
911 }
912 
913 void
914 send_probe(int seq, u_int8_t ttl, int iflag, struct sockaddr_in *to)
915 {
916 	struct ip *ip = (struct ip *)outpacket;
917 	u_char *p = (u_char *)(ip + 1);
918 	struct udphdr *up = (struct udphdr *)(p + lsrrlen);
919 	struct icmp *icmpp = (struct icmp *)(p + lsrrlen);
920 	struct packetdata *op;
921 	struct timeval tv;
922 	int i;
923 
924 	ip->ip_len = htons(datalen);
925 	ip->ip_ttl = ttl;
926 	ip->ip_id = htons(ident+seq);
927 
928 	switch (proto) {
929 	case IPPROTO_ICMP:
930 		icmpp->icmp_type = icmp_type;
931 		icmpp->icmp_code = icmp_code;
932 		icmpp->icmp_seq = htons(seq);
933 		icmpp->icmp_id = htons(ident);
934 		op = (struct packetdata *)(icmpp + 1);
935 		break;
936 	case IPPROTO_UDP:
937 		up->uh_sport = htons(ident);
938 		if (iflag)
939 			up->uh_dport = htons(port+seq);
940 		else
941 			up->uh_dport = htons(port);
942 		up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
943 		    lsrrlen));
944 		up->uh_sum = 0;
945 		op = (struct packetdata *)(up + 1);
946 		break;
947 	default:
948 		op = (struct packetdata *)(ip + 1);
949 		break;
950 	}
951 	op->seq = seq;
952 	op->ttl = ttl;
953 	(void) gettimeofday(&tv, NULL);
954 
955 	/*
956 	 * We don't want hostiles snooping the net to get any useful
957 	 * information about us. Send the timestamp in network byte order,
958 	 * and perturb the timestamp enough that they won't know our
959 	 * real clock ticker. We don't want to perturb the time by too
960 	 * much: being off by a suspiciously large amount might indicate
961 	 * OpenBSD.
962 	 *
963 	 * The timestamps in the packet are currently unused. If future
964 	 * work wants to use them they will have to subtract out the
965 	 * perturbation first.
966 	 */
967 	(void) gettimeofday(&tv, NULL);
968 	op->sec = htonl(tv.tv_sec + sec_perturb);
969 	op->usec = htonl((tv.tv_usec + usec_perturb) % 1000000);
970 
971 	if (proto == IPPROTO_ICMP && icmp_type == ICMP_ECHO) {
972 		icmpp->icmp_cksum = 0;
973 		icmpp->icmp_cksum = in_cksum((u_short *)icmpp,
974 		    datalen - sizeof(struct ip) - lsrrlen);
975 		if (icmpp->icmp_cksum == 0)
976 			icmpp->icmp_cksum = 0xffff;
977 	}
978 
979 	if (dump)
980 		dump_packet();
981 
982 	i = sendto(sndsock, outpacket, datalen, 0, (struct sockaddr *)to,
983 	    sizeof(struct sockaddr_in));
984 	if (i < 0 || i != datalen)  {
985 		if (i < 0)
986 			perror("sendto");
987 		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
988 		    datalen, i);
989 		(void) fflush(stdout);
990 	}
991 }
992 
993 static char *ttab[] = {
994 	"Echo Reply",
995 	"ICMP 1",
996 	"ICMP 2",
997 	"Dest Unreachable",
998 	"Source Quench",
999 	"Redirect",
1000 	"ICMP 6",
1001 	"ICMP 7",
1002 	"Echo",
1003 	"Router Advert",
1004 	"Router Solicit",
1005 	"Time Exceeded",
1006 	"Param Problem",
1007 	"Timestamp",
1008 	"Timestamp Reply",
1009 	"Info Request",
1010 	"Info Reply",
1011 	"Mask Request",
1012 	"Mask Reply"
1013 };
1014 
1015 /*
1016  * Convert an ICMP "type" field to a printable string.
1017  */
1018 char *
1019 pr_type(u_int8_t t)
1020 {
1021 	if (t > 18)
1022 		return ("OUT-OF-RANGE");
1023 	return (ttab[t]);
1024 }
1025 
1026 int
1027 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq, int iflag)
1028 {
1029 	struct icmp *icp;
1030 	u_char code;
1031 	u_int8_t type;
1032 	int hlen;
1033 #ifndef ARCHAIC
1034 	struct ip *ip;
1035 
1036 	ip = (struct ip *) buf;
1037 	hlen = ip->ip_hl << 2;
1038 	if (cc < hlen + ICMP_MINLEN) {
1039 		if (verbose)
1040 			printf("packet too short (%d bytes) from %s\n", cc,
1041 			    inet_ntoa(from->sin_addr));
1042 		return (0);
1043 	}
1044 	cc -= hlen;
1045 	icp = (struct icmp *)(buf + hlen);
1046 #else
1047 	icp = (struct icmp *)buf;
1048 #endif /* ARCHAIC */
1049 	type = icp->icmp_type;
1050 	code = icp->icmp_code;
1051 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1052 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1053 		struct ip *hip;
1054 		struct udphdr *up;
1055 		struct icmp *icmpp;
1056 
1057 		hip = &icp->icmp_ip;
1058 		hlen = hip->ip_hl << 2;
1059 
1060 		switch (proto) {
1061 		case IPPROTO_ICMP:
1062 			if (icmp_type == ICMP_ECHO &&
1063 			    type == ICMP_ECHOREPLY &&
1064 			    icp->icmp_id == htons(ident) &&
1065 			    icp->icmp_seq == htons(seq))
1066 				return (-2); /* we got there */
1067 
1068 			icmpp = (struct icmp *)((u_char *)hip + hlen);
1069 			if (hlen + 8 <= cc && hip->ip_p == IPPROTO_ICMP &&
1070 			    icmpp->icmp_id == htons(ident) &&
1071 			    icmpp->icmp_seq == htons(seq))
1072 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1073 			break;
1074 
1075 		case IPPROTO_UDP:
1076 			up = (struct udphdr *)((u_char *)hip + hlen);
1077 			if (hlen + 12 <= cc && hip->ip_p == proto &&
1078 			    up->uh_sport == htons(ident) &&
1079 			    ((iflag && up->uh_dport == htons(port + seq)) ||
1080 			    (!iflag && up->uh_dport == htons(port))))
1081 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1082 			break;
1083 		default:
1084 			/* this is some odd, user specified proto,
1085 			 * how do we check it?
1086 			 */
1087 			if (hip->ip_p == proto)
1088 				return (type == ICMP_TIMXCEED? -1 : code + 1);
1089 		}
1090 	}
1091 #ifndef ARCHAIC
1092 	if (verbose) {
1093 		int i;
1094 		in_addr_t *lp = (in_addr_t *)&icp->icmp_ip;
1095 
1096 		printf("\n%d bytes from %s", cc, inet_ntoa(from->sin_addr));
1097 		printf(" to %s", inet_ntoa(ip->ip_dst));
1098 		printf(": icmp type %u (%s) code %d\n", type, pr_type(type),
1099 		    icp->icmp_code);
1100 		for (i = 4; i < cc ; i += sizeof(in_addr_t))
1101 			printf("%2d: x%8.8lx\n", i, (unsigned long)*lp++);
1102 	}
1103 #endif /* ARCHAIC */
1104 	return (0);
1105 }
1106 
1107 void
1108 print(struct sockaddr *from, int cc, const char *to)
1109 {
1110 	char hbuf[NI_MAXHOST];
1111 	if (getnameinfo(from, from->sa_len,
1112 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1113 		strlcpy(hbuf, "invalid", sizeof(hbuf));
1114 	if (nflag)
1115 		printf(" %s", hbuf);
1116 	else
1117 		printf(" %s (%s)", inetname(from), hbuf);
1118 
1119 	if (Aflag)
1120 		print_asn((struct sockaddr_storage *)from);
1121 
1122 	if (verbose)
1123 		printf(" %d bytes to %s", cc, to);
1124 }
1125 
1126 /*
1127  * Checksum routine for Internet Protocol family headers (C Version)
1128  */
1129 u_short
1130 in_cksum(u_short *addr, int len)
1131 {
1132 	u_short *w = addr, answer;
1133 	int nleft = len, sum = 0;
1134 
1135 	/*
1136 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1137 	 *  we add sequential 16 bit words to it, and at the end, fold
1138 	 *  back all the carry bits from the top 16 bits into the lower
1139 	 *  16 bits.
1140 	 */
1141 	while (nleft > 1)  {
1142 		sum += *w++;
1143 		nleft -= 2;
1144 	}
1145 
1146 	/* mop up an odd byte, if necessary */
1147 	if (nleft == 1)
1148 		sum += *(u_char *)w;
1149 
1150 	/*
1151 	 * add back carry outs from top 16 bits to low 16 bits
1152 	 */
1153 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1154 	sum += (sum >> 16);			/* add carry */
1155 	answer = ~sum;				/* truncate to 16 bits */
1156 	return (answer);
1157 }
1158 
1159 /*
1160  * Construct an Internet address representation.
1161  */
1162 const char *
1163 inetname(struct sockaddr *sa)
1164 {
1165 	static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1166 	static int first = 1;
1167 	char *cp;
1168 
1169 	if (first) {
1170 		first = 0;
1171 		if (gethostname(domain, sizeof(domain)) == 0 &&
1172 		    (cp = strchr(domain, '.')) != NULL)
1173 			(void) strlcpy(domain, cp + 1, sizeof(domain));
1174 		else
1175 			domain[0] = 0;
1176 	}
1177 	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1178 	    NI_NAMEREQD) == 0) {
1179 		if ((cp = strchr(line, '.')) != NULL && strcmp(cp + 1,
1180 		    domain) == 0)
1181 			*cp = '\0';
1182 		return (line);
1183 	}
1184 
1185 	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1186 	    NI_NUMERICHOST) != 0)
1187 		return ("invalid");
1188 	return (line);
1189 }
1190 
1191 void
1192 print_asn(struct sockaddr_storage *ss)
1193 {
1194 	struct rrsetinfo *answers = NULL;
1195 	int counter;
1196 	const u_char *uaddr;
1197 	char qbuf[MAXDNAME], *qp;
1198 
1199 	switch (ss->ss_family) {
1200 	case AF_INET:
1201 		uaddr = (const u_char *)&((struct sockaddr_in *) ss)->sin_addr;
1202 		if (snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u."
1203 		    "origin.asn.cymru.com",
1204 		    (uaddr[3] & 0xff), (uaddr[2] & 0xff),
1205 		    (uaddr[1] & 0xff), (uaddr[0] & 0xff)) >= sizeof (qbuf))
1206 			return;
1207 		break;
1208 	case AF_INET6:
1209 		uaddr = (const u_char *)&((struct sockaddr_in6 *) ss)->sin6_addr;
1210 		if (snprintf(qbuf, sizeof qbuf,
1211 		    "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
1212 		    "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
1213 		    "origin6.asn.cymru.com",
1214 		    (uaddr[15] & 0x0f), ((uaddr[15] >>4)& 0x0f),
1215 		    (uaddr[14] & 0x0f), ((uaddr[14] >>4)& 0x0f),
1216 		    (uaddr[13] & 0x0f), ((uaddr[13] >>4)& 0x0f),
1217 		    (uaddr[12] & 0x0f), ((uaddr[12] >>4)& 0x0f),
1218 		    (uaddr[11] & 0x0f), ((uaddr[11] >>4)& 0x0f),
1219 		    (uaddr[10] & 0x0f), ((uaddr[10] >>4)& 0x0f),
1220 		    (uaddr[9] & 0x0f), ((uaddr[9] >>4)& 0x0f),
1221 		    (uaddr[8] & 0x0f), ((uaddr[8] >>4)& 0x0f),
1222 		    (uaddr[7] & 0x0f), ((uaddr[7] >>4)& 0x0f),
1223 		    (uaddr[6] & 0x0f), ((uaddr[6] >>4)& 0x0f),
1224 		    (uaddr[5] & 0x0f), ((uaddr[5] >>4)& 0x0f),
1225 		    (uaddr[4] & 0x0f), ((uaddr[4] >>4)& 0x0f),
1226 		    (uaddr[3] & 0x0f), ((uaddr[3] >>4)& 0x0f),
1227 		    (uaddr[2] & 0x0f), ((uaddr[2] >>4)& 0x0f),
1228 		    (uaddr[1] & 0x0f), ((uaddr[1] >>4)& 0x0f),
1229 		    (uaddr[0] & 0x0f), ((uaddr[0] >>4)& 0x0f)) >= sizeof (qbuf))
1230 			return;
1231 		break;
1232 	default:
1233 		return;
1234 	}
1235 
1236 	if (getrrsetbyname(qbuf, C_IN, T_TXT, 0, &answers) != 0)
1237 		return;
1238 	for (counter = 0; counter < answers->rri_nrdatas; counter++) {
1239 		char *p, *as = answers->rri_rdatas[counter].rdi_data;
1240 		as++; /* skip first byte, it contains length */
1241 		if ((p = strchr(as,'|'))) {
1242 			printf(counter ? ", " : " [");
1243 			p[-1] = 0;
1244 			printf("AS%s", as);
1245 		}
1246 	}
1247 	if (counter)
1248 		printf("]");
1249 
1250 	freerrset(answers);
1251 }
1252 
1253 int
1254 map_tos(char *s, int *val)
1255 {
1256 	/* DiffServ Codepoints and other TOS mappings */
1257 	const struct toskeywords {
1258 		const char	*keyword;
1259 		int		 val;
1260 	} *t, toskeywords[] = {
1261 		{ "af11",		IPTOS_DSCP_AF11 },
1262 		{ "af12",		IPTOS_DSCP_AF12 },
1263 		{ "af13",		IPTOS_DSCP_AF13 },
1264 		{ "af21",		IPTOS_DSCP_AF21 },
1265 		{ "af22",		IPTOS_DSCP_AF22 },
1266 		{ "af23",		IPTOS_DSCP_AF23 },
1267 		{ "af31",		IPTOS_DSCP_AF31 },
1268 		{ "af32",		IPTOS_DSCP_AF32 },
1269 		{ "af33",		IPTOS_DSCP_AF33 },
1270 		{ "af41",		IPTOS_DSCP_AF41 },
1271 		{ "af42",		IPTOS_DSCP_AF42 },
1272 		{ "af43",		IPTOS_DSCP_AF43 },
1273 		{ "critical",		IPTOS_PREC_CRITIC_ECP },
1274 		{ "cs0",		IPTOS_DSCP_CS0 },
1275 		{ "cs1",		IPTOS_DSCP_CS1 },
1276 		{ "cs2",		IPTOS_DSCP_CS2 },
1277 		{ "cs3",		IPTOS_DSCP_CS3 },
1278 		{ "cs4",		IPTOS_DSCP_CS4 },
1279 		{ "cs5",		IPTOS_DSCP_CS5 },
1280 		{ "cs6",		IPTOS_DSCP_CS6 },
1281 		{ "cs7",		IPTOS_DSCP_CS7 },
1282 		{ "ef",			IPTOS_DSCP_EF },
1283 		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
1284 		{ "lowdelay",		IPTOS_LOWDELAY },
1285 		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
1286 		{ "reliability",	IPTOS_RELIABILITY },
1287 		{ "throughput",		IPTOS_THROUGHPUT },
1288 		{ NULL, 		-1 },
1289 	};
1290 
1291 	for (t = toskeywords; t->keyword != NULL; t++) {
1292 		if (strcmp(s, t->keyword) == 0) {
1293 			*val = t->val;
1294 			return (1);
1295 		}
1296 	}
1297 
1298 	return (0);
1299 }
1300 
1301 void
1302 usage(void)
1303 {
1304 	extern char *__progname;
1305 
1306 	fprintf(stderr,
1307 	    "usage: %s [-AcDdIlnSvx] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
1308 	    "\t[-P proto] [-p port] [-q nqueries] [-s src_addr] [-t toskeyword]\n"
1309 	    "\t[-V rtable] [-w waittime] host [packetsize]\n", __progname);
1310 	exit(1);
1311 }
1312