Comportamento speciale (e AFAICT) leggermente sotto documentato in iputils ping : fai il ping da solo.
Se ping 0questo è ciò che accade (fortemente modificato e commentato per chiarezza):
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()non è POSIX, ma suppongo che copi il comportamento di inet_addr()quando vengono convertiti meno di 4 decimali puntati. Nel caso di un numero singolo senza punto, viene semplicemente memorizzato nell'indirizzo di rete binario ed 0x00000000è equivalente alla forma tratteggiata 0.0.0.0.
Puoi vederlo se strace(come 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.
Puoi anche vedere la modifica se invece esegui il binding a un'interfaccia specifica :
# 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.
Mentre 0 può essere trattato come 0.0.0.0 e un indirizzo di trasmissione in molti casi, questo non è chiaramente ciò che il ping sta facendo . In casi speciali questo significa "l'IP primario dell'interfaccia in questione" (con una gestione aggiuntiva per i casi multicast / broadcast).
RFC 1122 §3.2.1.3 spiega il comportamento: sia 0.0.0.0 sia l'indirizzo IP con la rete mascherata (il "numero host", ad es. 0.0.0.1 in caso di loopback) significano "questo host su questa rete".
(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.
Almeno nel caso di 0 o 0.0.0.0, in questo modo si pingcomportano iputils , altri ping e altri sistemi operativi potrebbero comportarsi diversamente. Ad esempio FreeBSD esegue il ping di 0.0.0.0 tramite la route predefinita (che non credo sia un comportamento "corretto").
ping 1o 0.0.0.1non funziona come sperato (non per me comunque, iputils-sss20101006 ).