Cosa fa ping -n in modo diverso?

Sep 03 2020

Durante la risoluzione dei problemi di un occasionale "blocco" della rete sulla mia rete Internet domestica, mi sono imbattuto in questo suggerimento tecnico di Dell . Suggeriscono di utilizzare ping -nper evitare uno stallo causato dalla risoluzione DNS. Questo mi ha fatto pensare, cosa fa -neffettivamente l' interruttore? Mi sembra che la risoluzione DNS sia richiesta se si esegue il ping di un nome DNS, ma non è necessaria se si esegue il ping di un IP.

Dalla pagina man:
-n Solo output numerico. Non verrà effettuato alcun tentativo di cercare nomi simbolici per gli indirizzi host.

Se eseguo il ping di un indirizzo IP come ping 8.8.8.8ci sono delle ricerche DNS qui? Fa ping -n 8.8.8.8qualcosa di diverso?

Risposte

2 KamilMaciorowski Sep 03 2020 at 06:23

Se eseguo il ping di un indirizzo IP come ping 8.8.8.8ci sono delle ricerche DNS qui? Fa ping -n 8.8.8.8qualcosa di diverso?

Può dipendere dall'implementazione. Se pingsenza -ninclude dns.googlenel suo output, ping -nprobabilmente no, questa è la differenza. Ma è possibile che nessuno dei due output includa la stringa.


Nel mio Ubuntu 18.04.4 LTS si man 8 pinglegge:

pingfa parte del iputilspacchetto e le ultime versioni sono disponibili in formato sorgente su http://www.skbuff.net/iputils/iputils-current.tar.bz2.

Questo indirizzo esatto sembra non funzionare, ancora http://www.skbuff.net/iputilsfornisce altri collegamenti, compreso quello a SourceForge . Ho scaricato iputils-s20151218 e letto il codice.

-nè gestito in ping_common.c:

case 'n':
        options |= F_NUMERIC;
        break;

Quindi l'opzione ( options & F_NUMERIC) è importante in ping.c:

