Deleted Added
sdiff udiff text old ( 66808 ) new ( 78064 )
full compact
1/* $KAME: traceroute6.c,v 1.42 2001/05/08 04:36:41 itojun Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:

--- 61 unchanged lines hidden (view full) ---

71 The Regents of the University of California. All rights reserved.\n";
72#endif /* not lint */
73
74#ifndef lint
75#if 0
76static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93";
77#endif
78static const char rcsid[] =
79 "$FreeBSD: head/usr.sbin/traceroute6/traceroute6.c 78064 2001-06-11 12:39:29Z ume $";
80#endif /* not lint */
81
82/*
83 * traceroute host - trace the route ip packets follow going to "host".
84 *
85 * Attempt to trace the route an ip packet would follow to some
86 * internet host. We find out intermediate hops by launching probe
87 * packets with a small ttl (time to live) then listening for an

--- 292 unchanged lines hidden (view full) ---

380 char *argv[];
381{
382 struct hostent *hp;
383 int error;
384 struct addrinfo hints, *res;
385 int ch, i, on, probe, seq, hops, rcvcmsglen;
386 static u_char *rcvcmsgbuf;
387 char hbuf[NI_MAXHOST], src0[NI_MAXHOST];
388 char *ep;
389
390 /*
391 * Receive ICMP
392 */
393 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
394 perror("socket(ICMPv6)");
395 exit(5);
396 }
397
398 /* revoke privs */
399 seteuid(getuid());
400 setuid(getuid());
401
402 /* set a minimum set of socket options */
403 on = 1;
404 /* specify to tell receiving interface */
405#ifdef IPV6_RECVPKTINFO
406 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
407 sizeof(on)) < 0)
408 err(1, "setsockopt(IPV6_RECVPKTINFO)");
409#else /* old adv. API */

--- 8 unchanged lines hidden (view full) ---

418 sizeof(on)) < 0)
419 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
420#else /* old adv. API */
421 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
422 sizeof(on)) < 0)
423 err(1, "setsockopt(IPV6_HOPLIMIT)");
424#endif
425
426 seq = 0;
427
428 while ((ch = getopt(argc, argv, "df:g:lm:np:q:rs:w:v")) != -1)
429 switch(ch) {
430 case 'd':
431 options |= SO_DEBUG;
432 break;
433 case 'f':
434 ep = NULL;
435 first_hop = strtoul(optarg, &ep, 0);
436 if (!*argv || *ep) {
437 Fprintf(stderr,
438 "traceroute6: invalid min hoplimit.\n");
439 exit(1);
440 }
441 if (first_hop > max_hops) {
442 Fprintf(stderr,
443 "traceroute6: min hoplimit must be <= %d.\n", max_hops);
444 exit(1);
445 }
446 break;
447 case 'g':
448 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);

--- 30 unchanged lines hidden (view full) ---

479 inet6_rthdr_add(cmsg, (struct in6_addr *)hp->h_addr, IPV6_RTHDR_LOOSE);
480#endif
481 freehostent(hp);
482 break;
483 case 'l':
484 lflag++;
485 break;
486 case 'm':
487 ep = NULL;
488 max_hops = strtoul(optarg, &ep, 0);
489 if (!*argv || *ep) {
490 Fprintf(stderr,
491 "traceroute6: invalid max hoplimit.\n");
492 exit(1);
493 }
494 if (max_hops < first_hop) {
495 Fprintf(stderr,
496 "traceroute6: max hoplimit must be >= %d.\n", first_hop);
497 exit(1);
498 }
499 break;
500 case 'n':
501 nflag++;
502 break;
503 case 'p':
504 ep = NULL;
505 port = strtoul(optarg, &ep, 0);
506 if (!*argv || *ep) {
507 Fprintf(stderr,
508 "traceroute6: port.\n");
509 exit(1);
510 }
511 if (port < 1) {
512 Fprintf(stderr,
513 "traceroute6: port must be >0.\n");
514 exit(1);
515 }
516 break;
517 case 'q':
518 ep = NULL;
519 nprobes = strtoul(optarg, &ep, 0);
520 if (!*argv || *ep) {
521 Fprintf(stderr,
522 "traceroute6: invalid nprobes.\n");
523 exit(1);
524 }
525 if (nprobes < 1) {
526 Fprintf(stderr,
527 "traceroute6: nprobes must be >0.\n");
528 exit(1);
529 }
530 break;
531 case 'r':
532 options |= SO_DONTROUTE;

--- 4 unchanged lines hidden (view full) ---

537 * probe (e.g., on a multi-homed host).
538 */
539 source = optarg;
540 break;
541 case 'v':
542 verbose++;
543 break;
544 case 'w':
545 ep = NULL;
546 waittime = strtoul(optarg, &ep, 0);
547 if (!*argv || *ep) {
548 Fprintf(stderr,
549 "traceroute6: invalid wait time.\n");
550 exit(1);
551 }
552 if (waittime <= 1) {
553 Fprintf(stderr,
554 "traceroute6: wait must be >1 sec.\n");
555 exit(1);
556 }
557 break;
558 default:
559 usage();
560 }
561 argc -= optind;
562 argv += optind;
563
564 if (argc < 1 || argc > 2)
565 usage();
566
567#if 1
568 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
569#else
570 setlinebuf (stdout);
571#endif
572

--- 10 unchanged lines hidden (view full) ---

