diff options
Diffstat (limited to 'freebsd/sbin/ping/ping.c')
-rw-r--r-- | freebsd/sbin/ping/ping.c | 396 |
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 |