Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139405267
D38431.id116747.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D38431.id116747.diff
View Options
diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile
--- a/sbin/ping/Makefile
+++ b/sbin/ping/Makefile
@@ -10,6 +10,7 @@
BINOWN= root
BINMODE=4555
LIBADD= m
+NO_WCAST_ALIGN=
.if ${MK_INET_SUPPORT}!= "no"
CFLAGS+= -DINET
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -91,7 +91,6 @@
#include <errno.h>
#include <math.h>
#include <netdb.h>
-#include <stddef.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -224,10 +223,10 @@
static void pinger(void);
static char *pr_addr(struct in_addr);
static char *pr_ntime(n_time);
-static void pr_icmph(struct icmp *, struct ip *, const u_char *const);
+static void pr_icmph(struct icmp *);
static void pr_iph(struct ip *);
-static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *);
-static void pr_retip(struct ip *, const u_char *);
+static void pr_pack(char *, int, struct sockaddr_in *, struct timespec *);
+static void pr_retip(struct ip *);
static void status(int);
static void stopit(int);
@@ -238,6 +237,7 @@
struct in_addr ifaddr;
struct timespec last, intvl;
struct iovec iov;
+ struct ip *ip;
struct msghdr msg;
struct sigaction si_sa;
size_t sz;
@@ -715,9 +715,7 @@
#endif /*IPSEC*/
if (options & F_HDRINCL) {
- struct ip ip;
-
- memcpy(&ip, outpackhdr, sizeof(ip));
+ ip = (struct ip*)outpackhdr;
if (!(options & (F_TTL | F_MTTL))) {
mib[0] = CTL_NET;
mib[1] = PF_INET;
@@ -728,16 +726,15 @@
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;
- memcpy(outpackhdr, &ip, sizeof(ip));
+ 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;
}
/*
@@ -935,8 +932,7 @@
while (!finish_up) {
struct timespec now, timeout;
fd_set rfds;
- int n;
- ssize_t cc;
+ int cc, n;
check_status();
if ((unsigned)srecv >= FD_SETSIZE)
@@ -963,9 +959,6 @@
warn("recvmsg");
continue;
}
- /* If we have a 0 byte read from recvfrom continue */
- if (cc == 0)
- continue;
#ifdef SO_TIMESTAMP
if (cmsg != NULL &&
cmsg->cmsg_level == SOL_SOCKET &&
@@ -1056,17 +1049,18 @@
{
struct timespec now;
struct tv32 tv32;
- struct icmp icp;
+ struct ip *ip;
+ struct icmp *icp;
int cc, i;
u_char *packet;
packet = outpack;
- 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 */
+ memcpy(&icp, &outpack, sizeof(struct icmp *));
+ 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 % mx_dup_ck);
@@ -1081,7 +1075,7 @@
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))
+ icp->icmp_otime = htonl((now.tv_sec % (24*60*60))
* 1000 + now.tv_nsec / 1000000);
if (timing)
bcopy((void *)&tv32,
@@ -1089,28 +1083,16 @@
sizeof(tv32));
}
- memcpy(outpack, &icp, ICMP_MINLEN + phdr_len);
-
cc = ICMP_MINLEN + phdr_len + datalen;
/* compute ICMP checksum here */
- 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));
+ icp->icmp_cksum = in_cksum((u_char *)icp, cc);
if (options & F_HDRINCL) {
- struct ip ip;
-
cc += sizeof(struct ip);
- 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));
+ ip = (struct ip *)outpackhdr;
+ ip->ip_len = htons(cc);
+ ip->ip_sum = in_cksum(outpackhdr, cc);
packet = outpackhdr;
}
i = send(ssend, (char *)packet, cc, 0);
@@ -1140,76 +1122,43 @@
* program to be run without having intermingled output (or statistics!).
*/
static void
-pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
+pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timespec *tv)
{
struct in_addr ina;
- u_char *cp, *dp, l;
- struct icmp icp;
- struct ip ip;
- const u_char *icmp_data_raw;
- ssize_t icmp_data_raw_len;
+ u_char *cp, *dp;
+ struct icmp *icp, *oicmp;
+ struct ip *ip, *oip;
+ const void *tp;
double triptime;
- int dupflag, i, j, recv_len;
- uint8_t hlen;
+ 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 header length is contained in the lower four bits of the first
- * byte and represents the number of 4 byte octets the header takes up.
- *
- * The IHL minimum value is 5 (20 bytes) and its maximum value is 15
- * (60 bytes).
- */
- memcpy(&l, buf, sizeof(l));
- hlen = (l & 0x0f) << 2;
- /* Reject IP packets with a short header */
- if (hlen < sizeof(struct ip)) {
- if (options & F_VERBOSE)
- warn("IHL too short (%d bytes) from %s", hlen,
- inet_ntoa(from->sin_addr));
- return;
- }
-
- memcpy(&ip, buf, sizeof(struct ip));
-
- /* Check packet has enough data to carry a valid ICMP header */
+ /* Check the IP header */
+ memcpy(&ip, &buf, sizeof(struct ip *));
+ hlen = ip->ip_hl << 2;
recv_len = cc;
if (cc < hlen + ICMP_MINLEN) {
if (options & F_VERBOSE)
- warn("packet too short (%zd bytes) from %s", cc,
+ warn("packet too short (%d 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_len = cc - (hlen + offsetof(struct icmp, icmp_data));
- icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_data);
-#endif
-
/* Now the ICMP part */
cc -= hlen;
- memcpy(&icp, buf + hlen, MIN((ssize_t)sizeof(icp), cc));
- if (icp.icmp_type == icmp_type_rsp) {
- if (icp.icmp_id != ident)
+ icp = (struct icmp *)(buf + hlen);
+ if (icp->icmp_type == icmp_type_rsp) {
+ if (icp->icmp_id != ident)
return; /* 'Twas not our ECHO */
++nreceived;
triptime = 0.0;
if (timing) {
struct timespec tv1;
struct tv32 tv32;
- const u_char *tp;
-
- tp = icmp_data_raw + phdr_len;
+ tp = icp->icmp_data;
+ tp = (const char *)tp + phdr_len;
if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
sizeof(tv1)) {
@@ -1230,7 +1179,7 @@
timing = 0;
}
- seq = ntohs(icp.icmp_seq);
+ seq = ntohs(icp->icmp_seq);
if (TST(seq % mx_dup_ck)) {
++nrepeats;
@@ -1252,9 +1201,9 @@
if (options & F_DOT)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
- (void)printf("%zd bytes from %s: icmp_seq=%u", cc,
+ (void)printf("%d bytes from %s: icmp_seq=%u", cc,
pr_addr(from->sin_addr), seq);
- (void)printf(" ttl=%d", ip.ip_ttl);
+ (void)printf(" ttl=%d", ip->ip_ttl);
if (timing)
(void)printf(" time=%.3f ms", triptime);
if (dupflag)
@@ -1264,12 +1213,12 @@
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(
@@ -1277,8 +1226,7 @@
recv_len, send_len);
}
/* check the data */
- cp = (u_char*)(buf + hlen + offsetof(struct icmp,
- icmp_data) + phdr_len);
+ cp = (u_char*)&icp->icmp_data[phdr_len];
dp = &outpack[ICMP_MINLEN + phdr_len];
cc -= ICMP_MINLEN + phdr_len;
i = 0;
@@ -1293,8 +1241,7 @@
(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
i, *dp, *cp);
(void)printf("\ncp:");
- cp = (u_char*)(buf + hlen +
- offsetof(struct icmp, icmp_data));
+ cp = (u_char*)&icp->icmp_data[0];
for (i = 0; i < datalen; ++i, ++cp) {
if ((i % 16) == 8)
(void)printf("\n\t");
@@ -1322,55 +1269,18 @@
* as root to avoid leaking information not normally
* available to those not running as root.
*/
-
- /*
- * If we don't have enough bytes for a quoted IP header and an
- * ICMP header then stop.
- */
- if (icmp_data_raw_len <
- (ssize_t)(sizeof(struct ip) + sizeof(struct icmp))) {
- if (options & F_VERBOSE)
- warnx("quoted data too short (%zd bytes) from %s",
- icmp_data_raw_len, inet_ntoa(from->sin_addr));
- return;
- }
-
- memcpy(&oip_header_len, icmp_data_raw, sizeof(oip_header_len));
- oip_header_len = (oip_header_len & 0x0f) << 2;
-
- /* Reject IP packets with a short header */
- if (oip_header_len < sizeof(struct ip)) {
- if (options & F_VERBOSE)
- warnx("inner IHL too short (%d bytes) from %s",
- oip_header_len, inet_ntoa(from->sin_addr));
- return;
- }
-
- /*
- * Check against the actual IHL length, to protect against
- * quoated packets carrying IP options.
- */
- if (icmp_data_raw_len <
- (ssize_t)(oip_header_len + sizeof(struct icmp))) {
- if (options & F_VERBOSE)
- warnx("inner packet too short (%zd bytes) from %s",
- icmp_data_raw_len, inet_ntoa(from->sin_addr));
- return;
- }
-
- memcpy(&oip, icmp_data_raw, sizeof(struct ip));
- oicmp_raw = icmp_data_raw + oip_header_len;
- memcpy(&oicmp, oicmp_raw, sizeof(struct icmp));
+ memcpy(&oip, icp->icmp_data, sizeof(struct ip *));
+ oicmp = (struct icmp *)(oip + 1);
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("%zd 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("%d bytes from %s: ", cc,
pr_addr(from->sin_addr));
- pr_icmph(&icp, &oip, oicmp_raw);
+ pr_icmph(icp);
} else
return;
}
@@ -1540,7 +1450,7 @@
* Print a descriptive string about an ICMP header.
*/
static void
-pr_icmph(struct icmp *icp, struct ip *oip, const u_char *const oicmp_raw)
+pr_icmph(struct icmp *icp)
{
switch(icp->icmp_type) {
@@ -1578,11 +1488,11 @@
break;
}
/* Print returned IP header information */
- pr_retip(oip, oicmp_raw);
+ pr_retip((struct ip *)icp->icmp_data);
break;
case ICMP_SOURCEQUENCH:
(void)printf("Source Quench\n");
- pr_retip(oip, oicmp_raw);
+ pr_retip((struct ip *)icp->icmp_data);
break;
case ICMP_REDIRECT:
switch(icp->icmp_code) {
@@ -1603,7 +1513,7 @@
break;
}
(void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr));
- pr_retip(oip, oicmp_raw);
+ pr_retip((struct ip *)icp->icmp_data);
break;
case ICMP_ECHO:
(void)printf("Echo Request\n");
@@ -1622,12 +1532,12 @@
icp->icmp_code);
break;
}
- pr_retip(oip, oicmp_raw);
+ pr_retip((struct ip *)icp->icmp_data);
break;
case ICMP_PARAMPROB:
(void)printf("Parameter problem: pointer = 0x%02x\n",
icp->icmp_hun.ih_pptr);
- pr_retip(oip, oicmp_raw);
+ pr_retip((struct ip *)icp->icmp_data);
break;
case ICMP_TSTAMP:
(void)printf("Timestamp\n");
@@ -1725,9 +1635,14 @@
* Dump some info on a returned (via ICMP) IP packet.
*/
static void
-pr_retip(struct ip *ip, const u_char *cp)
+pr_retip(struct ip *ip)
{
+ 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",
diff --git a/sbin/ping/tests/ping_test.sh b/sbin/ping/tests/ping_test.sh
--- a/sbin/ping/tests/ping_test.sh
+++ b/sbin/ping/tests/ping_test.sh
@@ -178,7 +178,7 @@
}
inject_pip_body()
{
- atf_check -s exit:2 -o match:"Destination Host Unreachable" -o not-match:"01010101" python3 $(atf_get_srcdir)/injection.py pip
+ atf_check -s exit:2 -o match:"Destination Host Unreachable" -o match:"(01){40}" python3 $(atf_get_srcdir)/injection.py pip
}
inject_pip_cleanup()
{
diff --git a/sbin/ping/tests/test_ping.py b/sbin/ping/tests/test_ping.py
--- a/sbin/ping/tests/test_ping.py
+++ b/sbin/ping/tests/test_ping.py
@@ -853,7 +853,6 @@
"stderr": "",
"redacted": True,
},
- marks=pytest.mark.skip("XXX currently failing"),
id="_0_0_opts_unk",
),
pytest.param(
@@ -879,7 +878,6 @@
"stderr": "",
"redacted": False,
},
- marks=pytest.mark.skip("XXX currently failing"),
id="_3_1_opts_NOP_40",
),
pytest.param(
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 12, 5:52 PM (28 m, 15 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26906584
Default Alt Text
D38431.id116747.diff (13 KB)
Attached To
Mode
D38431: ping: Reference implementation
Attached
Detach File
Event Timeline
Log In to Comment