summaryrefslogtreecommitdiffstats
path: root/freebsd/sbin/ping/ping.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sbin/ping/ping.c')
-rw-r--r--freebsd/sbin/ping/ping.c396
1 files changed, 257 insertions, 139 deletions
diff --git a/freebsd/sbin/ping/ping.c b/freebsd/sbin/ping/ping.c
index ad5515ab..f0d1f7ce 100644
--- a/freebsd/sbin/ping/ping.c
+++ b/freebsd/sbin/ping/ping.c
@@ -1,5 +1,9 @@
#include <machine/rtems-bsd-user-space.h>
+#ifdef __rtems__
+#include "rtems-bsd-ping-namespace.h"
+#endif /* __rtems__ */
+
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -43,21 +47,6 @@ static const char copyright[] =
static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
#endif /* not lint */
#endif
-#ifdef __rtems__
-#define __need_getopt_newlib
-#include <getopt.h>
-#define RTEMS_BSD_PROGRAM_NO_OPEN_WRAP
-#define RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP
-#define RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP
-#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
-#include <machine/rtems-bsd-program.h>
-#include <machine/rtems-bsd-commands.h>
-#endif /* __rtems__ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -79,7 +68,14 @@ __FBSDID("$FreeBSD$");
* This program has to run SUID to ROOT to access the ICMP socket.
*/
+#ifdef __rtems__
+#define __need_getopt_newlib
+#include <getopt.h>
+#include <machine/rtems-bsd-program.h>
+#include <machine/rtems-bsd-commands.h>
+#endif /* __rtems__ */
#include <rtems/bsd/sys/param.h> /* NB: we rely on this for <sys/types.h> */
+#include <sys/capsicum.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/time.h>
@@ -92,6 +88,11 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_var.h>
#include <arpa/inet.h>
+#ifdef HAVE_LIBCASPER
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#endif
+
#ifdef IPSEC
#include <netipsec/ipsec.h>
#endif /*IPSEC*/
@@ -107,6 +108,9 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
+#ifdef __rtems__
+#include "rtems-bsd-ping-ping-data.h"
+#endif /* __rtems__ */
#define INADDR_LEN ((int)sizeof(in_addr_t))
#define TIMEVAL_LEN ((int)sizeof(struct tv32))
@@ -168,20 +172,20 @@ static int options;
* to 8192 for complete accuracy...
*/
#define MAX_DUP_CHK (8 * 128)
-static const int mx_dup_ck = MAX_DUP_CHK;
static char rcvd_tbl[MAX_DUP_CHK / 8];
static struct sockaddr_in whereto; /* who to ping */
static int datalen = DEFDATALEN;
static int maxpayload;
-static int s; /* socket file descriptor */
+static int ssend; /* send socket file descriptor */
+static int srecv; /* receive socket file descriptor */
static u_char outpackhdr[IP_MAXPACKET], *outpack;
-static const char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
-static const char BSPACE = '\b'; /* characters written for flood */
+static const char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
+static const char BSPACE = '\b'; /* characters written for flood */
static const char DOT = '.';
static char *hostname;
static char *shostname;
-static int ident; /* process id to identify our packets */
+static int ident; /* process id to identify our packets */
static int uid; /* cached uid for micro-optimization */
static u_char icmp_type = ICMP_ECHO;
static u_char icmp_type_rsp = ICMP_ECHOREPLY;
@@ -190,31 +194,49 @@ static int send_len;
/* counters */
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
-static long npackets; /* max packets to transmit */
-static long nreceived; /* # of packets we got back */
-static long nrepeats; /* number of duplicates */
-static long ntransmitted; /* sequence # for outbound packets = #sent */
+#ifndef __rtems__
+static long npackets; /* max packets to transmit */
+#else /* __rtems__ */
+static long npackets = 3; /* max packets to transmit */
+#endif /* __rtems__ */
+static long nreceived; /* # of packets we got back */
+static long nrepeats; /* number of duplicates */
+static long ntransmitted; /* sequence # for outbound packets = #sent */
static long snpackets; /* max packets to transmit in one sweep */
-static long sntransmitted; /* # of packets we sent in this sweep */
-static int sweepmax; /* max value of payload in sweep */
-static int sweepmin = 0; /* start value of payload in sweep */
-static int sweepincr = 1; /* payload increment in sweep */
-static int interval = 1000; /* interval between packets, ms */
-static int waittime = MAXWAIT; /* timeout for each packet */
-static long nrcvtimeout = 0; /* # of packets we got back after waittime */
+static long sntransmitted; /* # of packets we sent in this sweep */
+static int sweepmax; /* max value of payload in sweep */
+static int sweepmin = 0; /* start value of payload in sweep */
+static int sweepincr = 1; /* payload increment in sweep */
+static int interval = 1000; /* interval between packets, ms */
+static int waittime = MAXWAIT; /* timeout for each packet */
+static long nrcvtimeout = 0; /* # of packets we got back after waittime */
/* timing */
-static int timing; /* flag to do timing */
+static int timing; /* flag to do timing */
static double tmin = 999999999.0; /* minimum round trip time */
-static double tmax = 0.0; /* maximum round trip time */
-static double tsum = 0.0; /* sum of all times, for doing average */
-static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
+static double tmax = 0.0; /* maximum round trip time */
+static double tsum = 0.0; /* sum of all times, for doing average */
+static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
-static volatile sig_atomic_t finish_up; /* nonzero if we've been told to finish up */
+/* nonzero if we've been told to finish up */
+static volatile sig_atomic_t finish_up;
+#ifndef __rtems__
static volatile sig_atomic_t siginfo_p;
+#endif /* __rtems__ */
+
+#ifdef HAVE_LIBCASPER
+static cap_channel_t *capdns;
+#endif
+#ifdef __rtems__
+static u_char packet[IP_MAXPACKET] __aligned(4);
+static char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
+#endif /* __rtems__ */
static void fill(char *, char *);
static u_short in_cksum(u_short *, int);
+#ifdef HAVE_LIBCASPER
+static cap_channel_t *capdns_setup(void);
+#endif
static void check_status(void);
static void finish(void) __dead2;
static void pinger(void);
@@ -232,55 +254,32 @@ static void tvsub(struct timeval *, const struct timeval *);
static void usage(void) __dead2;
#ifdef __rtems__
-static int main(int argc, char **argv);
+static int main(int argc, char *argv[]);
+
+RTEMS_LINKER_RWSET(bsd_prog_ping, char);
-int rtems_bsd_command_ping(int argc, char *argv[])
+int
+rtems_bsd_command_ping(int argc, char *argv[])
{
int exit_code;
+ void *data_begin;
+ size_t data_size;
- rtems_bsd_program_lock();
-
- memset(&rcvd_tbl[0], 0, sizeof(rcvd_tbl));
- s = -1;
- memset(&outpackhdr[0], 0, sizeof(outpackhdr));
- icmp_type = ICMP_ECHO;
- icmp_type_rsp = ICMP_ECHOREPLY;
- phdr_len = 0;
- nmissedmax = 0;
- npackets = 3;
- nreceived = 0;
- nrepeats = 0;
- ntransmitted = 0;
- snpackets = 0;
- sntransmitted = 0;
- sweepmax = 0;
- sweepmin = 0;
- sweepincr = 1;
- interval = 1000;
- waittime = MAXWAIT;
- nrcvtimeout = 0;
- timing = 0;
- tmin = 999999999.0;
- tmax = 0.0;
- tsum = 0.0;
- tsumsq = 0.0;
- finish_up = 0;
- siginfo_p = 0;
-
- exit_code = rtems_bsd_program_call_main("ping", main, argc, argv);
+ data_begin = RTEMS_LINKER_SET_BEGIN(bsd_prog_ping);
+ data_size = RTEMS_LINKER_SET_SIZE(bsd_prog_ping);
+ rtems_bsd_program_lock();
+ exit_code = rtems_bsd_program_call_main_with_data_restore("ping",
+ main, argc, argv, data_begin, data_size);
rtems_bsd_program_unlock();
- close(s);
-
return exit_code;
}
-#endif /* __rtems__ */
int
-#ifndef __rtems__
-main(int argc, char *const *argv)
-#else /* __rtems__ */
main(int argc, char **argv)
+#else /* __rtems__ */
+int
+main(int argc, char *const *argv)
#endif /* __rtems__ */
{
struct sockaddr_in from, sock_in;
@@ -289,13 +288,14 @@ main(int argc, char **argv)
struct iovec iov;
struct ip *ip;
struct msghdr msg;
+#ifndef __rtems__
struct sigaction si_sa;
+#endif /* __rtems__ */
size_t sz;
#ifndef __rtems__
u_char *datap, packet[IP_MAXPACKET] __aligned(4);
#else /* __rtems__ */
u_char *datap;
- static u_char packet[IP_MAXPACKET] __aligned(4);
#endif /* __rtems__ */
char *ep, *source, *target, *payload;
struct hostent *hp;
@@ -305,19 +305,23 @@ main(int argc, char **argv)
struct sockaddr_in *to;
double t;
u_long alarmtimeout, ultmp;
- int almost_done, ch, df, hold, i, icmp_len, mib[4], preload, sockerrno,
- tos, ttl;
+ int almost_done, ch, df, hold, i, icmp_len, mib[4], preload;
+ int ssend_errno, srecv_errno, tos, ttl;
char ctrl[CMSG_SPACE(sizeof(struct timeval))];
#ifndef __rtems__
char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
-#else /* __rtems__ */
- static char hnamebuf[MAXHOSTNAMELEN];
- static char snamebuf[MAXHOSTNAMELEN];
#endif /* __rtems__ */
#ifdef IP_OPTIONS
char rspace[MAX_IPOPTLEN]; /* record route space */
#endif
unsigned char loop, mttl;
+
+ payload = source = NULL;
+#ifdef IPSEC_POLICY_IPSEC
+ policy_in = policy_out = NULL;
+#endif
+ cap_rights_t rights;
+ bool cansandbox;
#ifdef __rtems__
struct getopt_data getopt_data;
memset(&getopt_data, 0, sizeof(getopt_data));
@@ -328,22 +332,38 @@ main(int argc, char **argv)
#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
#endif /* __rtems__ */
- payload = source = NULL;
-#ifdef IPSEC_POLICY_IPSEC
- policy_in = policy_out = NULL;
-#endif
-
/*
* Do the stuff that we need root priv's for *first*, and
* then drop our setuid bit. Save error reporting for
* after arg parsing.
+ *
+ * Historicaly ping was using one socket 's' for sending and for
+ * receiving. After capsicum(4) related changes we use two
+ * sockets. It was done for special ping use case - when user
+ * issue ping on multicast or broadcast address replies come
+ * from different addresses, not from the address we
+ * connect(2)'ed to, and send socket do not receive those
+ * packets.
*/
- s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- sockerrno = errno;
+ ssend = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ ssend_errno = errno;
+ srecv = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ srecv_errno = errno;
- setuid(getuid());
+ if (setuid(getuid()) != 0)
+ err(EX_NOPERM, "setuid() failed");
uid = getuid();
+ if (ssend < 0) {
+ errno = ssend_errno;
+ err(EX_OSERR, "ssend socket");
+ }
+
+ if (srecv < 0) {
+ errno = srecv_errno;
+ err(EX_OSERR, "srecv socket");
+ }
+
alarmtimeout = df = preload = tos = 0;
outpack = outpackhdr + sizeof(struct ip);
@@ -612,13 +632,22 @@ main(int argc, char **argv)
if (options & F_PINGFILLED) {
fill((char *)datap, payload);
}
+#ifdef HAVE_LIBCASPER
+ capdns = capdns_setup();
+#endif
if (source) {
bzero((char *)&sock_in, sizeof(sock_in));
sock_in.sin_family = AF_INET;
if (inet_aton(source, &sock_in.sin_addr) != 0) {
shostname = source;
} else {
- hp = gethostbyname2(source, AF_INET);
+#ifdef HAVE_LIBCASPER
+ if (capdns != NULL)
+ hp = cap_gethostbyname2(capdns, source,
+ AF_INET);
+ else
+#endif
+ hp = gethostbyname2(source, AF_INET);
if (!hp)
errx(EX_NOHOST, "cannot resolve %s: %s",
source, hstrerror(h_errno));
@@ -634,7 +663,8 @@ main(int argc, char **argv)
snamebuf[sizeof(snamebuf) - 1] = '\0';
shostname = snamebuf;
}
- if (bind(s, (struct sockaddr *)&sock_in, sizeof sock_in) == -1)
+ if (bind(ssend, (struct sockaddr *)&sock_in, sizeof sock_in) ==
+ -1)
err(1, "bind");
}
@@ -645,7 +675,12 @@ main(int argc, char **argv)
if (inet_aton(target, &to->sin_addr) != 0) {
hostname = target;
} else {
- hp = gethostbyname2(target, AF_INET);
+#ifdef HAVE_LIBCASPER
+ if (capdns != NULL)
+ hp = cap_gethostbyname2(capdns, target, AF_INET);
+ else
+#endif
+ hp = gethostbyname2(target, AF_INET);
if (!hp)
errx(EX_NOHOST, "cannot resolve %s: %s",
target, hstrerror(h_errno));
@@ -658,6 +693,20 @@ main(int argc, char **argv)
hostname = hnamebuf;
}
+#ifdef HAVE_LIBCASPER
+ /* From now on we will use only reverse DNS lookups. */
+ if (capdns != NULL) {
+ const char *types[1];
+
+ types[0] = "ADDR";
+ if (cap_dns_type_limit(capdns, types, 1) < 0)
+ err(1, "unable to limit access to system.dns service");
+ }
+#endif
+
+ if (connect(ssend, (struct sockaddr *)&whereto, sizeof(whereto)) != 0)
+ err(1, "connect");
+
if (options & F_FLOOD && options & F_INTERVAL)
errx(EX_USAGE, "-f and -i: incompatible options");
@@ -678,16 +727,15 @@ main(int argc, char **argv)
ident = getpid() & 0xFFFF;
- if (s < 0) {
- errno = sockerrno;
- err(EX_OSERR, "socket");
- }
hold = 1;
- if (options & F_SO_DEBUG)
- (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ if (options & F_SO_DEBUG) {
+ (void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold,
sizeof(hold));
+ (void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ sizeof(hold));
+ }
if (options & F_SO_DONTROUTE)
- (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
+ (void)setsockopt(ssend, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
sizeof(hold));
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
@@ -697,7 +745,7 @@ main(int argc, char **argv)
buf = ipsec_set_policy(policy_in, strlen(policy_in));
if (buf == NULL)
errx(EX_CONFIG, "%s", ipsec_strerror());
- if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
+ if (setsockopt(srecv, IPPROTO_IP, IP_IPSEC_POLICY,
buf, ipsec_get_policylen(buf)) < 0)
err(EX_CONFIG,
"ipsec policy cannot be configured");
@@ -708,7 +756,7 @@ main(int argc, char **argv)
buf = ipsec_set_policy(policy_out, strlen(policy_out));
if (buf == NULL)
errx(EX_CONFIG, "%s", ipsec_strerror());
- if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
+ if (setsockopt(ssend, IPPROTO_IP, IP_IPSEC_POLICY,
buf, ipsec_get_policylen(buf)) < 0)
err(EX_CONFIG,
"ipsec policy cannot be configured");
@@ -729,17 +777,43 @@ main(int argc, char **argv)
if (sysctl(mib, 4, &ttl, &sz, NULL, 0) == -1)
err(1, "sysctl(net.inet.ip.ttl)");
}
- setsockopt(s, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
+ setsockopt(ssend, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
ip->ip_v = IPVERSION;
ip->ip_hl = sizeof(struct ip) >> 2;
ip->ip_tos = tos;
ip->ip_id = 0;
- ip->ip_off = df ? IP_DF : 0;
+ ip->ip_off = htons(df ? IP_DF : 0);
ip->ip_ttl = ttl;
ip->ip_p = IPPROTO_ICMP;
ip->ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
ip->ip_dst = to->sin_addr;
}
+
+ if (options & F_NUMERIC)
+ cansandbox = true;
+#ifdef HAVE_LIBCASPER
+ else if (capdns != NULL)
+ cansandbox = true;
+#endif
+ else
+ cansandbox = false;
+
+ /*
+ * Here we enter capability mode. Further down access to global
+ * namespaces (e.g filesystem) is restricted (see capsicum(4)).
+ * We must connect(2) our socket before this point.
+ */
+ if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
+ err(1, "cap_enter");
+
+ cap_rights_init(&rights, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
+ if (cap_rights_limit(srecv, &rights) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit srecv");
+
+ cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
+ if (cap_rights_limit(ssend, &rights) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit ssend");
+
/* record route option */
if (options & F_RROUTE) {
#ifdef IP_OPTIONS
@@ -748,7 +822,7 @@ main(int argc, char **argv)
rspace[IPOPT_OLEN] = sizeof(rspace) - 1;
rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
rspace[sizeof(rspace) - 1] = IPOPT_EOL;
- if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
+ if (setsockopt(ssend, IPPROTO_IP, IP_OPTIONS, rspace,
sizeof(rspace)) < 0)
err(EX_OSERR, "setsockopt IP_OPTIONS");
#else
@@ -758,38 +832,38 @@ main(int argc, char **argv)
}
if (options & F_TTL) {
- if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl,
+ if (setsockopt(ssend, IPPROTO_IP, IP_TTL, &ttl,
sizeof(ttl)) < 0) {
err(EX_OSERR, "setsockopt IP_TTL");
}
}
if (options & F_NOLOOP) {
- if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
+ if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
sizeof(loop)) < 0) {
err(EX_OSERR, "setsockopt IP_MULTICAST_LOOP");
}
}
if (options & F_MTTL) {
- if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &mttl,
+ if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_TTL, &mttl,
sizeof(mttl)) < 0) {
err(EX_OSERR, "setsockopt IP_MULTICAST_TTL");
}
}
if (options & F_MIF) {
- if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
+ if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
sizeof(ifaddr)) < 0) {
err(EX_OSERR, "setsockopt IP_MULTICAST_IF");
}
}
#ifdef SO_TIMESTAMP
{ int on = 1;
- if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
+ if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
err(EX_OSERR, "setsockopt SO_TIMESTAMP");
}
#endif
if (sweepmax) {
- if (sweepmin >= sweepmax)
- errx(EX_USAGE, "Maximum packet size must be greater than the minimum packet size");
+ if (sweepmin > sweepmax)
+ errx(EX_USAGE, "Maximum packet size must be no less than the minimum packet size");
if (datalen != DEFDATALEN)
errx(EX_USAGE, "Packet size and ping sweep are mutually exclusive");
@@ -802,7 +876,7 @@ main(int argc, char **argv)
datalen = sweepmin;
send_len = icmp_len + sweepmin;
}
- if (options & F_SWEEP && !sweepmax)
+ if (options & F_SWEEP && !sweepmax)
errx(EX_USAGE, "Maximum sweep size must be specified");
/*
@@ -818,11 +892,19 @@ main(int argc, char **argv)
* as well.
*/
hold = IP_MAXPACKET + 128;
- (void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
+ (void)setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
sizeof(hold));
+ /* CAP_SETSOCKOPT removed */
+ cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
+ if (cap_rights_limit(srecv, &rights) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit srecv setsockopt");
if (uid == 0)
- (void)setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
+ (void)setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
sizeof(hold));
+ /* CAP_SETSOCKOPT removed */
+ cap_rights_init(&rights, CAP_SEND);
+ if (cap_rights_limit(ssend, &rights) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit ssend setsockopt");
if (to->sin_family == AF_INET) {
(void)printf("PING %s (%s)", hostname,
@@ -832,9 +914,9 @@ main(int argc, char **argv)
if (sweepmax)
(void)printf(": (%d ... %d) data bytes\n",
sweepmin, sweepmax);
- else
+ else
(void)printf(": %d data bytes\n", datalen);
-
+
} else {
if (sweepmax)
(void)printf("PING %s: (%d ... %d) data bytes\n",
@@ -867,8 +949,6 @@ main(int argc, char **argv)
if (sigaction(SIGALRM, &si_sa, 0) == -1)
err(EX_OSERR, "sigaction SIGALRM");
}
-#else /* __rtems__ */
- (void) si_sa;
#endif /* __rtems__ */
bzero(&msg, sizeof(msg));
@@ -906,10 +986,10 @@ main(int argc, char **argv)
int cc, n;
check_status();
- if ((unsigned)s >= FD_SETSIZE)
+ if ((unsigned)srecv >= FD_SETSIZE)
errx(EX_OSERR, "descriptor too large");
FD_ZERO(&rfds);
- FD_SET(s, &rfds);
+ FD_SET(srecv, &rfds);
(void)gettimeofday(&now, NULL);
timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
@@ -922,8 +1002,8 @@ main(int argc, char **argv)
timeout.tv_sec++;
}
if (timeout.tv_sec < 0)
- timeout.tv_sec = timeout.tv_usec = 0;
- n = select(s + 1, &rfds, NULL, NULL, &timeout);
+ timerclear(&timeout);
+ n = select(srecv + 1, &rfds, NULL, NULL, &timeout);
if (n < 0)
continue; /* Must be EINTR. */
if (n == 1) {
@@ -934,7 +1014,7 @@ main(int argc, char **argv)
msg.msg_controllen = sizeof(ctrl);
#endif
msg.msg_namelen = sizeof(from);
- if ((cc = recvmsg(s, &msg, 0)) < 0) {
+ if ((cc = recvmsg(srecv, &msg, 0)) < 0) {
if (errno == EINTR)
continue;
warn("recvmsg");
@@ -960,14 +1040,14 @@ main(int argc, char **argv)
}
if (n == 0 || options & F_FLOOD) {
if (sweepmax && sntransmitted == snpackets) {
- for (i = 0; i < sweepincr ; ++i)
+ for (i = 0; i < sweepincr ; ++i)
*datap++ = i;
datalen += sweepincr;
if (datalen > sweepmax)
break;
send_len = icmp_len + datalen;
sntransmitted = 0;
- }
+ }
if (!npackets || ntransmitted < npackets)
pinger();
else {
@@ -1044,7 +1124,7 @@ pinger(void)
icp->icmp_seq = htons(ntransmitted);
icp->icmp_id = ident; /* ID */
- CLR(ntransmitted % mx_dup_ck);
+ CLR(ntransmitted % MAX_DUP_CHK);
if ((options & F_TIME) || timing) {
(void)gettimeofday(&now, NULL);
@@ -1068,13 +1148,11 @@ pinger(void)
if (options & F_HDRINCL) {
cc += sizeof(struct ip);
ip = (struct ip *)outpackhdr;
- ip->ip_len = cc;
+ ip->ip_len = htons(cc);
ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
packet = outpackhdr;
}
- i = sendto(s, (char *)packet, cc, 0, (struct sockaddr *)&whereto,
- sizeof(whereto));
-
+ i = send(ssend, (char *)packet, cc, 0);
if (i < 0 || i != cc) {
if (i < 0) {
if (options & F_FLOOD && errno == ENOBUFS) {
@@ -1142,7 +1220,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
#endif
tp = (const char *)tp + phdr_len;
- if (cc - ICMP_MINLEN - phdr_len >= sizeof(tv1)) {
+ if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
+ sizeof(tv1)) {
/* Copy to avoid alignment problems: */
memcpy(&tv32, tp, sizeof(tv32));
tv1.tv_sec = ntohl(tv32.tv32_sec);
@@ -1162,18 +1241,18 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
seq = ntohs(icp->icmp_seq);
- if (TST(seq % mx_dup_ck)) {
+ if (TST(seq % MAX_DUP_CHK)) {
++nrepeats;
--nreceived;
dupflag = 1;
} else {
- SET(seq % mx_dup_ck);
+ SET(seq % MAX_DUP_CHK);
dupflag = 0;
}
if (options & F_QUIET)
return;
-
+
if (options & F_WAITTIME && triptime > waittime) {
++nrcvtimeout;
return;
@@ -1195,7 +1274,7 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
if (options & F_MASK) {
/* Just prentend this cast isn't ugly */
(void)printf(" mask=%s",
- pr_addr(*(struct in_addr *)&(icp->icmp_mask)));
+ inet_ntoa(*(struct in_addr *)&(icp->icmp_mask)));
}
if (options & F_TIME) {
(void)printf(" tso=%s", pr_ntime(icp->icmp_otime));
@@ -1437,6 +1516,7 @@ static void
check_status(void)
{
+#ifndef __rtems__
if (siginfo_p) {
siginfo_p = 0;
(void)fprintf(stderr, "\r%ld/%ld packets received (%.1f%%)",
@@ -1447,6 +1527,7 @@ check_status(void)
tmin, tsum / (nreceived + nrepeats), tmax);
(void)fprintf(stderr, "\n");
}
+#endif /* __rtems__ */
}
/*
@@ -1697,12 +1778,21 @@ pr_addr(struct in_addr ina)
struct hostent *hp;
static char buf[16 + 3 + MAXHOSTNAMELEN];
- if ((options & F_NUMERIC) ||
- !(hp = gethostbyaddr((char *)&ina, 4, AF_INET)))
+ if (options & F_NUMERIC)
return inet_ntoa(ina);
+
+#ifdef HAVE_LIBCASPER
+ if (capdns != NULL)
+ hp = cap_gethostbyaddr(capdns, (char *)&ina, 4, AF_INET);
else
- (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,
- inet_ntoa(ina));
+#endif
+ hp = gethostbyaddr((char *)&ina, 4, AF_INET);
+
+ if (hp == NULL)
+ return inet_ntoa(ina);
+
+ (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,
+ inet_ntoa(ina));
return(buf);
}
@@ -1752,7 +1842,7 @@ fill(char *bp, char *patp)
u_int ii, jj, kk;
for (cp = patp; *cp; cp++) {
- if (!isxdigit((unsigned char) *cp))
+ if (!isxdigit((unsigned char)*cp))
errx(EX_USAGE,
"patterns must be specified as hex digits");
@@ -1775,6 +1865,34 @@ fill(char *bp, char *patp)
}
}
+#ifdef HAVE_LIBCASPER
+static cap_channel_t *
+capdns_setup(void)
+{
+ cap_channel_t *capcas, *capdnsloc;
+ const char *types[2];
+ int families[1];
+
+ capcas = cap_init();
+ if (capcas == NULL)
+ err(1, "unable to create casper process");
+ capdnsloc = cap_service_open(capcas, "system.dns");
+ /* Casper capability no longer needed. */
+ cap_close(capcas);
+ if (capdnsloc == NULL)
+ err(1, "unable to open system.dns service");
+ types[0] = "NAME";
+ types[1] = "ADDR";
+ if (cap_dns_type_limit(capdnsloc, types, 2) < 0)
+ err(1, "unable to limit access to system.dns service");
+ families[0] = AF_INET;
+ if (cap_dns_family_limit(capdnsloc, families, 1) < 0)
+ err(1, "unable to limit access to system.dns service");
+
+ return (capdnsloc);
+}
+#endif /* HAVE_LIBCASPER */
+
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
#define SECOPT " [-P policy]"
#else