pr_addr(__u32 addr)
{
        …

        if (exiting || (options & F_NUMERIC) ||
            !(hp = gethostbyaddr((char *)&addr, 4, AF_INET)))
                sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&addr));
        else {
                …

Per arrivare a gethostbyaddr, entrambi exitinge options & F_NUMERICdevono essere falsi (perché a || bnon valuterà bse aè vero). Quest'ultimo dipende dal fatto che -nsia stato utilizzato o meno.

gethostbyaddrè il "tentativo di cercare nomi simbolici per indirizzi host". Vedi man 3 gethostbyaddr. Questa è la stessa chiamata della libreria getent hostsutilizzata quando si fornisce un indirizzo IP (vedere man 1 getent).

Vedi la differenza:

$ getent hosts 8.8.8.8 8.8.8.8 dns.google $ ping -c 1 dns.google
…
64 bytes from dns.google (8.8.8.8): icmp_seq=1 ttl=120 time=10.6 ms
…
$ ping -n -c 1 dns.google … 64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=11.3 ms … $

Può sembrare pingsenza -nutilizzare solo la stringa fornita dall'utente; ma no:

$ getent hosts poczta.wp.pl 193.17.41.99 poczta.wp.pl $ getent hosts 193.17.41.99
193.17.41.99    poczta.o2.pl
$ ping -c 1 poczta.wp.pl … 64 bytes from poczta.o2.pl (193.17.41.99): icmp_seq=1 ttl=60 time=9.71 ms … $

Qui è poczta.wp.plstato risolto a 193.17.41.99e poi è 193.17.41.99stato risolto a poczta.o2.pl(nota o2invece di wp). L'utilizzo di -nsopprimerebbe l'ultimo passaggio.

Per alcuni indirizzi questo accade:

$ getent hosts superuser.com 151.101.1.69 superuser.com 151.101.193.69 superuser.com 151.101.65.69 superuser.com 151.101.129.69 superuser.com $ getent hosts 151.101.1.69 151.101.193.69 151.101.65.69 151.101.129.69        
$ # the output was empty $ ping -c 1 superuser.com
…
64 bytes from 151.101.1.69 (151.101.1.69): icmp_seq=1 ttl=58 time=37.1 ms
…
$ ping -n -c 1 superuser.com … 64 bytes from 151.101.1.69: icmp_seq=1 ttl=58 time=36.8 ms … $

Ma se fornisco un indirizzo numerico, non ci sarà alcuna differenza:

$ getent hosts 8.8.8.8 8.8.8.8 dns.google $ ping -c 1 8.8.8.8
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=10.8 ms
…
$ ping -n -c 1 8.8.8.8 … 64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=8.91 ms … $ 

È a causa di questo frammento da ping.c:

if (inet_aton(target, &whereto.sin_addr) == 1) {
        hostname = target;
         if (argc == 1)
                 options |= F_NUMERIC;
} else

inet_atonconverte dalla notazione IPv4 numeri e punti in formato binario. Ritorna 1in caso di successo. Se l'ultimo argomento fornito a pingpuò essere convertito, il frammento viene valutato options |= F_NUMERIC come se -nfosse stato utilizzato .

In realtà ho compilato pingdal sorgente in due versioni: l'originale e con il if … options |= F_NUMERIC;commento. La versione modificata si comporta in questo modo:

$ ./ping -c 1 8.8.8.8 … 64 bytes from dns.google (8.8.8.8): icmp_seq=1 ttl=120 time=9.67 ms … $ ./ping -n -c 1 8.8.8.8
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=8.69 ms
…
$ 

Ora posso rispondere esplicitamente alla domanda:

Fa ping -n 8.8.8.8qualcosa di diverso [rispetto a ping 8.8.8.8]?

No. L'indirizzo nella notazione IPv4 numeri e punti fa funzionare ping(da iputilsLinux) come se -nfosse usato.


Se eseguo il ping di un indirizzo IP come ping 8.8.8.8ci sono delle ricerche DNS qui?

Ho creato uno spazio dei nomi di rete separato (per assicurarmi che il minor traffico possibile interferisca) con una coppia di veth, quindi l'ho usato wireshark. (Se vuoi replicare i miei risultati e hai bisogno di aiuto con la procedura, vedi questa risposta , esempio 2).

Con l'originale ping:

  • ping -n -c 1 8.8.8.8genera ICMP echo requeste riceve ICMP echo reply. Nessun DNS coinvolto.
  • ping -c 1 8.8.8.8 fa lo stesso (nessuna sorpresa qui, spiegato sopra).

Ciò significa che non è presente alcuna ricerca DNS . Di seguito sono riportati alcuni test per il confronto.

Con il mio modificato ping:

  • ping -n -c 1 8.8.8.8 si comporta come l'originale.
  • ping -c 1 8.8.8.8interroga il server DNS dopo ICMP e riceve una risposta. Questo è per ottenere dns.google.

Di nuovo con l'originale ping:

  • ping -n -c 1 dns.googleinterroga il server DNS e riceve una risposta prima di ICMP. Questo per tradurre dns.googlein 8.8.8.8o 8.8.4.4.
  • ping -c 1 dns.googleinterroga il server DNS e riceve una risposta prima di ICMP (per tradurre in 8.8.8.8o in 8.8.4.4) e separatamente dopo ICMP (per tradurre indietro).
1 xenoid Sep 03 2020 at 03:56

Dalla pagina man:

-n Solo output numerico. Non verrà effettuato alcun tentativo di cercare nomi simbolici per gli indirizzi host

quindi la differenza è nell'output:

>ping  whitehouse.gov
PING whitehouse.gov(g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add)) 56 data bytes
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=1 ttl=52 time=7.38 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=2 ttl=52 time=6.91 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=3 ttl=52 time=21.6 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=4 ttl=52 time=7.60 ms
>ping  -n whitehouse.gov
PING whitehouse.gov(2a02:26f0:82:280::2add) 56 data bytes
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=1 ttl=52 time=10.0 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=2 ttl=52 time=5.63 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=3 ttl=52 time=10.4 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=4 ttl=52 time=12.5 ms