diff options
Diffstat (limited to 'freebsd/sbin/ping/ping.c')
-rw-r--r-- | freebsd/sbin/ping/ping.c | 386 |
1 files changed, 172 insertions, 214 deletions
diff --git a/freebsd/sbin/ping/ping.c b/freebsd/sbin/ping/ping.c index 5df1e875..e31941b8 100644 --- a/freebsd/sbin/ping/ping.c +++ b/freebsd/sbin/ping/ping.c @@ -104,16 +104,20 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <math.h> #include <netdb.h> +#include <stddef.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> +#include <time.h> #include <unistd.h> #ifdef __rtems__ #include "rtems-bsd-ping-ping-data.h" #endif /* __rtems__ */ +#include "utils.h" + #define INADDR_LEN ((int)sizeof(in_addr_t)) #define TIMEVAL_LEN ((int)sizeof(struct tv32)) #define MASK_LEN (ICMP_MASKLEN - ICMP_MINLEN) @@ -135,7 +139,7 @@ __FBSDID("$FreeBSD$"); struct tv32 { int32_t tv32_sec; - int32_t tv32_usec; + int32_t tv32_nsec; }; /* various options */ @@ -235,7 +239,6 @@ static char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN]; #endif /* __rtems__ */ static void fill(char *, char *); -static u_short in_cksum(u_short *, int); #ifndef __rtems__ static cap_channel_t *capdns_setup(void); #endif /* __rtems__ */ @@ -244,15 +247,14 @@ static void finish(void) __dead2; static void pinger(void); static char *pr_addr(struct in_addr); static char *pr_ntime(n_time); -static void pr_icmph(struct icmp *); +static void pr_icmph(struct icmp *, struct ip *, const u_char *const); static void pr_iph(struct ip *); -static void pr_pack(char *, int, struct sockaddr_in *, struct timeval *); -static void pr_retip(struct ip *); +static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *); +static void pr_retip(struct ip *, const u_char *); #ifndef __rtems__ static void status(int); static void stopit(int); #endif /* __rtems__ */ -static void tvsub(struct timeval *, const struct timeval *); static void usage(void) __dead2; #ifdef __rtems__ @@ -286,9 +288,8 @@ main(int argc, char *const *argv) { struct sockaddr_in from, sock_in; struct in_addr ifaddr; - struct timeval last, intvl; + struct timespec last, intvl; struct iovec iov; - struct ip *ip; struct msghdr msg; #ifndef __rtems__ struct sigaction si_sa; @@ -310,7 +311,7 @@ main(int argc, char *const *argv) long ltmp; 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))]; + char ctrl[CMSG_SPACE(sizeof(struct timespec))]; #ifndef __rtems__ char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN]; #endif /* __rtems__ */ @@ -335,6 +336,8 @@ main(int argc, char *const *argv) #define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data) #endif /* __rtems__ */ + options |= F_NUMERIC; + /* * Do the stuff that we need root priv's for *first*, and * then drop our setuid bit. Save error reporting for @@ -371,7 +374,7 @@ main(int argc, char *const *argv) outpack = outpackhdr + sizeof(struct ip); while ((ch = getopt(argc, argv, - "Aac:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" + "Aac:DdfG:g:Hh:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC "P:" @@ -437,6 +440,9 @@ main(int argc, char *const *argv) options |= F_SWEEP; sweepmin = ltmp; break; + case 'H': + options &= ~F_NUMERIC; + break; case 'h': /* Packet size increment for ping sweep */ ltmp = strtol(optarg, &ep, 0); if (*ep || ep == optarg || ltmp < 1) @@ -685,8 +691,8 @@ main(int argc, char *const *argv) hostname = hnamebuf; } -#ifndef __rtems__ /* From now on we will use only reverse DNS lookups. */ +#ifdef WITH_CASPER if (capdns != NULL) { const char *types[1]; @@ -694,7 +700,7 @@ main(int argc, char *const *argv) if (cap_dns_type_limit(capdns, types, 1) < 0) err(1, "unable to limit access to system.dns service"); } -#endif /* __rtems__ */ +#endif if (connect(ssend, (struct sockaddr *)&whereto, sizeof(whereto)) != 0) err(1, "connect"); @@ -759,7 +765,9 @@ main(int argc, char *const *argv) #endif /*IPSEC*/ if (options & F_HDRINCL) { - ip = (struct ip*)outpackhdr; + struct ip ip; + + memcpy(&ip, outpackhdr, sizeof(ip)); if (!(options & (F_TTL | F_MTTL))) { mib[0] = CTL_NET; mib[1] = PF_INET; @@ -770,15 +778,16 @@ main(int argc, char *const *argv) err(1, "sysctl(net.inet.ip.ttl)"); } 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 = 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; + ip.ip_v = IPVERSION; + ip.ip_hl = sizeof(struct ip) >> 2; + ip.ip_tos = tos; + ip.ip_id = 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; + memcpy(outpackhdr, &ip, sizeof(ip)); } #ifndef __rtems__ @@ -789,7 +798,7 @@ main(int argc, char *const *argv) */ caph_cache_catpages(); if (caph_enter_casper() < 0) - err(1, "cap_enter"); + err(1, "caph_enter_casper"); cap_rights_init(&rights, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT); if (caph_rights_limit(srecv, &rights) < 0) @@ -841,9 +850,15 @@ main(int argc, char *const *argv) } } #ifdef SO_TIMESTAMP - { int on = 1; - if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0) - err(EX_OSERR, "setsockopt SO_TIMESTAMP"); + { + int on = 1; + int ts_clock = SO_TS_MONOTONIC; + if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on, + sizeof(on)) < 0) + err(EX_OSERR, "setsockopt SO_TIMESTAMP"); + if (setsockopt(srecv, SOL_SOCKET, SO_TS_CLOCK, &ts_clock, + sizeof(ts_clock)) < 0) + err(EX_OSERR, "setsockopt SO_TS_CLOCK"); } #endif if (sweepmax) { @@ -946,6 +961,7 @@ main(int argc, char *const *argv) msg.msg_iovlen = 1; #ifdef SO_TIMESTAMP msg.msg_control = (caddr_t)ctrl; + msg.msg_controllen = sizeof(ctrl); #endif iov.iov_base = packet; iov.iov_len = IP_MAXPACKET; @@ -958,19 +974,19 @@ main(int argc, char *const *argv) while (preload--) /* fire off them quickies */ pinger(); } - (void)gettimeofday(&last, NULL); + (void)clock_gettime(CLOCK_MONOTONIC, &last); if (options & F_FLOOD) { intvl.tv_sec = 0; - intvl.tv_usec = 10000; + intvl.tv_nsec = 10000000; } else { intvl.tv_sec = interval / 1000; - intvl.tv_usec = interval % 1000 * 1000; + intvl.tv_nsec = interval % 1000 * 1000000; } almost_done = 0; while (!finish_up) { - struct timeval now, timeout; + struct timespec now, timeout; #ifndef __rtems__ fd_set rfds; #else /* __rtems__ */ @@ -978,7 +994,8 @@ main(int argc, char *const *argv) sizeof(fd_set) * 8)]; #define rfds (*(fd_set *)(&big_enough_rfds[0])) #endif /* __rtems__ */ - int cc, n; + int n; + ssize_t cc; check_status(); #ifndef __rtems__ @@ -989,28 +1006,18 @@ main(int argc, char *const *argv) memset(big_enough_rfds, 0, sizeof(big_enough_rfds)); #endif /* __rtems__ */ 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; - while (timeout.tv_usec < 0) { - timeout.tv_usec += 1000000; - timeout.tv_sec--; - } - while (timeout.tv_usec >= 1000000) { - timeout.tv_usec -= 1000000; - timeout.tv_sec++; - } + (void)clock_gettime(CLOCK_MONOTONIC, &now); + timespecadd(&last, &intvl, &timeout); + timespecsub(&timeout, &now, &timeout); if (timeout.tv_sec < 0) - timerclear(&timeout); - n = select(srecv + 1, &rfds, NULL, NULL, &timeout); + timespecclear(&timeout); + n = pselect(srecv + 1, &rfds, NULL, NULL, &timeout, NULL); if (n < 0) continue; /* Must be EINTR. */ if (n == 1) { - struct timeval *tv = NULL; + struct timespec *tv = NULL; #ifdef SO_TIMESTAMP - struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl; - - msg.msg_controllen = sizeof(ctrl); + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); #endif msg.msg_namelen = sizeof(from); if ((cc = recvmsg(srecv, &msg, 0)) < 0) { @@ -1020,7 +1027,8 @@ main(int argc, char *const *argv) continue; } #ifdef SO_TIMESTAMP - if (cmsg->cmsg_level == SOL_SOCKET && + if (cmsg != NULL && + cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP && cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) { /* Copy to avoid alignment problems: */ @@ -1029,7 +1037,7 @@ main(int argc, char *const *argv) } #endif if (tv == NULL) { - (void)gettimeofday(&now, NULL); + (void)clock_gettime(CLOCK_MONOTONIC, &now); tv = &now; } pr_pack((char *)packet, cc, &from, tv); @@ -1053,17 +1061,17 @@ main(int argc, char *const *argv) if (almost_done) break; almost_done = 1; - intvl.tv_usec = 0; + intvl.tv_nsec = 0; if (nreceived) { intvl.tv_sec = 2 * tmax / 1000; if (!intvl.tv_sec) intvl.tv_sec = 1; } else { intvl.tv_sec = waittime / 1000; - intvl.tv_usec = waittime % 1000 * 1000; + intvl.tv_nsec = waittime % 1000 * 1000000; } } - (void)gettimeofday(&last, NULL); + (void)clock_gettime(CLOCK_MONOTONIC, &last); if (ntransmitted - nreceived - 1 > nmissedmax) { nmissedmax = ntransmitted - nreceived - 1; if (options & F_MISSED) @@ -1102,53 +1110,69 @@ stopit(int sig __unused) * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet * will be added on by the kernel. The ID field is our UNIX process ID, * and the sequence number is an ascending integer. The first TIMEVAL_LEN - * bytes of the data portion are used to hold a UNIX "timeval" struct in + * bytes of the data portion are used to hold a UNIX "timespec" struct in * host byte-order, to compute the round-trip time. */ static void pinger(void) { - struct timeval now; + struct timespec now; struct tv32 tv32; - struct ip *ip; - struct icmp *icp; + struct icmp icp; int cc, i; u_char *packet; packet = outpack; - icp = (struct icmp *)outpack; - icp->icmp_type = icmp_type; - icp->icmp_code = 0; - icp->icmp_cksum = 0; - icp->icmp_seq = htons(ntransmitted); - icp->icmp_id = ident; /* ID */ + memcpy(&icp, outpack, ICMP_MINLEN + phdr_len); + icp.icmp_type = icmp_type; + icp.icmp_code = 0; + icp.icmp_cksum = 0; + icp.icmp_seq = htons(ntransmitted); + icp.icmp_id = ident; /* ID */ CLR(ntransmitted % MAX_DUP_CHK); if ((options & F_TIME) || timing) { - (void)gettimeofday(&now, NULL); - - tv32.tv32_sec = htonl(now.tv_sec); - tv32.tv32_usec = htonl(now.tv_usec); + (void)clock_gettime(CLOCK_MONOTONIC, &now); + /* + * Truncate seconds down to 32 bits in order + * to fit the timestamp within 8 bytes of the + * packet. We're only concerned with + * durations, not absolute times. + */ + tv32.tv32_sec = (uint32_t)htonl(now.tv_sec); + tv32.tv32_nsec = (uint32_t)htonl(now.tv_nsec); if (options & F_TIME) - icp->icmp_otime = htonl((now.tv_sec % (24*60*60)) - * 1000 + now.tv_usec / 1000); + icp.icmp_otime = htonl((now.tv_sec % (24*60*60)) + * 1000 + now.tv_nsec / 1000000); if (timing) bcopy((void *)&tv32, (void *)&outpack[ICMP_MINLEN + phdr_len], sizeof(tv32)); } + memcpy(outpack, &icp, ICMP_MINLEN + phdr_len); + cc = ICMP_MINLEN + phdr_len + datalen; /* compute ICMP checksum here */ - icp->icmp_cksum = in_cksum((u_short *)icp, cc); + icp.icmp_cksum = in_cksum(outpack, cc); + /* Update icmp_cksum in the raw packet data buffer. */ + memcpy(outpack + offsetof(struct icmp, icmp_cksum), &icp.icmp_cksum, + sizeof(icp.icmp_cksum)); if (options & F_HDRINCL) { + struct ip ip; + cc += sizeof(struct ip); - ip = (struct ip *)outpackhdr; - ip->ip_len = htons(cc); - ip->ip_sum = in_cksum((u_short *)outpackhdr, cc); + ip.ip_len = htons(cc); + /* Update ip_len in the raw packet data buffer. */ + memcpy(outpackhdr + offsetof(struct ip, ip_len), &ip.ip_len, + sizeof(ip.ip_len)); + ip.ip_sum = in_cksum(outpackhdr, cc); + /* Update ip_sum in the raw packet data buffer. */ + memcpy(outpackhdr + offsetof(struct ip, ip_sum), &ip.ip_sum, + sizeof(ip.ip_sum)); packet = outpackhdr; } i = send(ssend, (char *)packet, cc, 0); @@ -1178,56 +1202,71 @@ pinger(void) * program to be run without having intermingled output (or statistics!). */ static void -pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) +pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv) { struct in_addr ina; - u_char *cp, *dp; - struct icmp *icp; - struct ip *ip; - const void *tp; + u_char *cp, *dp, l; + struct icmp icp; + struct ip ip; + const u_char *icmp_data_raw; double triptime; - int dupflag, hlen, i, j, recv_len, seq; + int dupflag, hlen, i, j, recv_len; + uint16_t seq; static int old_rrlen; static char old_rr[MAX_IPOPTLEN]; + struct ip oip; + u_char oip_header_len; + struct icmp oicmp; + const u_char *oicmp_raw; + + /* + * Get size of IP header of the received packet. The + * information is contained in the lower four bits of the + * first byte. + */ + memcpy(&l, buf, sizeof(l)); + hlen = (l & 0x0f) << 2; + memcpy(&ip, buf, hlen); /* Check the IP header */ - ip = (struct ip *)buf; - hlen = ip->ip_hl << 2; recv_len = cc; if (cc < hlen + ICMP_MINLEN) { if (options & F_VERBOSE) - warn("packet too short (%d bytes) from %s", cc, + warn("packet too short (%zd bytes) from %s", cc, inet_ntoa(from->sin_addr)); return; } +#ifndef icmp_data + icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_ip); +#else + icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_data); +#endif + /* Now the ICMP part */ cc -= hlen; - icp = (struct icmp *)(buf + hlen); - if (icp->icmp_type == icmp_type_rsp) { - if (icp->icmp_id != ident) + memcpy(&icp, buf + hlen, MIN((ssize_t)sizeof(icp), cc)); + if (icp.icmp_type == icmp_type_rsp) { + if (icp.icmp_id != ident) return; /* 'Twas not our ECHO */ ++nreceived; triptime = 0.0; if (timing) { - struct timeval tv1; + struct timespec tv1; struct tv32 tv32; -#ifndef icmp_data - tp = &icp->icmp_ip; -#else - tp = icp->icmp_data; -#endif - tp = (const char *)tp + phdr_len; + const u_char *tp; + + tp = icmp_data_raw + phdr_len; 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); - tv1.tv_usec = ntohl(tv32.tv32_usec); - tvsub(tv, &tv1); + tv1.tv_nsec = ntohl(tv32.tv32_nsec); + timespecsub(tv, &tv1, tv); triptime = ((double)tv->tv_sec) * 1000.0 + - ((double)tv->tv_usec) / 1000.0; + ((double)tv->tv_nsec) / 1000000.0; tsum += triptime; tsumsq += triptime * triptime; if (triptime < tmin) @@ -1238,7 +1277,7 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) timing = 0; } - seq = ntohs(icp->icmp_seq); + seq = ntohs(icp.icmp_seq); if (TST(seq % MAX_DUP_CHK)) { ++nrepeats; @@ -1260,10 +1299,9 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) if (options & F_FLOOD) (void)write(STDOUT_FILENO, &BSPACE, 1); else { - (void)printf("%d bytes from %s: icmp_seq=%u", cc, - inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr), - seq); - (void)printf(" ttl=%d", ip->ip_ttl); + (void)printf("%zd bytes from %s: icmp_seq=%u", cc, + pr_addr(from->sin_addr), seq); + (void)printf(" ttl=%d", ip.ip_ttl); if (timing) (void)printf(" time=%.3f ms", triptime); if (dupflag) @@ -1273,12 +1311,12 @@ 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", - inet_ntoa(*(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)); - (void)printf(" tsr=%s", pr_ntime(icp->icmp_rtime)); - (void)printf(" tst=%s", pr_ntime(icp->icmp_ttime)); + (void)printf(" tso=%s", pr_ntime(icp.icmp_otime)); + (void)printf(" tsr=%s", pr_ntime(icp.icmp_rtime)); + (void)printf(" tst=%s", pr_ntime(icp.icmp_ttime)); } if (recv_len != send_len) { (void)printf( @@ -1286,7 +1324,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) recv_len, send_len); } /* check the data */ - cp = (u_char*)&icp->icmp_data[phdr_len]; + cp = (u_char*)(buf + hlen + offsetof(struct icmp, + icmp_data) + phdr_len); dp = &outpack[ICMP_MINLEN + phdr_len]; cc -= ICMP_MINLEN + phdr_len; i = 0; @@ -1301,7 +1340,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); (void)printf("\ncp:"); - cp = (u_char*)&icp->icmp_data[0]; + cp = (u_char*)(buf + hlen + + offsetof(struct icmp, icmp_data)); for (i = 0; i < datalen; ++i, ++cp) { if ((i % 16) == 8) (void)printf("\n\t"); @@ -1329,22 +1369,22 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) * as root to avoid leaking information not normally * available to those not running as root. */ -#ifndef icmp_data - struct ip *oip = &icp->icmp_ip; -#else - struct ip *oip = (struct ip *)icp->icmp_data; -#endif - struct icmp *oicmp = (struct icmp *)(oip + 1); + memcpy(&oip_header_len, icmp_data_raw, sizeof(oip_header_len)); + oip_header_len = (oip_header_len & 0x0f) << 2; + memcpy(&oip, icmp_data_raw, oip_header_len); + oicmp_raw = icmp_data_raw + oip_header_len; + memcpy(&oicmp, oicmp_raw, offsetof(struct icmp, icmp_id) + + sizeof(oicmp.icmp_id)); if (((options & F_VERBOSE) && uid == 0) || (!(options & F_QUIET2) && - (oip->ip_dst.s_addr == whereto.sin_addr.s_addr) && - (oip->ip_p == IPPROTO_ICMP) && - (oicmp->icmp_type == ICMP_ECHO) && - (oicmp->icmp_id == ident))) { - (void)printf("%d bytes from %s: ", cc, + (oip.ip_dst.s_addr == whereto.sin_addr.s_addr) && + (oip.ip_p == IPPROTO_ICMP) && + (oicmp.icmp_type == ICMP_ECHO) && + (oicmp.icmp_id == ident))) { + (void)printf("%zd bytes from %s: ", cc, pr_addr(from->sin_addr)); - pr_icmph(icp); + pr_icmph(&icp, &oip, oicmp_raw); } else return; } @@ -1438,65 +1478,6 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) } } -/* - * in_cksum -- - * Checksum routine for Internet Protocol family headers (C Version) - */ -u_short -in_cksum(u_short *addr, int len) -{ - int nleft, sum; - u_short *w; - union { - u_short us; - u_char uc[2]; - } last; - u_short answer; - - nleft = len; - sum = 0; - w = addr; - - /* - * Our algorithm is simple, using a 32 bit accumulator (sum), we add - * sequential 16 bit words to it, and at the end, fold back all the - * carry bits from the top 16 bits into the lower 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - /* mop up an odd byte, if necessary */ - if (nleft == 1) { - last.uc[0] = *(u_char *)w; - last.uc[1] = 0; - sum += last.us; - } - - /* add back carry outs from top 16 bits to low 16 bits */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return(answer); -} - -/* - * tvsub -- - * Subtract 2 timeval structs: out = out - in. Out is assumed to - * be >= in. - */ -static void -tvsub(struct timeval *out, const struct timeval *in) -{ - - if ((out->tv_usec -= in->tv_usec) < 0) { - --out->tv_sec; - out->tv_usec += 1000000; - } - out->tv_sec -= in->tv_sec; -} - #ifndef __rtems__ /* * status -- @@ -1593,7 +1574,7 @@ static char *ttab[] = { * Print a descriptive string about an ICMP header. */ static void -pr_icmph(struct icmp *icp) +pr_icmph(struct icmp *icp, struct ip *oip, const u_char *const oicmp_raw) { switch(icp->icmp_type) { @@ -1631,19 +1612,11 @@ pr_icmph(struct icmp *icp) break; } /* Print returned IP header information */ -#ifndef icmp_data - pr_retip(&icp->icmp_ip); -#else - pr_retip((struct ip *)icp->icmp_data); -#endif + pr_retip(oip, oicmp_raw); break; case ICMP_SOURCEQUENCH: (void)printf("Source Quench\n"); -#ifndef icmp_data - pr_retip(&icp->icmp_ip); -#else - pr_retip((struct ip *)icp->icmp_data); -#endif + pr_retip(oip, oicmp_raw); break; case ICMP_REDIRECT: switch(icp->icmp_code) { @@ -1664,11 +1637,7 @@ pr_icmph(struct icmp *icp) break; } (void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr)); -#ifndef icmp_data - pr_retip(&icp->icmp_ip); -#else - pr_retip((struct ip *)icp->icmp_data); -#endif + pr_retip(oip, oicmp_raw); break; case ICMP_ECHO: (void)printf("Echo Request\n"); @@ -1687,20 +1656,12 @@ pr_icmph(struct icmp *icp) icp->icmp_code); break; } -#ifndef icmp_data - pr_retip(&icp->icmp_ip); -#else - pr_retip((struct ip *)icp->icmp_data); -#endif + pr_retip(oip, oicmp_raw); break; case ICMP_PARAMPROB: (void)printf("Parameter problem: pointer = 0x%02x\n", icp->icmp_hun.ih_pptr); -#ifndef icmp_data - pr_retip(&icp->icmp_ip); -#else - pr_retip((struct ip *)icp->icmp_data); -#endif + pr_retip(oip, oicmp_raw); break; case ICMP_TSTAMP: (void)printf("Timestamp\n"); @@ -1798,14 +1759,9 @@ pr_addr(struct in_addr ina) * Dump some info on a returned (via ICMP) IP packet. */ static void -pr_retip(struct ip *ip) +pr_retip(struct ip *ip, const u_char *cp) { - u_char *cp; - int hlen; - pr_iph(ip); - hlen = ip->ip_hl << 2; - cp = (u_char *)ip + hlen; if (ip->ip_p == 6) (void)printf("TCP: from port %u, to port %u (decimal)\n", @@ -1818,7 +1774,7 @@ pr_retip(struct ip *ip) static char * pr_ntime(n_time timestamp) { - static char buf[10]; + static char buf[11]; int hour, min, sec; sec = ntohl(timestamp) / 1000; @@ -1867,9 +1823,10 @@ static cap_channel_t * capdns_setup(void) { cap_channel_t *capcas, *capdnsloc; +#ifdef WITH_CASPER const char *types[2]; int families[1]; - +#endif capcas = cap_init(); if (capcas == NULL) err(1, "unable to create casper process"); @@ -1878,6 +1835,7 @@ capdns_setup(void) cap_close(capcas); if (capdnsloc == NULL) err(1, "unable to open system.dns service"); +#ifdef WITH_CASPER types[0] = "NAME2ADDR"; types[1] = "ADDR2NAME"; if (cap_dns_type_limit(capdnsloc, types, 2) < 0) @@ -1885,7 +1843,7 @@ capdns_setup(void) families[0] = AF_INET; if (cap_dns_family_limit(capdnsloc, families, 1) < 0) err(1, "unable to limit access to system.dns service"); - +#endif return (capdnsloc); } #endif /* __rtems__ */ @@ -1900,11 +1858,11 @@ usage(void) { (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", -"usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]", +"usage: ping [-AaDdfHnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]", " [-h sweepincrsize] [-i wait] [-l preload] [-M mask | time] [-m ttl]", " " SECOPT " [-p pattern] [-S src_addr] [-s packetsize] [-t timeout]", " [-W waittime] [-z tos] host", -" ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]", +" ping [-AaDdfHLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]", " [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]", " [-s packetsize] [-T ttl] [-t timeout] [-W waittime]", " [-z tos] mcast-group"); |