Specjalne (i AFAICT) nieco niedokumentowane zachowanie w iputils ping : pingujesz siebie.
Jeśli ping 0tak się dzieje (mocno edytowane i komentowane dla jasności):
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()nie jest POSIX, ale zakładam, że kopiuje zachowanie, inet_addr()gdy konwertowane są mniej niż 4 kropki dziesiętne. W przypadku pojedynczego numeru bez kropek jest on po prostu zapisywany w binarnym adresie sieciowym i 0x00000000jest równoważny postaci kropkowanej 0.0.0.0.
Możesz to zobaczyć, jeśli strace(jako 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.
Możesz również zobaczyć zmianę, jeśli zamiast tego powiążesz z określonym interfejsem:
# 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.
Podczas gdy 0 może być traktowane jako 0.0.0.0 i adres rozgłoszeniowy w wielu przypadkach , wyraźnie nie robi tego ping . W przypadkach specjalnych oznacza to „podstawowy adres IP danego interfejsu” (z pewną dodatkową obsługą przypadków multiemisji / emisji).
RFC 1122 §3.2.1.3 wyjaśnia zachowanie: zarówno 0.0.0.0, jak i adres IP z maskowaną siecią („numer hosta”, np. 0.0.0.1 w przypadku pętli zwrotnej) oznaczają „ten host w tej sieci”.
(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.
Przynajmniej w przypadku 0 lub 0.0.0.0 tak pingzachowuje się iputils , inne pingi i inne systemy operacyjne mogą zachowywać się inaczej. Na przykład FreeBSD pinguje 0.0.0.0 domyślną trasą (co nie uważam za zachowanie „poprawne”).
ping 1lub 0.0.0.1nie działają tak, jak się spodziewano (i tak nie dla mnie, iputils-sss20101006 ).