583 }
584 if (res->ai_addrlen != sizeof(Dst)) {
585 (void)fprintf(stderr,
586 "traceroute6: size of sockaddr mismatch\n");
587 exit(1);
588 }
589 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
590 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
591 if (!hostname) {
592 (void)fprintf(stderr, "traceroute6: not enough core\n");
593 exit(1);
594 }
595
596 if (*++argv) {
597 ep = NULL;
598 datalen = strtoul(*argv, &ep, 0);
599 if (!*argv || *ep) {
600 Fprintf(stderr,
601 "traceroute6: invalid packet length.\n");
602 exit(1);
603 }
604 }
605 if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) {
606 Fprintf(stderr,
607 "traceroute6: packet size must be 0 <= s < %ld.\n",
608 (long)(MAXPACKET - sizeof(struct opacket)));
609 exit(1);
610 }
611 datalen += sizeof(struct opacket);
612 outpacket = (struct opacket *)malloc((unsigned)datalen);

--- 211 unchanged lines hidden (view full) ---

824 ident = ntohs(Src.sin6_port);
825 }
826
827 /*
828 * Message to users
829 */
830 if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
831 sizeof(hbuf), NULL, 0, NI_NUMERICHOST | niflag))
832 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
833 Fprintf(stderr, "traceroute6");
834 Fprintf(stderr, " to %s (%s)", hostname, hbuf);
835 if (source)
836 Fprintf(stderr, " from %s", source);
837 Fprintf(stderr,
838 ", %d hops max, %d byte packets\n",
839 max_hops, datalen);
840 (void) fflush(stderr);

--- 85 unchanged lines hidden (view full) ---

926 cc = recvmsg(rcvsock, mhdr, 0);
927
928 return(cc);
929#else
930 fd_set *fdsp;
931 struct timeval wait;
932 int cc = 0, fdsn;
933
934 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
935 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
936 err(1, "malloc");
937 memset(fdsp, 0, fdsn);
938 FD_SET(sock, fdsp);
939 wait.tv_sec = waittime; wait.tv_usec = 0;
940
941 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
942 cc = recvmsg(rcvsock, mhdr, 0);

--- 168 unchanged lines hidden (view full) ---

1111#ifdef OLDRAWSOCKET
1112 ip = (struct ip6_hdr *) buf;
1113 hlen = sizeof(struct ip6_hdr);
1114 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1115 if (verbose) {
1116 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1117 hbuf, sizeof(hbuf), NULL, 0,
1118 NI_NUMERICHOST | niflag) != 0)
1119 strlcpy(hbuf, "invalid", sizeof(hbuf));
1120 Printf("packet too short (%d bytes) from %s\n", cc,
1121 hbuf);
1122 }
1123 return (0);
1124 }
1125 cc -= hlen;
1126 icp = (struct icmp6_hdr *)(buf + hlen);
1127#else
1128 if (cc < sizeof(struct icmp6_hdr)) {
1129 if (verbose) {
1130 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1131 hbuf, sizeof(hbuf), NULL, 0,
1132 NI_NUMERICHOST | niflag) != 0)
1133 strlcpy(hbuf, "invalid", sizeof(hbuf));
1134 Printf("data too short (%d bytes) from %s\n", cc, hbuf);
1135 }
1136 return(0);
1137 }
1138 icp = (struct icmp6_hdr *)buf;
1139#endif
1140 /* get optional information via advanced API */
1141 rcvpktinfo = NULL;

--- 41 unchanged lines hidden (view full) ---

1183 }
1184 if (verbose) {
1185 int i;
1186 u_int8_t *p;
1187 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1188
1189 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1190 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST | niflag) != 0)
1191 strlcpy(sbuf, "invalid", sizeof(hbuf));
1192 Printf("\n%d bytes from %s to %s", cc, sbuf,
1193 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1194 dbuf, sizeof(dbuf))
1195 : "?");
1196 Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
1197 icp->icmp6_code);
1198 p = (u_int8_t *)(icp + 1);
1199#define WIDTH 16

--- 62 unchanged lines hidden (view full) ---

1262 struct msghdr *mhdr;
1263 int cc;
1264{
1265 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1266 char hbuf[NI_MAXHOST];
1267
1268 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1269 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST | niflag) != 0)
1270 strlcpy(hbuf, "invalid", sizeof(hbuf));
1271 if (nflag)
1272 Printf(" %s", hbuf);
1273 else if (lflag)
1274 Printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1275 else
1276 Printf(" %s", inetname((struct sockaddr *)from));
1277
1278 if (verbose) {

--- 40 unchanged lines hidden (view full) ---

1319 static char line[NI_MAXHOST];
1320 static char domain[MAXHOSTNAMELEN + 1];
1321 static int first = 1;
1322
1323 if (first && !nflag) {
1324 first = 0;
1325 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1326 (cp = index(domain, '.')))
1327 (void) strlcpy(domain, cp + 1, sizeof(domain));
1328 else
1329 domain[0] = 0;
1330 }
1331 cp = NULL;
1332 if (!nflag) {
1333 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1334 NI_NAMEREQD) == 0) {
1335 if ((cp = index(line, '.')) &&
1336 !strcmp(cp + 1, domain))
1337 *cp = 0;
1338 cp = line;
1339 }
1340 }
1341 if (cp)
1342 return cp;
1343
1344 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1345 NI_NUMERICHOST | niflag) != 0)
1346 strlcpy(line, "invalid", sizeof(line));
1347 return line;
1348}
1349
1350void
1351usage()
1352{
1353 (void)fprintf(stderr,
1354"usage: traceroute6 [-dlnrv] [-f firsthop] [-g gateway] [-m hoplimit] [-p port]\n"
1355" [-q probes] [-s src] [-w waittime] target [datalen]\n");
1356 exit(1);
1357}