/* vi: set sw=4 ts=4: */
/*
- * $Id: ping6.c,v 1.3 2003/01/12 06:08:33 andersen Exp $
+ * $Id: ping6.c,v 1.6 2004/03/15 08:28:48 andersen Exp $
* Mini ping implementation for busybox
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
*
* This code is derived from software contributed to Berkeley by
* Mike Muuss.
- *
+ *
* Original copyright notice is retained at the end of this file.
*
* This version is an adaptation of ping.c from busybox.
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>
-#include <sys/time.h>
#include <sys/times.h>
-#include <sys/signal.h>
+#include <signal.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <stddef.h> /* offsetof */
#include "busybox.h"
-static const int DEFDATALEN = 56;
-static const int MAXIPLEN = 60;
-static const int MAXICMPLEN = 76;
-static const int MAXPACKET = 65468;
-#define MAX_DUP_CHK (8 * 128)
-static const int MAXWAIT = 10;
-static const int PINGINTERVAL = 1; /* second */
+enum {
+ DEFDATALEN = 56,
+ MAXIPLEN = 60,
+ MAXICMPLEN = 76,
+ MAXPACKET = 65468,
+ MAX_DUP_CHK = (8 * 128),
+ MAXWAIT = 10,
+ PINGINTERVAL = 1 /* second */
+};
#define O_QUIET (1 << 0)
#define O_VERBOSE (1 << 1)
/* simple version */
#ifndef CONFIG_FEATURE_FANCY_PING6
+static struct hostent *h;
+
void noresp(int ign)
{
printf("No response from %s\n", h->h_name);
static void ping(const char *host)
{
- struct hostent *h;
struct sockaddr_in6 pingaddr;
struct icmp6_hdr *pkt;
int pingsock, c;
setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, (char *) &sockopt,
sizeof(sockopt));
- c = sendto(pingsock, packet, sizeof(packet), 0,
+ c = sendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), 0,
(struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6));
if (c < 0 || c != sizeof(packet))
- perror_msg_and_die("sendto");
+ bb_perror_msg_and_die("sendto");
signal(SIGALRM, noresp);
alarm(5); /* give the host 5000ms to respond */
(struct sockaddr *) &from, &fromlen)) < 0) {
if (errno == EINTR)
continue;
- perror_msg("recvfrom");
+ bb_perror_msg("recvfrom");
continue;
}
if (c >= 8) { /* icmp6_hdr */
return;
}
-extern int ping6_main(int argc, char **argv)
+int ping6_main(int argc, char **argv)
{
argc--;
argv++;
if (argc < 1)
- show_usage();
+ bb_show_usage();
ping(*argv);
return EXIT_SUCCESS;
}
static char rcvd_tbl[MAX_DUP_CHK / 8];
# ifdef CONFIG_FEATURE_FANCY_PING
-extern
+extern
# endif
struct hostent *hostent;
{
struct icmp6_hdr *pkt;
int i;
- char packet[datalen + 8];
+ char packet[datalen + sizeof (struct icmp6_hdr)];
pkt = (struct icmp6_hdr *) packet;
(struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6));
if (i < 0)
- perror_msg_and_die("sendto");
+ bb_perror_msg_and_die("sendto");
else if ((size_t)i != sizeof(packet))
- error_msg_and_die("ping wrote %d chars; %d expected", i,
+ bb_error_msg_and_die("ping wrote %d chars; %d expected", i,
(int)sizeof(packet));
signal(SIGALRM, sendping);
}
}
+/* RFC3542 changed some definitions from RFC2292 for no good reason, whee !
+ * the newer 3542 uses a MLD_ prefix where as 2292 uses ICMP6_ prefix */
+#ifndef MLD_LISTENER_QUERY
+# define MLD_LISTENER_QUERY ICMP6_MEMBERSHIP_QUERY
+#endif
+#ifndef MLD_LISTENER_REPORT
+# define MLD_LISTENER_REPORT ICMP6_MEMBERSHIP_REPORT
+#endif
+#ifndef MLD_LISTENER_REDUCTION
+# define MLD_LISTENER_REDUCTION ICMP6_MEMBERSHIP_REDUCTION
+#endif
static char *icmp6_type_name (int id)
{
switch (id) {
case ICMP6_PARAM_PROB: return "Parameter Problem";
case ICMP6_ECHO_REPLY: return "Echo Reply";
case ICMP6_ECHO_REQUEST: return "Echo Request";
- case ICMP6_MEMBERSHIP_QUERY: return "Membership Query";
- case ICMP6_MEMBERSHIP_REPORT: return "Membership Report";
- case ICMP6_MEMBERSHIP_REDUCTION: return "Membership Reduction";
- default: return "unknown ICMP type";
+ case MLD_LISTENER_QUERY: return "Listener Query";
+ case MLD_LISTENER_REPORT: return "Listener Report";
+ case MLD_LISTENER_REDUCTION: return "Listener Reduction";
+ default: return "unknown ICMP type";
}
}
return;
printf("%d bytes from %s: icmp6_seq=%u", sz,
- inet_ntop(AF_INET6, (struct in_addr6 *) &pingaddr.sin6_addr,
+ inet_ntop(AF_INET6, &pingaddr.sin6_addr,
buf, sizeof(buf)),
icmppkt->icmp6_seq);
- printf(" ttl=%d time=%lu.%lu ms", hoplimit,
+ printf(" ttl=%d time=%lu.%lu ms", hoplimit,
triptime / 10, triptime % 10);
if (dupflag)
printf(" (DUP!)");
printf("\n");
- } else
+ } else
if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST)
- error_msg("Warning: Got ICMP %d (%s)",
+ bb_error_msg("Warning: Got ICMP %d (%s)",
icmppkt->icmp6_type, icmp6_type_name (icmppkt->icmp6_type));
}
pingaddr.sin6_family = AF_INET6;
hostent = xgethostbyname2(host, AF_INET6);
if (hostent->h_addrtype != AF_INET6)
- error_msg_and_die("unknown address type; only AF_INET6 is currently supported.");
+ bb_error_msg_and_die("unknown address type; only AF_INET6 is currently supported.");
memcpy(&pingaddr.sin6_addr, hostent->h_addr, sizeof(pingaddr.sin6_addr));
}
if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
sizeof(filt)) < 0)
- error_msg_and_die("setsockopt(ICMP6_FILTER)");
+ bb_error_msg_and_die("setsockopt(ICMP6_FILTER)");
}
#endif /*ICMP6_FILTER*/
if (ifname) {
if ((pingaddr.sin6_scope_id = if_nametoindex(ifname)) == 0)
- error_msg_and_die("%s: invalid interface name", ifname);
+ bb_error_msg_and_die("%s: invalid interface name", ifname);
}
printf("PING %s (%s): %d data bytes\n",
hostent->h_name,
- inet_ntop(AF_INET6, (struct in_addr6 *) &pingaddr.sin6_addr,
+ inet_ntop(AF_INET6, &pingaddr.sin6_addr,
buf, sizeof(buf)),
datalen);
if ((c = recvmsg(pingsock, &msg, 0)) < 0) {
if (errno == EINTR)
continue;
- perror_msg("recvfrom");
+ bb_perror_msg("recvfrom");
continue;
}
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
pingstats(0);
}
-extern int ping6_main(int argc, char **argv)
+int ping6_main(int argc, char **argv)
{
char *thisarg;
break;
case 'c':
if (--argc <= 0)
- show_usage();
+ bb_show_usage();
argv++;
pingcount = atoi(*argv);
break;
case 's':
if (--argc <= 0)
- show_usage();
+ bb_show_usage();
argv++;
datalen = atoi(*argv);
break;
case 'I':
if (--argc <= 0)
- show_usage();
+ bb_show_usage();
argv++;
ifname = *argv;
break;
default:
- show_usage();
+ bb_show_usage();
}
argc--;
argv++;
}
if (argc < 1)
- show_usage();
+ bb_show_usage();
myid = getpid() & 0xFFFF;
ping(*argv);
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
- * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
+ * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
+ * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
*
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software