ping -n 有何不同?

ping -n 有何不同?

在对家里的互联网偶尔出现的网络“停顿”进行故障排除时,我遇到了这个问题戴尔的技术提示。他们建议使用ping -n以避免 DNS 解析导致的停顿。这让我开始思考,交换机-n实际上做了什么?在我看来,如果您 p​​ing DNS 名称,则需要 DNS 解析,但如果您 p​​ing IP,则不需要。

从手册页中:
-n 仅数字输出。不会尝试查找主机地址的符号名称。

如果我 ping 一个 IP 地址,那么ping 8.8.8.8这里如何进行 DNS 查找?ping -n 8.8.8.8会有什么不同吗?

答案1

如果我 ping 一个 IP 地址,那么ping 8.8.8.8这里如何进行 DNS 查找?ping -n 8.8.8.8会有什么不同吗?

这可能取决于实现。如果其输出中ping-n包含任何内容,则可能不存在,这就是区别。但有可能两个输出都不包含字符串。dns.googleping -n


在我的 Ubuntu 18.04.4 LTS 中man 8 ping显示:

ping是软件包的一部分iputils,最新版本的源代码可在 处获得http://www.skbuff.net/iputils/iputils-current.tar.bz2

这个确切的地址似乎仍然不起作用http://www.skbuff.net/iputils提供其他链接,包括SourceForge 的一个。我已经下载了iputils-s20151218并阅读代码。

-n处理方式ping_common.c

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

那么选项(options & F_NUMERIC)在以下情况下很重要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 {

为了得到gethostbyaddrexiting和都options & F_NUMERIC必须为假(因为a || bdoes 不会评估b是否a为真)。后者取决于是否-n被使用。

gethostbyaddr是“尝试查找主机地址的符号名称”。请参阅。这是提供 IP 地址时使用的man 3 gethostbyaddr同一个库调用(请参阅)。getent hostsman 1 getent

看到不同:

$ 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
$

看起来似乎ping没有-n仅仅使用用户提供的字符串;但事实并非如此:

$ 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
$

这里poczta.wp.pl被解析为193.17.41.99,然后193.17.41.99被解析为poczta.o2.pl(注意o2而不是wp)。使用-n会取消后面的步骤。

对于某些地址,会发生这种情况:

$ 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
$

如果我提供一个数字地址,那么就不会有区别:

$ 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
$ 

这是因为来自这个片段ping.c

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

inet_aton将 IPv4 数字和点表示法转换为二进制形式。成功时返回1。如果最后一个参数ping可以转换,则该片段评估options |= F_NUMERIC 就像-n被使用过一样

我实际上ping从源代码编译了两个版本:原始版本和if … options |= F_NUMERIC;注释掉的版本。修改后的版本的行为如下:

$ ./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
$ 

现在我可以明确地回答这个问题:

ping -n 8.8.8.8了一些不同的事情吗ping 8.8.8.8

不。IPv4 数字和点表示法中的地址使pingiputils在 Linux 上)工作得像-n被使用过一样。


如果我 ping 一个 IP 地址,ping 8.8.8.8这里如何进行 DNS 查找?

我创建了一个单独的网络命名空间(以确保尽可能少的流量干扰),其中包含一个 veth 对,然后wireshark在那里使用。(如果你想复制我的结果并需要有关该过程的帮助,请参阅这个答案,示例2)。

原文如下ping

  • ping -n -c 1 8.8.8.8生成ICMP echo request并接收ICMP echo reply。不涉及 DNS。
  • ping -c 1 8.8.8.8做同样的事情(这并不奇怪,上面已经解释过了)。

这意味着没有 DNS 查找下面是一些用于比较的测试。

经过我的修改ping

  • ping -n -c 1 8.8.8.8表现和原版一样。
  • ping -c 1 8.8.8.8ICMP 后查询 DNS 服务器,并收到响应。这样就得到了dns.google

再次回到原文ping

  • ping -n -c 1 dns.google查询 DNS 服务器并在 ICMP 之前收到响应。这将转换dns.google8.8.8.88.8.4.4
  • ping -c 1 dns.google在 ICMP 之前查询 DNS 服务器并接收响应(转换为8.8.8.8或 转换为8.8.4.4)以及在 ICMP 之后分别接收响应(转换回来)。

答案2

从手册页中:

-n 仅输出数字。不会尝试查找主机地址的符号名称

所以区别在于输出:

>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

相关内容