Small bug in ping

2 messages, 2 authors, 2014-06-04 · open the first message on its own page

Small bug in ping

From: Jakob Unterwurzacher <hidden>
Date: 2014-06-03 20:58:17

Hi!

I was waiting for a machine to boot, pinging it, and noticed what I
believe is a bug in the output of iputils' ping.

Reproducer:
1) Ping a host on the LAN that is down
2) Wait until you get "Destination Host Unreachable" from your own IP
3) Boot up host
4) Ping replies seem to come from your own IP

ping output looks like this:
# ping -n 192.168.0.121
From 192.168.0.251 icmp_seq=54 Destination Host Unreachable
From 192.168.0.251 icmp_seq=55 Destination Host Unreachable
64 bytes from 192.168.0.251: icmp_seq=77 ttl=64 time=0.466 ms
64 bytes from 192.168.0.251: icmp_seq=78 ttl=64 time=3.06 ms
...
tcpdump looks good:
# tcpdump host 192.168.0.121 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
22:21:59.038558 IP 192.168.0.251 > 192.168.0.121: ICMP echo request, id 4724, seq 116, length 64
22:21:59.039095 IP 192.168.0.121 > 192.168.0.251: ICMP echo reply, id 4724, seq 116, length 64
22:22:00.038553 IP 192.168.0.251 > 192.168.0.121: ICMP echo request, id 4724, seq 117, length 64
22:22:00.039071 IP 192.168.0.121 > 192.168.0.251: ICMP echo reply, id 4724, seq 117, length 64
Also, strace confirms that ping gets the packets correctly:
# strace -p `pgrep ping`
Process 4724 attached
poll([{fd=3, events=POLLIN|POLLERR}], 1, 28) = 0 (Timeout)
sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.0.121")}, msg_iov(1)=[{"\10\0\356\373\22t\0\223\206.\216S\0\0\0\0\"\250\0\0\0\0\0\0\20\21\22\23\24\25\26\27"..., 64}], msg_controllen=0, msg_flags=0}, MSG_CONFIRM) = 64
recvmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.0.121")}, msg_iov(1)=[{"E\0\0T\200b\0\0@\1w\202\300\250\0y\300\250\0\373\0\0\366\373\22t\0\223\206.\216S"..., 192}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=0x1d /* SCM_??? */, ...}, msg_flags=0}, 0) = 84
write(1, "64 bytes from 192.168.0.251: icm"..., 63) = 63
poll([{fd=3, events=POLLIN|POLLERR}], 1, 998) = 0 (Timeout)
sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.0.121")}, msg_iov(1)=[{"\10\0\227\363\22t\0\224\207.\216S\0\0\0\0x\257\0\0\0\0\0\0\20\21\22\23\24\25\26\27"..., 64}], msg_controllen=0, msg_flags=0}, MSG_CONFIRM) = 64
recvmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.0.121")}, msg_iov(1)=[{"E\0\0T\200c\0\0@\1w\201\300\250\0y\300\250\0\373\0\0\237\363\22t\0\224\207.\216S"..., 192}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=0x1d /* SCM_??? */, ...}, msg_flags=0}, 0) = 84
write(1, "64 bytes from 192.168.0.251: icm"..., 63) = 63
...
( In case the output gets horribly word-wrapped: I have pasted it to
https://gist.github.com/anonymous/597434502b928a75ac05 )

Best regards,
Jakob

Re: Small bug in ping

From: David Newall <hidden>
Date: 2014-06-04 09:50:52

On 04/06/14 06:28, Jakob Unterwurzacher wrote:
4) Ping replies seem to come from your own IP
Yes, a bug.  To minimise use of DNS, ping only queries or formats an 
addresses once, and returns that result thereafter.  The bug was 
introduced at bug10979-less-dns.  I sent the following patch, which only 
returns the previous value if it's for the same IP address, to ping's 
maintainer, last month:

Index: iputils/ping.c
===================================================================
--- iputils.orig/ping.c	2013-12-12 21:50:00.237785711 -0800
+++ iputils/ping.c	2013-12-12 22:11:24.800155180 -0800
@@ -1243,7 +1243,12 @@
  pr_addr(__u32 addr)
  {
  	struct hostent *hp;
-	static char buf[4096];
+	static char buf[4096] = "";
+	static __u32 last_addr;
+
+	if (*buf && addr == last_addr)
+		return(buf);
+	last_addr = addr;
  
  	in_pr_addr = !setjmp(pr_addr_jmp);
  
Index: iputils/ping6.c
===================================================================
--- iputils.orig/ping6.c	2013-12-12 21:50:00.189785476 -0800
+++ iputils/ping6.c	2013-12-12 22:12:22.856444368 -0800
@@ -1794,7 +1794,7 @@
   */
  char * pr_addr(struct in6_addr *addr)
  {
-	struct hostent *hp = NULL;
+	static struct hostent *hp = NULL;
  	static char *s;
  
  #ifdef USE_IDN
@@ -1803,7 +1803,7 @@
  
  	in_pr_addr = !setjmp(pr_addr_jmp);
  
-	if (!(exiting || options&F_NUMERIC))
+	if (!hp && !(exiting || options&F_NUMERIC))
  		hp = gethostbyaddr((__u8*)addr, sizeof(struct in6_addr), AF_INET6);
  
  	in_pr_addr = 0;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help