Skip to content

Commit 4cf5a47

Browse files
Copilotithewei
andcommitted
Fix ICMPv6 checksum, skip non-echo-reply packets, improve TTL display
Co-authored-by: ithewei <26049660+ithewei@users.noreply.github.com>
1 parent d94a9a0 commit 4cf5a47

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

protocol/icmp.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ int ping(const char* host, int cnt) {
6969
// NOTE: checksum
7070
icmp_req->icmp_seq = ++seq;
7171
icmp_req->icmp_cksum = 0;
72-
icmp_req->icmp_cksum = checksum((uint8_t*)icmp_req, sendbytes);
72+
// NOTE: ICMPv6 checksum includes a pseudo-header and is auto-computed
73+
// by the kernel for IPPROTO_ICMPV6 raw sockets.
74+
if (!is_ipv6) {
75+
icmp_req->icmp_cksum = checksum((uint8_t*)icmp_req, sendbytes);
76+
}
7377
start_hrtime = gethrtime_us();
7478
addrlen = sockaddr_len(&peeraddr);
7579
int nsend = sendto(sockfd, sendbuf, sendbytes, 0, &peeraddr.sa, addrlen);
@@ -78,8 +82,13 @@ int ping(const char* host, int cnt) {
7882
continue;
7983
}
8084
++send_cnt;
81-
addrlen = sizeof(peeraddr);
82-
int nrecv = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, &peeraddr.sa, &addrlen);
85+
int nrecv;
86+
do {
87+
addrlen = sizeof(peeraddr);
88+
nrecv = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, &peeraddr.sa, &addrlen);
89+
// For IPv6, raw sockets receive all ICMPv6 types (e.g. Neighbor
90+
// Discovery). Skip anything that is not an echo reply.
91+
} while (is_ipv6 && nrecv >= (int)sizeof(icmphdr_t) && ((icmp_t*)recvbuf)->icmp_type != ICMP6_ECHO_REPLY);
8392
if (nrecv < 0) {
8493
perror("recvfrom");
8594
continue;
@@ -106,7 +115,11 @@ int ping(const char* host, int cnt) {
106115
min_rtt = MIN(rtt, min_rtt);
107116
max_rtt = MAX(rtt, max_rtt);
108117
total_rtt += rtt;
109-
printd("%d bytes from %s: icmp_seq=%u ttl=%u time=%.1f ms\n", icmp_len, ip, seq, is_ipv6 ? 0 : ipheader->ttl, rtt);
118+
if (is_ipv6) {
119+
printd("%d bytes from %s: icmp_seq=%u hlim=? time=%.1f ms\n", icmp_len, ip, seq, rtt);
120+
} else {
121+
printd("%d bytes from %s: icmp_seq=%u ttl=%u time=%.1f ms\n", icmp_len, ip, seq, ipheader->ttl, rtt);
122+
}
110123
fflush(stdout);
111124
++ok_cnt;
112125
if (cnt > 0) hv_sleep(1); // sleep a while, then agian

0 commit comments

Comments
 (0)