diff options
author | 2001-06-22 13:20:21 +0000 | |
---|---|---|
committer | 2001-06-22 13:20:21 +0000 | |
commit | 85f04dfa5b0ccd38e1f117360b57724191842cc2 (patch) | |
tree | 94722171d61424571bd542d358a256caebd61b28 | |
parent | cleanup COMPAT_RFC1885 case, for icmp6 echoback packet size consideration (diff) | |
download | wireguard-openbsd-85f04dfa5b0ccd38e1f117360b57724191842cc2.tar.xz wireguard-openbsd-85f04dfa5b0ccd38e1f117360b57724191842cc2.zip |
sync usage/manpage with reality.
From: Brian Poole <raj@cerias.purdue.edu>
-rw-r--r-- | sbin/ping6/ping6.8 | 15 | ||||
-rw-r--r-- | sbin/ping6/ping6.c | 145 |
2 files changed, 141 insertions, 19 deletions
diff --git a/sbin/ping6/ping6.8 b/sbin/ping6/ping6.8 index d0414ea3000..0bcb59f4f47 100644 --- a/sbin/ping6/ping6.8 +++ b/sbin/ping6/ping6.8 @@ -1,5 +1,5 @@ -.\" $OpenBSD: ping6.8,v 1.15 2001/03/19 06:54:15 itojun Exp $ -.\" $KAME: ping6.8,v 1.37 2001/03/19 06:54:22 itojun Exp $ +.\" $OpenBSD: ping6.8,v 1.16 2001/06/22 13:20:21 itojun Exp $ +.\" $KAME: ping6.8,v 1.40 2001/06/22 13:16:02 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -39,9 +39,9 @@ packets to network hosts .Sh SYNOPSIS .Nm ping6 .\" without ipsec, or new ipsec -.Op Fl dfHnNqRtvw +.Op Fl dfHnNqRtvwW .\" old ipsec -.\" .Op Fl AdEfnNqRtvw +.\" .Op Fl AdEfnNqRtvwW .Bk -words .Op Fl a Ar addrtype .Ek @@ -417,6 +417,9 @@ ping6 -a agl dst.foo.com .Pp .Sh SEE ALSO .Xr netstat 1 , +.Xr icmp6 4 , +.Xr inet6 4 , +.Xr ip6 4 , .Xr ifconfig 8 , .Xr ping 8 , .Xr routed 8 , @@ -432,8 +435,8 @@ ping6 -a agl dst.foo.com .Rs .%A Matt Crawford .%T "IPv6 Node Information Queries" -.%N draft-ietf-ipngwg-icmp-name-lookups-06.txt -.%D July 2000 +.%N draft-ietf-ipngwg-icmp-name-lookups-07.txt +.%D August 2000 .%O work in progress material .Re .Sh HISTORY diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c index 656c8c7fa88..bba008c12b3 100644 --- a/sbin/ping6/ping6.c +++ b/sbin/ping6/ping6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ping6.c,v 1.29 2001/05/09 11:39:45 itojun Exp $ */ -/* $KAME: ping6.c,v 1.125 2001/05/09 11:17:33 itojun Exp $ */ +/* $OpenBSD: ping6.c,v 1.30 2001/06/22 13:20:21 itojun Exp $ */ +/* $KAME: ping6.c,v 1.129 2001/06/22 13:16:02 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -216,6 +216,7 @@ int ident; /* process id to identify our packets */ u_int8_t nonce[8]; /* nonce field for node information */ struct in6_addr srcaddr; int hoplimit = -1; /* hoplimit */ +int pathmtu = 0; /* path MTU for the destination. 0 = unspec. */ /* counters */ long npackets; /* max packets to transmit */ @@ -251,11 +252,13 @@ volatile sig_atomic_t seeninfo; int main __P((int, char *[])); void fill __P((char *, char *)); int get_hoplim __P((struct msghdr *)); +int get_pathmtu __P((struct msghdr *)); struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *)); void onsignal __P((int)); void retransmit __P((void)); void onint __P((int)); -void pinger __P((void)); +size_t pingerlen __P((void)); +int pinger __P((void)); const char *pr_addr __P((struct sockaddr *, int)); void pr_icmph __P((struct icmp6_hdr *, u_char *)); void pr_iph __P((struct ip6_hdr *)); @@ -323,7 +326,7 @@ main(argc, argv) #endif /*IPSEC_POLICY_IPSEC*/ #endif while ((ch = getopt(argc, argv, - "a:b:c:dfHh:I:i:l:nNp:qRS:s:tvwW" ADDOPTS)) != EOF) { + "a:b:c:dfHh:I:i:l:mnNp:qRS:s:tvwW" ADDOPTS)) != -1) { #undef ADDOPTS switch (ch) { case 'a': @@ -439,6 +442,14 @@ main(argc, argv) if (preload < 0 || *optarg == '\0' || *e != '\0') errx(1, "illegal preload value -- %s", optarg); break; + case 'm': +#ifdef IPV6_USE_MIN_MTU + options |= F_NOMINMTU; + break; +#else + errx(1, "-%c is not supported on this platform", ch); + /*NOTREACHED*/ +#endif case 'n': options &= ~F_HOSTNAME; break; @@ -620,13 +631,18 @@ main(argc, argv) timing = 1; } else timing = 0; + /* in F_VERBOSE case, we may get non-echoreply packets*/ + if (options & F_VERBOSE) + packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; + else + packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; } else { /* suppress timing for node information query */ timing = 0; datalen = 2048; + packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; } - packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; if (!(packet = (u_char *)malloc((u_int)packlen))) err(1, "Unable to allocate packet"); if (!(options & F_PINGFILLED)) @@ -953,12 +969,13 @@ main(argc, argv) warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ #endif - printf("PING6(%d=40+8+%d bytes) ", datalen + 48, datalen); + printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), + (unsigned long)(pingerlen() - 8)); printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); while (preload--) /* Fire off them quickies. */ - pinger(); + (void)pinger(); (void)signal(SIGINT, onsignal); #ifdef SIGINFO @@ -1008,7 +1025,7 @@ main(argc, argv) #endif if (options & F_FLOOD) { - pinger(); + (void)pinger(); timeout.tv_sec = 0; timeout.tv_usec = 10000; tv = &timeout; @@ -1045,6 +1062,21 @@ main(argc, argv) sleep(1); } continue; + } else if (cc == 0) { + int mtu; + + /* + * receive control messages only. Process the + * exceptions (currently the only possiblity is + * a path MTU notification.) + */ + if ((mtu = get_pathmtu(&m)) > 0) { + if ((options & F_VERBOSE) != 0) { + printf("new path MTU (%d) is " + "notified\n", mtu); + } + } + continue; } else { /* * an ICMPv6 message (probably an echoreply) arrived. @@ -1087,10 +1119,8 @@ retransmit() { struct itimerval itimer; - if (!npackets || ntransmitted < npackets) { - pinger(); + if (pinger() == 0) return; - } /* * If we're not transmitting any more packets, change the timer @@ -1120,7 +1150,26 @@ retransmit() * of the data portion are used to hold a UNIX "timeval" struct in VAX * byte-order, to compute the round-trip time. */ -void +size_t +pingerlen() +{ + size_t l; + + if (options & F_FQDN) + l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); + else if (options & F_FQDNOLD) + l = ICMP6_NIQLEN; + else if (options & F_NODEADDR) + l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); + else if (options & F_SUPTYPES) + l = ICMP6_NIQLEN; + else + l = ICMP6ECHOLEN + datalen; + + return l; +} + +int pinger() { struct icmp6_hdr *icp; @@ -1129,6 +1178,9 @@ pinger() struct icmp6_nodeinfo *nip; int seq; + if (npackets && ntransmitted >= npackets) + return(-1); /* no more transmission */ + icp = (struct icmp6_hdr *)outpack; nip = (struct icmp6_nodeinfo *)outpack; memset(icp, 0, sizeof(*icp)); @@ -1200,6 +1252,11 @@ pinger() cc = ICMP6ECHOLEN + datalen; } +#ifdef DIAGNOSTIC + if (pingerlen() != cc) + errx(1, "internal error; length mismatch"); +#endif + smsghdr.msg_name = (caddr_t)&dst; smsghdr.msg_namelen = sizeof(dst); memset(&iov, 0, sizeof(iov)); @@ -1218,6 +1275,8 @@ pinger() } if (!(options & F_QUIET) && options & F_FLOOD) (void)write(STDOUT_FILENO, &DOT, 1); + + return(0); } int @@ -1951,6 +2010,62 @@ get_rcvpktinfo(mhdr) return(NULL); } +int +get_pathmtu(mhdr) + struct msghdr *mhdr; +{ +#ifdef IPV6_RECVPATHMTU + struct cmsghdr *cm; + struct ip6_mtuinfo *mtuctl = NULL; + + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; + cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { + if (cm->cmsg_len == 0) + return(0); + + if (cm->cmsg_level == IPPROTO_IPV6 && + cm->cmsg_type == IPV6_PATHMTU && + cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) { + mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm); + + /* + * If the notified destination is different from + * the one we are pinging, just ignore the info. + * We check the scope ID only when both notified value + * and our own value have non-0 values, because we may + * have used the default scope zone ID for sending, + * in which case the scope ID value is 0. + */ + if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr, + &dst.sin6_addr) || + (mtuctl->ip6m_addr.sin6_scope_id && + dst.sin6_scope_id && + mtuctl->ip6m_addr.sin6_scope_id != + dst.sin6_scope_id)) { + if ((options & F_VERBOSE) != 0) { + printf("path MTU for %s is notified. " + "(ignored)\n", + pr_addr((struct sockaddr *)&mtuctl->ip6m_addr, + sizeof(mtuctl->ip6m_addr))); + } + return(0); + } + + /* + * Ignore an invalid MTU. XXX: can we just believe + * the kernel check? + */ + if (mtuctl->ip6m_mtu < IPV6_MMTU) + return(0); + + /* notification for our destination. return the MTU. */ + return((int)mtuctl->ip6m_mtu); + } + } +#endif + return(0); +} + /* * tvsub -- * Subtract 2 timeval structs: out = out - in. Out is assumed to @@ -2518,7 +2633,11 @@ void usage() { (void)fprintf(stderr, - "usage: ping6 [-dfHmnNqvwW" + "usage: ping6 [-dfH" +#ifdef IPV6_USE_MIN_MTU + "m" +#endif + "nNqtvwW" #ifdef IPV6_REACHCONF "R" #endif |