summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoritojun <itojun@openbsd.org>2001-06-22 13:20:21 +0000
committeritojun <itojun@openbsd.org>2001-06-22 13:20:21 +0000
commit85f04dfa5b0ccd38e1f117360b57724191842cc2 (patch)
tree94722171d61424571bd542d358a256caebd61b28
parentcleanup COMPAT_RFC1885 case, for icmp6 echoback packet size consideration (diff)
downloadwireguard-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.815
-rw-r--r--sbin/ping6/ping6.c145
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