comment fonctionne ping zéro?

16

quelqu'un peut-il expliquer comment cela ping 0fonctionne et cela se traduit par 127.0.0.1.

[champu@testsrv ]$ ping 0
PING 0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.013 ms

--- 0 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.013/0.026/0.039/0.013 ms
Rahul Patil
la source
Vous vous cinglez: P
Alko

Réponses:

21

Comportement spécial (et AFAICT) légèrement sous-documenté dans iputils ping : vous vous cinglez .

Si c'est ping 0ce qui se passe (fortement édité et commenté pour plus de clarté):

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()n'est pas POSIX, mais je suppose qu'il copie le comportement inet_addr()lorsque moins de 4 décimales en pointillé sont converties. Dans le cas d'un nombre unique sans point, il est simplement stocké dans l'adresse réseau binaire et 0x00000000équivaut à la forme en pointillés 0.0.0.0.

Vous pouvez le voir si vous strace(en tant que 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.

Vous pouvez également voir le changement si vous vous connectez à une interface spécifique à la place:

# 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.

Alors que 0 peut être traité comme 0.0.0.0 et une adresse de diffusion dans de nombreux cas, ce n'est clairement pas ce que fait ping . Cela signifie dans certains cas "l'adresse IP principale de l'interface en question" (avec un traitement supplémentaire pour les cas de multidiffusion / diffusion).

La RFC 1122 §3.2.1.3 explique le comportement: à la fois 0.0.0.0 et l'adresse IP avec le réseau masqué (le "numéro d'hôte", par exemple 0.0.0.1 dans le cas du bouclage) signifient "cet hôte sur ce réseau".

       (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.

Au moins dans le cas de 0 ou 0.0.0.0, c'est ainsi que pingse comporte iputils , d'autres pings et autres OS peuvent se comporter différemment. Par exemple, FreeBSD envoie une requête 0.0.0.0 via la route par défaut (ce qui, à mon avis, n'est pas un comportement "correct").

ping 1ou 0.0.0.1ne fonctionnent pas comme prévu (pas pour moi de toute façon, iputils-sss20101006 ).

Mr Spuratic
la source
@ mr.spuratic .. que ce à quoi je m'attendais .. merci
Rahul Patil
N'est-ce pas techniquement le traiter comme 0.0.0.0, puis par la suite spécial 0.0.0.0 pour signifier "l'IP primaire de l'interface"? Que se passe-t-il si vous envoyez une requête ping à 0.0.0.0?
Random832
@ Random832 oui, c'est exact.
mr.spuratic