git: 0b9434d707c7 - main - ping: do a better job with what we received from the net, part 2
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Sep 2026 00:37:14 UTC
The branch main has been updated by maxim:
URL: https://cgit.FreeBSD.org/src/commit/?id=0b9434d707c71de7b1b62e400e6e780224f0384d
commit 0b9434d707c71de7b1b62e400e6e780224f0384d
Author: Maxim Konovalov <maxim@FreeBSD.org>
AuthorDate: 2026-09-16 18:42:00 +0000
Commit: Maxim Konovalov <maxim@FreeBSD.org>
CommitDate: 2026-09-17 00:31:10 +0000
ping: do a better job with what we received from the net, part 2
When we see a difference between the payload we sent and what we
received, we dump both but we were not prepared for the case when
the received payload is less than we sent. In this case we were trying
to dump more than needed.
Funny enough, 23 years ago I already fixed a similar issue here but
didn't pay attention to this small dumping loop.
Test written by jlduran.
Reviewed by: jlduran
MFC after: 1 month
Found with: Claude Code Sonnet 5
Differential Revision: https://reviews.freebsd.org/D59556
Differential Revision: https://reviews.freebsd.org/D59582
---
sbin/ping/ping.c | 6 ++++--
sbin/ping/tests/test_ping.py | 40 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index 5926641a4a50..362561f246e8 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -1109,7 +1109,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
const u_char *icmp_data_raw;
ssize_t icmp_data_raw_len;
double triptime;
- int dupflag, i, j, recv_len;
+ int avail, dupflag, i, j, recv_len;
int8_t hlen;
uint16_t seq;
static int old_rrlen;
@@ -1273,9 +1273,11 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
i, *dp, *cp);
(void)printf("\ncp:");
+ avail = (int)MIN((ssize_t)datalen,
+ i + cc);
cp = (u_char*)(buf + hlen +
offsetof(struct icmp, icmp_data));
- for (i = 0; i < datalen; ++i, ++cp) {
+ for (i = 0; i < avail; ++i, ++cp) {
if ((i % 16) == 8)
(void)printf("\n\t");
(void)printf(" %2x", *cp);
diff --git a/sbin/ping/tests/test_ping.py b/sbin/ping/tests/test_ping.py
index 88164c2ab816..51b8287814aa 100644
--- a/sbin/ping/tests/test_ping.py
+++ b/sbin/ping/tests/test_ping.py
@@ -80,6 +80,10 @@ def build_response_packet(echo, ip, icmp, oip_ihl, special):
# Build a package with a wrong last byte
payload_no_last_byte = sc.bytes_hex(load)[:-2]
load = (sc.hex_bytes(payload_no_last_byte)) + b"\x00"
+ if special == "short-wrong":
+ # Build a short package with a wrong last byte
+ payload_no_last_byte = sc.bytes_hex(load)[:-4]
+ load = (sc.hex_bytes(payload_no_last_byte)) + b"\x00"
if special == "not-mine":
# Modify the ICMP Identifier field
oicmp.id += 1
@@ -202,7 +206,7 @@ def pinger(
:keyword oip_ihl: Inner packet's Internet Header Length, defaults to None
:type oip_ihl: class:`scapy.fields.BitField`, optional
:keyword special: Send a special packet - one of `no-payload`, `not-mine`,
- `tcp`, `udp`, `wrong` or `warp`, defaults to None
+ `short-wrong`, `tcp`, `udp`, `wrong` or `warp`, defaults to None
:type special: str, optional
:keyword icmp_pptr: ICMP pointer, defaults to 0
:type icmp_pptr: class:`scapy.fields.ByteField`
@@ -1464,6 +1468,40 @@ round-trip min/avg/max/stddev = /// ms
},
id="_0_0_special_wrong",
),
+ pytest.param(
+ {
+ "src": "192.0.2.1",
+ "dst": "192.0.2.2",
+ "icmp_type": 0,
+ "icmp_code": 0,
+ "special": "short-wrong",
+ },
+ {
+ "returncode": 0,
+ "stdout": """\
+PATTERN: 0x01
+PING 192.0.2.2 (192.0.2.2): 56 data bytes
+63 bytes from: icmp_seq=0 ttl= time= ms
+wrong total length 83 instead of 84
+wrong data byte #54 should be 0x1 but was 0x0
+cp: xx xx xx xx xx xx xx xx
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
+dp: xx xx xx xx xx xx xx xx
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+
+--- 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_special_short_wrong",
+ ),
]
@pytest.mark.parametrize("pinger_kargs, expected", pinger_testdata)