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 #include #include -#include #include #include #include @@ -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 */ + 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 */ 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; + struct ip *ip; + 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 */ + 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 (%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)); + struct ip *oip = (struct ip *)icp->icmp_data; + struct icmp *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 @@ -781,6 +781,365 @@ }, id="_0_0", ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "EOL", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +wrong total length 88 instead of 84 + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_EOL", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "LSRR", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +LSRR: 192.0.2.10 + 192.0.2.20 + 192.0.2.30 + 192.0.2.40 + 192.0.2.50 + 192.0.2.60 + 192.0.2.70 + 192.0.2.80 + 192.0.2.90 + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_LSRR", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "LSRR-trunc", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +LSRR: (truncated route) + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_LSRR_trunc", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "SSRR", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +SSRR: 192.0.2.10 + 192.0.2.20 + 192.0.2.30 + 192.0.2.40 + 192.0.2.50 + 192.0.2.60 + 192.0.2.70 + 192.0.2.80 + 192.0.2.90 + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_SSRR", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "SSRR-trunc", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +SSRR: (truncated route) + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_SSRR_trunc", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "RR", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +RR: 192.0.2.10 + 192.0.2.20 + 192.0.2.30 + 192.0.2.40 + 192.0.2.50 + 192.0.2.60 + 192.0.2.70 + 192.0.2.80 + 192.0.2.90 + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_RR", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "RR-same", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms (same route) + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_RR_same", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "RR-trunc", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +RR: (truncated route) + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_RR_trunc", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 0, + "icmp_code": 0, + "opts": "NOP", + }, + { + "returncode": 0, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +64 bytes from: icmp_seq=0 ttl= time= ms +wrong total length 88 instead of 84 +NOP + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 1 packets received, 0.0% packet loss +round-trip min/avg/max/stddev = /// ms +""", + "stderr": "", + "redacted": True, + }, + id="_0_0_opts_NOP", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "ihl": 0x4, + }, + { + "returncode": 2, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_IHL_too_short", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "special": "no-payload", + }, + { + "returncode": 2, + "stdout": """\ +PATTERN: 0x01 +PING 192.0.2.2 (192.0.2.2): 56 data bytes +36 bytes from 192.0.2.2: Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 001c 0001 0 0000 40 01 f6dc 192.0.2.1 192.0.2.2 + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_quoted_data_too_short", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "oip_ihl": 0x4, + }, + { + "returncode": 2, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_inner_IHL_too_short", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "oip_ihl": 0xf, + }, + { + "returncode": 2, + "stdout": """\ +PING 192.0.2.2 (192.0.2.2): 56 data bytes +92 bytes from: Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 f 00 0054 0001 0 0000 40 01 eca4 192.0.2.1 192.0.2.2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": True, # XXX No redaction yet + }, + marks=pytest.mark.skip("XXX No redaction yet"), + id="_inner_packet_too_short", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "oip_ihl": 0xf, + "special": "no-payload", + }, + { + "returncode": 2, + "stdout": """\ +PATTERN: 0x01 +PING 192.0.2.2 (192.0.2.2): 56 data bytes + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_max_inner_packet_ihl_without_payload", + ), pytest.param( { "src": "192.0.2.1", @@ -868,7 +1227,6 @@ "stderr": "", "redacted": True, }, - marks=pytest.mark.skip("XXX currently failing"), id="_0_0_opts_unk", ), pytest.param( @@ -894,7 +1252,6 @@ "stderr": "", "redacted": False, }, - marks=pytest.mark.skip("XXX currently failing"), id="_3_1_opts_NOP_40", ), pytest.param( @@ -923,6 +1280,60 @@ marks=pytest.mark.skip("XXX currently failing"), id="_3_1_flags_DF", ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "special": "tcp", + }, + { + "returncode": 2, + "stdout": """\ +PATTERN: 0x01 +PING 192.0.2.2 (192.0.2.2): 56 data bytes +48 bytes from 192.0.2.2: Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 0028 0001 0 0000 40 06 f6cb 192.0.2.1 192.0.2.2 +TCP: from port 1234, to port 5678 (decimal) + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_3_1_special_tcp", + ), + pytest.param( + { + "src": "192.0.2.1", + "dst": "192.0.2.2", + "icmp_type": 3, + "icmp_code": 1, + "special": "udp", + }, + { + "returncode": 2, + "stdout": """\ +PATTERN: 0x01 +PING 192.0.2.2 (192.0.2.2): 56 data bytes +36 bytes from 192.0.2.2: Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 001c 0001 0 0000 40 11 f6cc 192.0.2.1 192.0.2.2 +UDP: from port 1234, to port 5678 (decimal) + + +--- 192.0.2.2 ping statistics --- +1 packets transmitted, 0 packets received, 100.0% packet loss +""", + "stderr": "", + "redacted": False, + }, + id="_3_1_special_udp", + ), ] @pytest.mark.parametrize("pinger_kargs, expected", pinger_testdata)