summaryrefslogtreecommitdiffstats
path: root/sbin/ping6
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-10-24 18:26:30 +0000
committerume <ume@FreeBSD.org>2003-10-24 18:26:30 +0000
commit881c4fa39150df7d0de2dae7ae808f6a73cb199a (patch)
tree6ce05cb7459c9a9be90d670c12bfddbbbcb6946d /sbin/ping6
parent0b2009d038122fd790a91ca95c5d9044ff2715c0 (diff)
downloadFreeBSD-src-881c4fa39150df7d0de2dae7ae808f6a73cb199a.zip
FreeBSD-src-881c4fa39150df7d0de2dae7ae808f6a73cb199a.tar.gz
Switch Advanced Sockets API for IPv6 from RFC2292 to RFC3542
(aka RFC2292bis). Though I believe this commit doesn't break backward compatibility againt existing binaries, it breaks backward compatibility of API. Now, the applications which use Advanced Sockets API such as telnet, ping6, mld6query and traceroute6 use RFC3542 API. Obtained from: KAME
Diffstat (limited to 'sbin/ping6')
-rw-r--r--sbin/ping6/Makefile6
-rw-r--r--sbin/ping6/ping6.8132
-rw-r--r--sbin/ping6/ping6.c381
3 files changed, 263 insertions, 256 deletions
diff --git a/sbin/ping6/Makefile b/sbin/ping6/Makefile
index 98378fc..4073a56 100644
--- a/sbin/ping6/Makefile
+++ b/sbin/ping6/Makefile
@@ -3,7 +3,8 @@
PROG= ping6
MAN= ping6.8
-CFLAGS+=-DINET6 -DIPSEC
+CFLAGS+=-DINET6 -DIPSEC -DKAME_SCOPEID -DUSE_RFC2292BIS \
+ -DHAVE_POLL_H -DHAVE_ARC4RANDOM
WARNS= 0
BINOWN= root
@@ -12,7 +13,4 @@ BINMODE=4555
LDADD= -lipsec -lm -lmd
DPADD= ${LIBIPSEC} ${LIBM} ${LIBMD}
-# kame scopeid hack
-CFLAGS+=-DKAME_SCOPEID
-
.include <bsd.prog.mk>
diff --git a/sbin/ping6/ping6.8 b/sbin/ping6/ping6.8
index 554bf2b..84a51ed 100644
--- a/sbin/ping6/ping6.8
+++ b/sbin/ping6/ping6.8
@@ -1,4 +1,4 @@
-.\" $KAME: ping6.8,v 1.43 2001/06/28 06:54:29 suz Exp $
+.\" $KAME: ping6.8,v 1.58 2003/06/20 12:00:22 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -40,9 +40,9 @@ packets to network hosts
.Sh SYNOPSIS
.Nm
.\" without ipsec, or new ipsec
-.Op Fl dfHnNqRtvwW
+.Op Fl dfHmnNqtvwW
.\" old ipsec
-.\" .Op Fl AdEfnNqRtvwW
+.\" .Op Fl AdEfmnNqRtvwW
.Bk -words
.Op Fl a Ar addrtype
.Ek
@@ -53,6 +53,9 @@ packets to network hosts
.Op Fl c Ar count
.Ek
.Bk -words
+.Op Fl g Ar gateway
+.Ek
+.Bk -words
.Op Fl h Ar hoplimit
.Ek
.Bk -words
@@ -78,7 +81,7 @@ packets to network hosts
.Op Fl s Ar packetsize
.Ek
.Bk -words
-.Op Ar hops...\&
+.Op Ar hops ...
.Ek
.Bk -words
.Ar host
@@ -86,7 +89,7 @@ packets to network hosts
.Sh DESCRIPTION
The
.Nm
-utility uses the
+command uses the
.Tn ICMPv6
protocol's mandatory
.Tn ICMP6_ECHO_REQUEST
@@ -103,14 +106,14 @@ The options are as follows:
.\" old ipsec
.\" .It Fl A
.\" Enables transport-mode IPsec authentication header
-.\" (experimental).
+.\" .Pq experimental .
.It Fl a Ar addrtype
Generate ICMPv6 Node Information Node Addresses query, rather than echo-request.
.Ar addrtype
must be a string constructed of the following characters.
.Bl -tag -width Ds -compact
.It Ic a
-requests all the responder's unicast addresses.
+requests unicast addresses from all of the responder's interfaces.
If the character is omitted,
only those addresses which belong to the interface which has the
responder's address are requests.
@@ -134,7 +137,7 @@ This is an experimental option.
Set socket buffer size.
.It Fl c Ar count
Stop after sending
-(and receiving)
+.Pq and receiving
.Ar count
.Tn ECHO_RESPONSE
packets.
@@ -144,7 +147,7 @@ Set the
option on the socket being used.
.\" .It Fl E
.\" Enables transport-mode IPsec encapsulated security payload
-.\" (experimental).
+.\" .Pq experimental .
.It Fl f
Flood ping.
Outputs packets as fast as they come back or one hundred times per second,
@@ -152,7 +155,7 @@ whichever is more.
For every
.Tn ECHO_REQUEST
sent a period
-.Dq .\&
+.Dq \&.
is printed, while for every
.Tn ECHO_REPLY
received a backspace is printed.
@@ -161,11 +164,16 @@ Only the super-user may use this option.
.Bf -emphasis
This can be very hard on a network and should be used with caution.
.Ef
+.It Fl g Ar gateway
+Specifies to use
+.Ar gateway
+as the next hop to the destination.
+The gateway must be a neighbor of the sending node.
.It Fl H
Specifies to try reverse-lookup of IPv6 addresses.
The
.Nm
-utility does not try reverse-lookup unless the option is specified.
+command does not try reverse-lookup unless the option is specified.
.It Fl h Ar hoplimit
Set the IPv6 hoplimit.
.It Fl I Ar interface
@@ -189,6 +197,16 @@ is specified,
sends that many packets as fast as possible before falling into its normal
mode of behavior.
Only the super-user may use this option.
+.It Fl m
+By default,
+.Nm
+asks the kernel to fragment packets to fit into the minimum IPv6 MTU.
+.Fl m
+will suppress the behavior in the following two levels:
+when the option is specified once, the behavior will be disabled for
+unicast packets.
+When the option is more than once, it will be disabled for both
+unicast and multicast packets.
.It Fl n
Numeric output only.
No attempt will be made to lookup symbolic names from addresses in the reply.
@@ -197,12 +215,12 @@ Probe node information multicast group
.Pq Li ff02::2:xxxx:xxxx .
.Ar host
must be string hostname of the target
-(must not be a numeric IPv6 address).
+.Pq must not be a numeric IPv6 address .
Node information multicast group will be computed based on given
.Ar host ,
and will be used as the final destination.
Since node information multicast group is a link-local multicast group,
-destination link needs to be specified by
+outgoing interface needs to be specified by
.Fl I
option.
.It Fl p Ar pattern
@@ -222,26 +240,10 @@ specifies IPsec policy to be used for the probe.
Quiet output.
Nothing is displayed except the summary lines at startup time and
when finished.
-.It Fl R
-Make the kernel believe that the target
-.Ar host
-(or the first
-.Ar hop
-if you specify
-.Ar hops )
-is reachable, by injecting upper-layer reachability confirmation hint.
-The option is meaningful only if the target
-.Ar host
-(or the first hop)
-is a neighbor.
.It Fl S Ar sourceaddr
Specifies the source address of request packets.
-The source address must be one of the unicast addresses of the sending node.
-If the outgoing interface is specified by the
-.Fl I
-option as well,
-.Ar sourceaddr
-needs to be an address assigned to the specified interface.
+The source address must be one of the unicast addresses of the sending node,
+and must be numeric.
.It Fl s Ar packetsize
Specifies the number of data bytes to be sent.
The default is 56, which translates into 64
@@ -299,26 +301,13 @@ If duplicate packets are received, they are not included in the packet
loss calculation, although the round trip time of these packets is used
in calculating the round-trip time statistics.
When the specified number of packets have been sent
-(and received)
+.Pq and received
or if the program is terminated with a
.Dv SIGINT ,
a brief summary is displayed, showing the number of packets sent and
-received, and the minimum, mean, maximum, and standard deviation of
+received, and the minimum, maximum, mean, and standard deviation of
the round-trip times.
.Pp
-If
-.Nm
-receives a
-.Dv SIGINFO
-(see the
-.Cm status
-argument for
-.Xr stty 1 )
-signal, the current number of packets sent and received, and the
-minimum, mean, maximum, and standard deviation of the round-trip times
-will be written to the standard output in the same format as the
-standard completion message.
-.Pp
This program is intended for use in network testing, measurement and
management.
Because of the load it can impose on the network, it is unwise to use
@@ -335,14 +324,12 @@ during normal operations or from automated scripts.
.\" When a
.\" .Ar packetsize
.\" is given, this indicated the size of this extra piece of data
-.\" (the default is 56).
+.\" .Pq the default is 56 .
.\" Thus the amount of data received inside of an IP packet of type
.\" .Tn ICMP
.\" .Tn ECHO_REPLY
.\" will always be 8 bytes more than the requested data space
-.\" (the
-.\" .Tn ICMP
-.\" header).
+.\" .Pq the Tn ICMP header .
.\" .Pp
.\" If the data space is at least eight bytes large,
.\" .Nm
@@ -353,12 +340,12 @@ during normal operations or from automated scripts.
.Sh DUPLICATE AND DAMAGED PACKETS
The
.Nm
-utility will report duplicate and damaged packets.
+command will report duplicate and damaged packets.
Duplicate packets should never occur when pinging a unicast address,
and seem to be caused by
inappropriate link-level retransmissions.
Duplicates may occur in many situations and are rarely
-(if ever)
+.Pq if ever
a good sign, although the presence of low levels of duplicates may not
always be cause for alarm.
Duplicates are expected when pinging a broadcast or multicast address,
@@ -369,7 +356,7 @@ Damaged packets are obviously serious cause for alarm and often
indicate broken hardware somewhere in the
.Nm
packet's path
-(in the network or in the hosts).
+.Pq in the network or in the hosts .
.Sh TRYING DIFFERENT DATA PATTERNS
The
(inter)network
@@ -398,11 +385,10 @@ You can then examine this file for repeated patterns that you can test
using the
.Fl p
option of
-.Nm .
+.Nm Ns .
.Sh RETURN VALUES
-The
.Nm
-utility returns 0 on success (the host is alive),
+command returns 0 on success (the host is alive),
and non-zero if the arguments are incorrect or the host is not responding.
.Sh EXAMPLES
Normally,
@@ -451,11 +437,28 @@ ping6 -a agl dst.foo.com
.Rs
.%A Matt Crawford
.%T "IPv6 Node Information Queries"
-.%N draft-ietf-ipngwg-icmp-name-lookups-07.txt
-.%D August 2000
+.%N draft-ietf-ipngwg-icmp-name-lookups-09.txt
+.%D May 2002
.%O work in progress material
.Re
+.Sh HISTORY
+The
+.Xr ping 8
+command appeared in
+.Bx 4.3 .
+The
+.Nm
+command with IPv6 support first appeared in the WIDE Hydrangea IPv6
+protocol stack kit.
+.Pp
+IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
+was initially integrated into
+.Fx 4.0
.Sh BUGS
+.Nm
+is intentionally separate from
+.Xr ping 8 .
+.Pp
There have been many discussions on why we separate
.Nm
and
@@ -484,16 +487,3 @@ or
.Fl 4
option (or something like those) to specify the particular address family.
This essentially means that we have two different commands.
-.Sh HISTORY
-The
-.Xr ping 8
-command appeared in
-.Bx 4.3 .
-The
-.Nm
-utility with IPv6 support first appeared in WIDE Hydrangea IPv6 protocol stack
-kit.
-.Pp
-IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
-was initially integrated into
-.Fx 4.0
diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c
index 70e2221..42c517c 100644
--- a/sbin/ping6/ping6.c
+++ b/sbin/ping6/ping6.c
@@ -1,4 +1,4 @@
-/* $KAME: ping6.c,v 1.126 2001/05/17 03:39:08 itojun Exp $ */
+/* $KAME: ping6.c,v 1.169 2003/07/25 06:01:47 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -123,30 +123,32 @@ static const char rcsid[] =
#include <err.h>
#include <errno.h>
#include <fcntl.h>
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
#include <math.h>
-#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#ifdef IPSEC
#include <netinet6/ah.h>
#include <netinet6/ipsec.h>
#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <md5.h>
-#else
-#include "md5.h"
-#endif
+
+struct tv32 {
+ u_int32_t tv32_sec;
+ u_int32_t tv32_usec;
+};
#define MAXPACKETLEN 131072
#define IP6LEN 40
-#define ICMP6ECHOLEN 8 /* icmp echo header length excluding time */
-#define ICMP6ECHOTMLEN sizeof(struct timeval)
+#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */
+#define ICMP6ECHOTMLEN sizeof(struct tv32)
#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8)
/* FQDN case, 64 bits of nonce + 32 bits ttl */
#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12)
@@ -180,9 +182,6 @@ static const char rcsid[] =
#define F_FQDN 0x1000
#define F_INTERFACE 0x2000
#define F_SRCADDR 0x4000
-#ifdef IPV6_REACHCONF
-#define F_REACHCONF 0x8000
-#endif
#define F_HOSTNAME 0x10000
#define F_FQDNOLD 0x20000
#define F_NIGROUP 0x40000
@@ -209,6 +208,7 @@ char rcvd_tbl[MAX_DUP_CHK / 8];
struct addrinfo *res;
struct sockaddr_in6 dst; /* who to ping6 */
struct sockaddr_in6 src; /* src addr of this packet */
+socklen_t srclen;
int datalen = DEFDATALEN;
int s; /* socket file descriptor */
u_char outpack[MAXPACKETLEN];
@@ -217,7 +217,6 @@ char DOT = '.';
char *hostname;
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. */
@@ -233,9 +232,7 @@ int timing; /* flag to do timing */
double tmin = 999999999.0; /* minimum round trip time */
double tmax = 0.0; /* maximum round trip time */
double tsum = 0.0; /* sum of all times, for doing average */
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
-#endif
/* for node addresses */
u_short naflags;
@@ -245,17 +242,16 @@ struct msghdr smsghdr;
struct iovec smsgiov;
char *scmsg = 0;
-volatile int signo;
volatile sig_atomic_t seenalrm;
volatile sig_atomic_t seenint;
#ifdef SIGINFO
volatile sig_atomic_t seeninfo;
#endif
+int main(int, char *[]);
void fill(char *, char *);
int get_hoplim(struct msghdr *);
int get_pathmtu(struct msghdr *);
-void set_pathmtu(int);
struct in6_pktinfo *get_rcvpktinfo(struct msghdr *);
void onsignal(int);
void retransmit(void);
@@ -270,7 +266,7 @@ void pr_nodeaddr(struct icmp6_nodeinfo *, int);
int myechoreply(const struct icmp6_hdr *);
int mynireply(const struct icmp6_nodeinfo *);
char *dnsdecode(const u_char **, const u_char *, const u_char *,
- u_char *, size_t);
+ char *, size_t);
void pr_pack(u_char *, int, struct msghdr *);
void pr_exthdrs(struct msghdr *);
void pr_ip6opt(void *);
@@ -290,17 +286,31 @@ main(argc, argv)
{
struct itimerval itimer;
struct sockaddr_in6 from;
+#ifndef HAVE_ARC4RANDOM
+ struct timeval seed;
+#endif
+#ifdef HAVE_POLL_H
+ int timeout;
+#else
struct timeval timeout, *tv;
+#endif
struct addrinfo hints;
+#ifdef HAVE_POLL_H
+ struct pollfd fdmaskp[1];
+#else
fd_set *fdmaskp;
int fdmasks;
+#endif
int cc, i;
- int ch, fromlen, hold, packlen, preload, optval, ret_ga;
+ int ch, hold, packlen, preload, optval, ret_ga;
u_char *datap, *packet;
- char *e, *target, *ifname = NULL;
+ char *e, *target, *ifname = NULL, *gateway = NULL;
int ip6optlen = 0;
struct cmsghdr *scmsgp = NULL;
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+ u_long lsockbufsize;
int sockbufsize = 0;
+#endif
int usepktinfo = 0;
struct in6_pktinfo *pktinfo = NULL;
#ifdef USE_RFC2292BIS
@@ -312,6 +322,9 @@ main(argc, argv)
#endif
double intval;
size_t rthlen;
+#ifdef IPV6_USE_MIN_MTU
+ int mflag = 0;
+#endif
/* just to be sure */
memset(&smsghdr, 0, sizeof(smsghdr));
@@ -329,7 +342,7 @@ main(argc, argv)
#endif /*IPSEC_POLICY_IPSEC*/
#endif
while ((ch = getopt(argc, argv,
- "a:b:c:dfHh:I:i:l:mnNp:qRS:s:tvwW" ADDOPTS)) != -1) {
+ "a:b:c:dfHg:h:I:i:l:mnNp:qS:s:tvwW" ADDOPTS)) != -1) {
#undef ADDOPTS
switch (ch) {
case 'a':
@@ -377,7 +390,13 @@ main(argc, argv)
}
case 'b':
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
- sockbufsize = atoi(optarg);
+ errno = 0;
+ e = NULL;
+ lsockbufsize = strtoul(optarg, &e, 10);
+ sockbufsize = lsockbufsize;
+ if (errno || !*optarg || *e ||
+ sockbufsize != lsockbufsize)
+ errx(1, "invalid socket buffer size");
#else
errx(1,
"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported");
@@ -393,16 +412,23 @@ main(argc, argv)
options |= F_SO_DEBUG;
break;
case 'f':
- if (getuid())
- errx(1, "must be superuser to flood ping");
+ if (getuid()) {
+ errno = EPERM;
+ errx(1, "Must be superuser to flood ping");
+ }
options |= F_FLOOD;
setbuf(stdout, (char *)NULL);
break;
+ case 'g':
+ gateway = optarg;
+ break;
case 'H':
options |= F_HOSTNAME;
break;
case 'h': /* hoplimit */
hoplimit = strtol(optarg, &e, 10);
+ if (*optarg == '\0' || *e != '\0')
+ errx(1, "illegal hoplimit %s", optarg);
if (255 < hoplimit || hoplimit < -1)
errx(1,
"illegal hoplimit -- %s", optarg);
@@ -435,15 +461,17 @@ main(argc, argv)
options |= F_INTERVAL;
break;
case 'l':
- if (getuid())
- errx(1, "must be superuser to preload");
+ if (getuid()) {
+ errno = EPERM;
+ errx(1, "Must be superuser to preload");
+ }
preload = strtol(optarg, &e, 10);
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;
+ mflag++;
break;
#else
errx(1, "-%c is not supported on this platform", ch);
@@ -462,19 +490,26 @@ main(argc, argv)
case 'q':
options |= F_QUIET;
break;
- case 'R':
-#ifdef IPV6_REACHCONF
- options |= F_REACHCONF;
- break;
-#else
- errx(1, "-R is not supported in this configuration");
-#endif
case 'S':
- /* XXX: use getaddrinfo? */
- if (inet_pton(AF_INET6, optarg, (void *)&srcaddr) != 1)
- errx(1, "invalid IPv6 address: %s", optarg);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_ICMPV6;
+
+ ret_ga = getaddrinfo(optarg, NULL, &hints, &res);
+ if (ret_ga) {
+ errx(1, "invalid source address: %s",
+ gai_strerror(ret_ga));
+ }
+ /*
+ * res->ai_family must be AF_INET6 and res->ai_addrlen
+ * must be sizeof(src).
+ */
+ memcpy(&src, res->ai_addr, res->ai_addrlen);
+ srclen = res->ai_addrlen;
+ freeaddrinfo(res);
options |= F_SRCADDR;
- usepktinfo++;
break;
case 's': /* size of packet to send */
datalen = strtol(optarg, &e, 10);
@@ -528,6 +563,7 @@ main(argc, argv)
/*NOTREACHED*/
}
}
+
argc -= optind;
argv += optind;
@@ -560,7 +596,7 @@ main(argc, argv)
target = argv[argc - 1];
/* getaddrinfo */
- bzero(&hints, sizeof(struct addrinfo));
+ memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_RAW;
@@ -583,6 +619,38 @@ main(argc, argv)
res->ai_protocol)) < 0)
err(1, "socket");
+ /* set the source address if specified. */
+ if ((options & F_SRCADDR) &&
+ bind(s, (struct sockaddr *)&src, srclen) != 0) {
+ err(1, "bind");
+ }
+
+ /* set the gateway (next hop) if specified */
+ if (gateway) {
+ struct addrinfo ghints, *gres;
+ int error;
+
+ memset(&ghints, 0, sizeof(ghints));
+ ghints.ai_family = AF_INET6;
+ ghints.ai_socktype = SOCK_RAW;
+ ghints.ai_protocol = IPPROTO_ICMPV6;
+
+ error = getaddrinfo(gateway, NULL, &hints, &gres);
+ if (error) {
+ errx(1, "getaddrinfo for the gateway %s: %s",
+ gateway, gai_strerror(error));
+ }
+ if (gres->ai_next && (options & F_VERBOSE))
+ warnx("gateway resolves to multiple addresses");
+
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP,
+ gres->ai_addr, gres->ai_addrlen)) {
+ err(1, "setsockopt(IPV6_NEXTHOP)");
+ }
+
+ freeaddrinfo(gres);
+ }
+
/*
* let the kerel pass extension headers of incoming packets,
* for privileged socket options
@@ -619,11 +687,11 @@ main(argc, argv)
seteuid(getuid());
setuid(getuid());
- if (options & F_FLOOD && options & F_INTERVAL)
+ if ((options & F_FLOOD) && (options & F_INTERVAL))
errx(1, "-f and -i incompatible options");
if ((options & F_NOUSERDATA) == 0) {
- if (datalen >= sizeof(struct timeval)) {
+ if (datalen >= sizeof(struct tv32)) {
/* we can time transfer */
timing = 1;
} else
@@ -641,15 +709,15 @@ main(argc, argv)
}
if (!(packet = (u_char *)malloc((u_int)packlen)))
- errx(1, "unable to allocate packet");
+ err(1, "Unable to allocate packet");
if (!(options & F_PINGFILLED))
for (i = ICMP6ECHOLEN; i < packlen; ++i)
*datap++ = i;
ident = getpid() & 0xFFFF;
-#ifndef __OpenBSD__
- gettimeofday(&timeout, NULL);
- srand((unsigned int)(timeout.tv_sec ^ timeout.tv_usec ^ (long)ident));
+#ifndef HAVE_ARC4RANDOM
+ gettimeofday(&seed, NULL);
+ srand((unsigned int)(seed.tv_sec ^ seed.tv_usec ^ (long)ident));
memset(nonce, 0, sizeof(nonce));
for (i = 0; i < sizeof(nonce); i += sizeof(int))
*((int *)&nonce[i]) = rand();
@@ -670,8 +738,9 @@ main(argc, argv)
&optval, sizeof(optval)) == -1)
err(1, "IPV6_MULTICAST_HOPS");
#ifdef IPV6_USE_MIN_MTU
- if ((options & F_NOMINMTU) == 0) {
- optval = 1;
+ if (mflag != 1) {
+ optval = mflag > 1 ? 0 : 1;
+
if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_USE_MIN_MTU)");
@@ -765,11 +834,6 @@ main(argc, argv)
if (hoplimit != -1)
ip6optlen += CMSG_SPACE(sizeof(int));
-#ifdef IPV6_REACHCONF
- if (options & F_REACHCONF)
- ip6optlen += CMSG_SPACE(0);
-#endif
-
/* set IP6 packet options */
if (ip6optlen) {
if ((scmsg = (char *)malloc(ip6optlen)) == 0)
@@ -798,10 +862,6 @@ main(argc, argv)
errx(1, "%s: invalid interface name", ifname);
#endif
}
- /* set the source address */
- if (options & F_SRCADDR)/* pktinfo must be valid */
- pktinfo->ipi6_addr = srcaddr;
-
if (hoplimit != -1) {
scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
scmsgp->cmsg_level = IPPROTO_IPV6;
@@ -810,15 +870,6 @@ main(argc, argv)
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
}
-#ifdef IPV6_REACHCONF
- if (options & F_REACHCONF) {
- scmsgp->cmsg_len = CMSG_LEN(0);
- scmsgp->cmsg_level = IPPROTO_IPV6;
- scmsgp->cmsg_type = IPV6_REACHCONF;
-
- scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
- }
-#endif
if (argc > 1) { /* some intermediate addrs are specified */
int hops, error;
@@ -873,11 +924,13 @@ main(argc, argv)
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
}
- {
+ if (!(options & F_SRCADDR)) {
/*
- * source selection
+ * get the source address. XXX since we revoked the root
+ * privilege, we cannot use a raw socket for this.
*/
- int dummy, len = sizeof(src);
+ int dummy;
+ socklen_t len = sizeof(src);
if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "UDP socket");
@@ -894,9 +947,14 @@ main(argc, argv)
err(1, "UDP setsockopt(IPV6_PKTINFO)");
if (hoplimit != -1 &&
- setsockopt(dummy, IPPROTO_IPV6, IPV6_HOPLIMIT,
+ setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
(void *)&hoplimit, sizeof(hoplimit)))
- err(1, "UDP setsockopt(IPV6_HOPLIMIT)");
+ err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)");
+
+ if (hoplimit != -1 &&
+ setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ (void *)&hoplimit, sizeof(hoplimit)))
+ err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)");
if (rthdr &&
setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR,
@@ -984,15 +1042,17 @@ main(argc, argv)
itimer.it_interval = interval;
itimer.it_value = interval;
(void)setitimer(ITIMER_REAL, &itimer, NULL);
- if (ntransmitted == 0)
+ if (ntransmitted)
retransmit();
}
+#ifndef HAVE_POLL_H
fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask);
if ((fdmaskp = malloc(fdmasks)) == NULL)
err(1, "malloc");
+#endif
- signo = seenalrm = seenint = 0;
+ seenalrm = seenint = 0;
#ifdef SIGINFO
seeninfo = 0;
#endif
@@ -1024,24 +1084,42 @@ main(argc, argv)
if (options & F_FLOOD) {
(void)pinger();
+#ifdef HAVE_POLL_H
+ timeout = 10;
+#else
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
tv = &timeout;
- } else
+#endif
+ } else {
+#ifdef HAVE_POLL_H
+ timeout = INFTIM;
+#else
tv = NULL;
+#endif
+ }
+#ifdef HAVE_POLL_H
+ fdmaskp[0].fd = s;
+ fdmaskp[0].events = POLLIN;
+ cc = poll(fdmaskp, 1, timeout);
+#else
memset(fdmaskp, 0, fdmasks);
FD_SET(s, fdmaskp);
cc = select(s + 1, fdmaskp, NULL, NULL, tv);
+#endif
if (cc < 0) {
if (errno != EINTR) {
+#ifdef HAVE_POLL_H
+ warn("poll");
+#else
warn("select");
+#endif
sleep(1);
}
continue;
} else if (cc == 0)
continue;
- fromlen = sizeof(from);
m.msg_name = (caddr_t)&from;
m.msg_namelen = sizeof(from);
memset(&iov, 0, sizeof(iov));
@@ -1073,7 +1151,6 @@ main(argc, argv)
printf("new path MTU (%d) is "
"notified\n", mtu);
}
- set_pathmtu(mtu);
}
continue;
} else {
@@ -1093,7 +1170,7 @@ void
onsignal(sig)
int sig;
{
- signo = sig;
+
switch (sig) {
case SIGALRM:
seenalrm++;
@@ -1245,9 +1322,14 @@ pinger()
icp->icmp6_code = 0;
icp->icmp6_id = htons(ident);
icp->icmp6_seq = ntohs(seq);
- if (timing)
- (void)gettimeofday((struct timeval *)
- &outpack[ICMP6ECHOLEN], NULL);
+ if (timing) {
+ struct timeval tv;
+ struct tv32 *tv32;
+ (void)gettimeofday(&tv, NULL);
+ tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN];
+ tv32->tv32_sec = htonl(tv.tv_sec);
+ tv32->tv32_usec = htonl(tv.tv_usec);
+ }
cc = ICMP6ECHOLEN + datalen;
}
@@ -1305,7 +1387,7 @@ dnsdecode(sp, ep, base, buf, bufsiz)
const u_char **sp;
const u_char *ep;
const u_char *base; /*base for compressed name*/
- u_char *buf;
+ char *buf;
size_t bufsiz;
{
int i;
@@ -1322,7 +1404,7 @@ dnsdecode(sp, ep, base, buf, bufsiz)
while (cp < ep) {
i = *cp;
if (i == 0 || cp != *sp) {
- if (strlcat(buf, ".", bufsiz) >= bufsiz)
+ if (strlcat((char *)buf, ".", bufsiz) >= bufsiz)
return NULL; /*result overrun*/
}
if (i == 0)
@@ -1347,7 +1429,7 @@ dnsdecode(sp, ep, base, buf, bufsiz)
while (i-- > 0 && cp < ep) {
l = snprintf(cresult, sizeof(cresult),
isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff);
- if (l < 0 || l >= sizeof(cresult))
+ if (l >= sizeof(cresult) || l < 0)
return NULL;
if (strlcat(buf, cresult, bufsiz) >= bufsiz)
return NULL; /*result overrun*/
@@ -1385,7 +1467,8 @@ pr_pack(buf, cc, mhdr)
int fromlen;
u_char *cp = NULL, *dp, *end = buf + cc;
struct in6_pktinfo *pktinfo = NULL;
- struct timeval tv, *tp;
+ struct timeval tv, tp;
+ struct tv32 *tpp;
double triptime = 0;
int dupflag;
size_t off;
@@ -1399,7 +1482,7 @@ pr_pack(buf, cc, mhdr)
mhdr->msg_namelen != sizeof(struct sockaddr_in6) ||
((struct sockaddr *)mhdr->msg_name)->sa_family != AF_INET6) {
if (options & F_VERBOSE)
- warnx("invalid peername\n");
+ warnx("invalid peername");
return;
}
from = (struct sockaddr *)mhdr->msg_name;
@@ -1427,14 +1510,14 @@ pr_pack(buf, cc, mhdr)
seq = ntohs(icp->icmp6_seq);
++nreceived;
if (timing) {
- tp = (struct timeval *)(icp + 1);
- tvsub(&tv, tp);
+ tpp = (struct tv32 *)(icp + 1);
+ tp.tv_sec = ntohl(tpp->tv32_sec);
+ tp.tv_usec = ntohl(tpp->tv32_usec);
+ tvsub(&tv, &tp);
triptime = ((double)tv.tv_sec) * 1000.0 +
((double)tv.tv_usec) / 1000.0;
tsum += triptime;
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
tsumsq += triptime * triptime;
-#endif
if (triptime < tmin)
tmin = triptime;
if (triptime > tmax)
@@ -1464,9 +1547,7 @@ pr_pack(buf, cc, mhdr)
memset(&dstsa, 0, sizeof(dstsa));
dstsa.sin6_family = AF_INET6;
-#ifdef SIN6_LEN
dstsa.sin6_len = sizeof(dstsa);
-#endif
dstsa.sin6_scope_id = pktinfo->ipi6_ifindex;
dstsa.sin6_addr = pktinfo->ipi6_addr;
(void)printf(" dst=%s",
@@ -1767,7 +1848,7 @@ pr_rthdr(void *extbuf)
else {
if (!inet_ntop(AF_INET6, in6, ntopbuf,
sizeof(ntopbuf)))
- strncpy(ntopbuf, "?", sizeof(ntopbuf));
+ strlcpy(ntopbuf, "?", sizeof(ntopbuf));
printf(" [%d]%s\n", i, ntopbuf);
}
}
@@ -1787,9 +1868,9 @@ pr_rthdr(void *extbuf)
#endif /* USE_RFC2292BIS */
int
-pr_bitrange(v, s, ii)
+pr_bitrange(v, soff, ii)
u_int32_t v;
- int s;
+ int soff;
int ii;
{
int off;
@@ -1800,7 +1881,7 @@ pr_bitrange(v, s, ii)
/* shift till we have 0x01 */
if ((v & 0x01) == 0) {
if (ii > 1)
- printf("-%u", s + off - 1);
+ printf("-%u", soff + off - 1);
ii = 0;
switch (v & 0x0f) {
case 0x00:
@@ -1828,7 +1909,7 @@ pr_bitrange(v, s, ii)
break;
}
if (!ii)
- printf(" %u", s + off);
+ printf(" %u", soff + off);
ii += i;
v >>= i; off += i;
}
@@ -1949,7 +2030,7 @@ pr_nodeaddr(ni, nilen)
if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) ==
NULL)
- strncpy(ntop_buf, "?", sizeof(ntop_buf));
+ strlcpy(ntop_buf, "?", sizeof(ntop_buf));
printf(" %s", ntop_buf);
if (withttl) {
if (ttl == 0xffffffff) {
@@ -2065,60 +2146,6 @@ get_pathmtu(mhdr)
return(0);
}
-void
-set_pathmtu(mtu)
- int mtu;
-{
-#ifdef IPV6_USE_MTU
- static int firsttime = 1;
- struct cmsghdr *cm;
-
- if (firsttime) {
- int oldlen = smsghdr.msg_controllen;
- char *oldbuf = smsghdr.msg_control;
-
- /* XXX: We need to enlarge control message buffer */
- firsttime = 0; /* prevent further enlargement */
-
- smsghdr.msg_controllen = oldlen + CMSG_SPACE(sizeof(int));
- if ((smsghdr.msg_control =
- (char *)malloc(smsghdr.msg_controllen)) == NULL)
- err(1, "set_pathmtu: malloc");
- cm = (struct cmsghdr *)CMSG_FIRSTHDR(&smsghdr);
- cm->cmsg_len = CMSG_LEN(sizeof(int));
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_USE_MTU;
-
- cm = (struct cmsghdr *)CMSG_NXTHDR(&smsghdr, cm);
- if (oldlen)
- memcpy((void *)cm, (void *)oldbuf, oldlen);
-
- free(oldbuf);
- }
-
- /*
- * look for a cmsgptr that points MTU structure.
- * XXX: this procedure seems redundant at this moment, but we'd better
- * keep the code generic enough for future extensions.
- */
- for (cm = CMSG_FIRSTHDR(&smsghdr); cm;
- cm = (struct cmsghdr *)CMSG_NXTHDR(&smsghdr, cm)) {
- if (cm->cmsg_len == 0) /* XXX: paranoid check */
- errx(1, "set_pathmtu: internal error");
-
- if (cm->cmsg_level == IPPROTO_IPV6 &&
- cm->cmsg_type == IPV6_USE_MTU &&
- cm->cmsg_len == CMSG_LEN(sizeof(int)))
- break;
- }
-
- if (cm == NULL)
- errx(1, "set_pathmtu: internal error: no space for path MTU");
-
- *(int *)CMSG_DATA(cm) = mtu;
-#endif
-}
-
/*
* tvsub --
* Subtract 2 timeval structs: out = out - in. Out is assumed to
@@ -2144,12 +2171,13 @@ void
onint(notused)
int notused;
{
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGALRM, SIG_IGN);
-
summary();
- exit(nreceived == 0);
+ (void)signal(SIGINT, SIG_DFL);
+ (void)kill(getpid(), SIGINT);
+
+ /* NOTREACHED */
+ exit(1);
}
/*
@@ -2167,10 +2195,10 @@ summary()
(void)printf("+%ld duplicates, ", nrepeats);
if (ntransmitted) {
if (nreceived > ntransmitted)
- (void)printf("-- somebody's printing up packets!");
+ (void)printf("-- somebody's duplicating packets!");
else
- (void)printf("%d%% packet loss",
- (int) (((ntransmitted - nreceived) * 100) /
+ (void)printf("%.1f%% packet loss",
+ ((((double)ntransmitted - nreceived) * 100.0) /
ntransmitted));
}
(void)putchar('\n');
@@ -2178,30 +2206,24 @@ summary()
/* Only display average to microseconds */
double num = nreceived + nrepeats;
double avg = tsum / num;
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
double dev = sqrt(tsumsq / num - avg * avg);
(void)printf(
"round-trip min/avg/max/std-dev = %.3f/%.3f/%.3f/%.3f ms\n",
tmin, avg, tmax, dev);
-#else
- (void)printf(
- "round-trip min/avg/max = %.3f/%.3f/%.3f ms\n",
- tmin, avg, tmax);
-#endif
(void)fflush(stdout);
}
(void)fflush(stdout);
}
/*subject type*/
-static char *niqcode[] = {
+static const char *niqcode[] = {
"IPv6 address",
"DNS label", /*or empty*/
"IPv4 address",
};
/*result code*/
-static char *nircode[] = {
+static const char *nircode[] = {
"Success", "Refused", "Unknown",
};
@@ -2323,11 +2345,11 @@ pr_icmph(icp, end)
(void)printf("Redirect\n");
if (!inet_ntop(AF_INET6, &red->nd_rd_dst, ntop_buf,
sizeof(ntop_buf)))
- strncpy(ntop_buf, "?", sizeof(ntop_buf));
+ strlcpy(ntop_buf, "?", sizeof(ntop_buf));
(void)printf("Destination: %s", ntop_buf);
if (!inet_ntop(AF_INET6, &red->nd_rd_target, ntop_buf,
sizeof(ntop_buf)))
- strncpy(ntop_buf, "?", sizeof(ntop_buf));
+ strlcpy(ntop_buf, "?", sizeof(ntop_buf));
(void)printf(" New Target: %s", ntop_buf);
break;
case ICMP6_NI_QUERY:
@@ -2459,10 +2481,10 @@ pr_iph(ip6)
(ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow),
ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim);
if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf)))
- strncpy(ntop_buf, "?", sizeof(ntop_buf));
+ strlcpy(ntop_buf, "?", sizeof(ntop_buf));
printf("%s->", ntop_buf);
if (!inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf)))
- strncpy(ntop_buf, "?", sizeof(ntop_buf));
+ strlcpy(ntop_buf, "?", sizeof(ntop_buf));
printf("%s\n", ntop_buf);
}
@@ -2594,7 +2616,7 @@ fill(bp, patp)
/* xxx */
if (ii > 0)
for (kk = 0;
- kk <= MAXDATALEN - (8 + sizeof(struct timeval) + ii);
+ kk <= MAXDATALEN - (8 + sizeof(struct tv32) + ii);
kk += ii)
for (jj = 0; jj < ii; ++jj)
bp[jj + kk] = pat[jj];
@@ -2623,7 +2645,7 @@ setpolicy(so, policy)
errx(1, "%s", ipsec_strerror());
if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
ipsec_get_policylen(buf)) < 0)
- warnx("unable to set IPSec policy");
+ warnx("Unable to set IPsec policy");
free(buf);
return 0;
@@ -2636,7 +2658,7 @@ nigroup(name)
char *name;
{
char *p;
- unsigned char *q;
+ char *q;
MD5_CTX ctxt;
u_int8_t digest[16];
u_int8_t c;
@@ -2654,16 +2676,16 @@ nigroup(name)
hbuf[(int)l] = '\0';
for (q = name; *q; q++) {
- if (isupper(*q))
- *q = tolower(*q);
+ if (isupper(*(unsigned char *)q))
+ *q = tolower(*(unsigned char *)q);
}
/* generate 8 bytes of pseudo-random value. */
- bzero(&ctxt, sizeof(ctxt));
+ memset(&ctxt, 0, sizeof(ctxt));
MD5Init(&ctxt);
c = l & 0xff;
MD5Update(&ctxt, &c, sizeof(c));
- MD5Update(&ctxt, name, l);
+ MD5Update(&ctxt, (unsigned char *)name, l);
MD5Final(digest, &ctxt);
if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1)
@@ -2685,9 +2707,6 @@ usage()
"m"
#endif
"nNqtvwW"
-#ifdef IPV6_REACHCONF
- "R"
-#endif
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"] [-P policy"
@@ -2695,9 +2714,9 @@ usage()
"AE"
#endif
#endif
- "] [-a [aAclsg]] [-b sockbufsiz] [-c count]\n"
+ "] [-a [aAclsg]] [-b sockbufsiz] [-c count] \n"
"\t[-I interface] [-i wait] [-l preload] [-p pattern] "
"[-S sourceaddr]\n"
- "\t[-s packetsize] [-h hoplimit] [hops...] host\n");
+ "\t[-s packetsize] [-h hoplimit] [hops...] [-g gateway] host\n");
exit(1);
}
OpenPOWER on IntegriCloud