iputils中的 特殊(和AFAICT)记录不足的行为ping
:ping您自己。
如果ping 0
发生这种情况(为了清晰起见,请对其进行大量编辑和评论):
if (inet_aton(target, &whereto.sin_addr)) == 1) {
// convert string to binary in_addr
}
// inet_aton returns 1 (success) and leaves the `in_addr` contents all zero.
if (source.sin_addr.s_addr == 0) {
// determine IP address of src interface, via UDP connect(), getsockname()
}
// special case for 0 dst address
if (whereto.sin_addr.s_addr == 0)
whereto.sin_addr.s_addr = source.sin_addr.s_addr;
inet_aton()
不是POSIX,但我假设它复制了inet_addr()
少于4个点分十进制数被转换时的行为。对于无点单号,它仅存储在二进制网络地址中,0x00000000
等效于点分形式0.0.0.0
。
如果您strace
(以root用户身份)可以看到此信息:
# strace -e trace=network ping 0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(1025),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(58056),
sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
...
PING 0 (127.0.0.1) 56(84) bytes of data.
如果绑定到特定接口,则还可以看到更改:
# strace -e trace=network ping -I eth0 0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
setsockopt(4, SOL_SOCKET, SO_BINDTODEVICE, "eth0\0", 5) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(1025),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(58408),
sin_addr=inet_addr("192.168.0.123")}, [16]) = 0
setsockopt(3, SOL_RAW, ICMP_FILTER, ...)
[...]
PING 0 (192.168.0.123) from 192.168.0.123 eth0: 56(84) bytes of data.
尽管0在许多情况下可能被视为0.0.0.0和广播地址,但这显然不是ping在做什么。在特殊情况下,它表示“所讨论的接口的主要IP”(对于多播/广播情况有一些额外的处理)。
RFC 1122§3.2.1.3解释了此行为:0.0.0.0和网络被屏蔽的IP地址(“主机号”,例如在环回情况下为0.0.0.1)均表示“此网络上的该主机”。
(a) { 0, 0 }
This host on this network. MUST NOT be sent, except as
a source address as part of an initialization procedure
by which the host learns its own IP address.
See also Section 3.3.6 for a non-standard use of {0,0}.
(b) { 0, <Host-number> }
Specified host on this network. It MUST NOT be sent,
except as a source address as part of an initialization
procedure by which the host learns its full IP address.
至少在iputils的ping
行为方式为0或0.0.0.0的情况下,其他ping和其他OS的行为可能有所不同。例如FreeBSD通过默认路由ping 0.0.0.0(我认为这不是“正确”的行为)。
ping 1
或0.0.0.1
没有按照期望的方式工作(无论如何对我来说不是iputils-sss20101006)。