Skip to content

Commit

Permalink
ping: discard packets with wrong source address
Browse files Browse the repository at this point in the history
RFC 1122 clearly states that the IP address in the reply MUST match the
one in the request:

	The IP source address in an ICMP Echo Reply MUST be the same
	as the specific-destination address (defined in Section
	3.2.1.3) of the corresponding ICMP Echo Request message.

This is not enforced in iputils neither in IPv4 nor in IPv6:

	$ ping -c4 127.0.0.1
	PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
	64 bytes from 127.0.0.5: icmp_seq=1 ttl=64 time=0.072 ms
	64 bytes from 127.0.0.5: icmp_seq=2 ttl=64 time=0.101 ms
	64 bytes from 127.0.0.5: icmp_seq=3 ttl=64 time=0.079 ms
	64 bytes from 127.0.0.5: icmp_seq=4 ttl=64 time=0.081 ms

	--- 127.0.0.1 ping statistics ---
	4 packets transmitted, 4 received, 0% packet loss, time 3056ms
	rtt min/avg/max/mdev = 0.072/0.083/0.101/0.010 ms

	$ ping -c4 ::1
	PING ::1(::1) 56 data bytes
	64 bytes from ::5: icmp_seq=1 ttl=64 time=0.029 ms
	64 bytes from ::5: icmp_seq=2 ttl=64 time=0.084 ms
	64 bytes from ::5: icmp_seq=3 ttl=64 time=0.064 ms
	64 bytes from ::5: icmp_seq=4 ttl=64 time=0.083 ms

	--- ::1 ping statistics ---
	4 packets transmitted, 4 received, 0% packet loss, time 3074ms
	rtt min/avg/max/mdev = 0.029/0.065/0.084/0.022 ms

The same issue happens both with raw and ICMP sockets.

Signed-off-by: Matteo Croce <[email protected]>
  • Loading branch information
teknoraver committed Mar 12, 2020
1 parent f406ac9 commit 5e052ad
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ping/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,9 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
csfailed = in_cksum((unsigned short *)icp, cc, 0);

if (icp->type == ICMP_ECHOREPLY) {
if (!rts->broadcast_pings && !rts->multicast &&
from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
return 1;
if (!is_ours(rts, sock, icp->un.echo.id))
return 1; /* 'Twas not our ECHO */
if (!contains_pattern_in_payload(rts, (uint8_t *)(icp + 1)))
Expand Down
3 changes: 3 additions & 0 deletions ping/ping6_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,9 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
}

if (icmph->icmp6_type == ICMP6_ECHO_REPLY) {
if (!rts->multicast &&
memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
return 1;
if (!is_ours(rts, sock, icmph->icmp6_id))
return 1;
if (!contains_pattern_in_payload(rts, (uint8_t *)(icmph + 1)))
Expand Down

0 comments on commit 5e052ad

Please sign in to comment.