如何解释这个`tcpdump`输出

网络工程 arp 转储
2021-07-29 15:21:54

tcpdump输出是通过简单的集线器连接从主机 1 向主机 2 发送单个 ping 包的结果:

root@mininet-vm:~# tcpdump -XX -n -i h2-eth0 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on h2-eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
00:19:06.466207 ARP, Request who-has 10.0.0.2 tell 10.0.0.1, length 28
        0x0000:  ffff ffff ffff 0000 0000 0001 0806 0001  ................
        0x0010:  0800 0604 0001 0000 0000 0001 0a00 0001  ................
        0x0020:  0000 0000 0000 0a00 0002                 ..........
00:19:06.466285 ARP, Reply 10.0.0.2 is-at 00:00:00:00:00:02, length 28
        0x0000:  0000 0000 0001 0000 0000 0002 0806 0001  ................
        0x0010:  0800 0604 0002 0000 0000 0002 0a00 0002  ................
        0x0020:  0000 0000 0001 0a00 0001                 ..........
00:19:06.468925 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 4587, seq 1, length 64
        0x0000:  0000 0000 0002 0000 0000 0001 0800 4500  ..............E.
        0x0010:  0054 ac58 4000 4001 7a4e 0a00 0001 0a00  .T.X@.@.zN......
        0x0020:  0002 0800 7d50 11eb 0001 ea2e f155 0000  ....}P.......U..
        0x0030:  0000 c86b 0600 0000 0000 1011 1213 1415  ...k............
        0x0040:  1617 1819 1a1b 1c1d 1e1f 2021 2223 2425  ...........!"#$%
        0x0050:  2627 2829 2a2b 2c2d 2e2f 3031 3233 3435  &'()*+,-./012345
        0x0060:  3637                                     67
00:19:06.468961 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 4587, seq 1, length 64
        0x0000:  0000 0000 0001 0000 0000 0002 0800 4500  ..............E.
        0x0010:  0054 d17f 0000 4001 9527 0a00 0002 0a00  .T....@..'......
        0x0020:  0001 0000 8550 11eb 0001 ea2e f155 0000  .....P.......U..
        0x0030:  0000 c86b 0600 0000 0000 1011 1213 1415  ...k............
        0x0040:  1617 1819 1a1b 1c1d 1e1f 2021 2223 2425  ...........!"#$%
        0x0050:  2627 2829 2a2b 2c2d 2e2f 3031 3233 3435  &'()*+,-./012345
        0x0060:  3637                                     67
00:19:11.471904 ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 28
        0x0000:  0000 0000 0001 0000 0000 0002 0806 0001  ................
        0x0010:  0800 0604 0001 0000 0000 0002 0a00 0002  ................
        0x0020:  0000 0000 0000 0a00 0001                 ..........
00:19:11.509755 ARP, Reply 10.0.0.1 is-at 00:00:00:00:00:01, length 28
        0x0000:  0000 0000 0002 0000 0000 0001 0806 0001  ................
        0x0010:  0800 0604 0002 0000 0000 0001 0a00 0001  ................
        0x0020:  0000 0000 0002 0a00 0002                 ..........

我对输出的顺序有点困惑。
我会假设顺序

ARP-request host 1 to host 2
ARP-reply host 2 to host 1
ICMP echo request host 1 to host 2
ARP-request host 2 to host 1
ARP-reply host 1 to host 2
ICMP echo reply host 2 to host 1

tcpdump显示顺序

ARP-request host 1 to host 2
ARP-reply host 2 to host 1
ICMP echo request host 1 to host 2
ICMP echo reply host 2 to host 1
ARP-request host 2 to host 1
ARP-reply host 1 to host 2

我不明白。

我的假设是,在通过 ICMP 进行回声回复之前,主机 2 必须使用 ARP 请求主机 1 的 MAC 地址。

我怎么了?

或者tcpdump只是更改其输出格式的顺序,以便 ICMP 请求和回复在tcpdump的输出中相距不远

更新:所有主机和网络集线器都运行带有内核 3.13.0-24-generic 的 Ubuntu 14.04(更准确地说:我正在运行一个 VM,我在其中运行带有集线器星型拓扑的 mininet)。

2个回答

你的假设是有缺陷的。

当主机 2 收到来自主机 1 的 ARP 请求时,除了发送 ARP 回复外,它还应该在它自己的 ARP 表中更新/添加主机 1 的条目。

因此,您的订单应该扩展为更像这样:

ARP-request host 1 to host 2
Host 2 updates or adds entry for host 1 in ARP table
ARP-reply host 2 to host 1
Host 1 adds entry for host 2 in ARP table
ICMP echo request host 1 to host 2
ICMP echo reply host 2 to host 1

至于为什么主机 2 这么快就发出 ARP 请求,我猜想您使用的操作系统要么为以这种方式添加的条目保留一个短计时器,要么发送 ARP 请求以最大程度地减少任何潜在 ARP 中毒攻击的影响。然而,这只是一个猜测,需要调查操作系统实际在做什么才能确定。

有关 ARP 过程的更多详细信息,您可以查看RFC 826这是来自 RFC 的处理流程:

Packet Reception:
-----------------

When an address resolution packet is received, the receiving
Ethernet module gives the packet to the Address Resolution module
which goes through an algorithm similar to the following.
Negative conditionals indicate an end of processing and a
discarding of the packet.

?Do I have the hardware type in ar$hrd?
Yes: (almost definitely)
  [optionally check the hardware length ar$hln]
  ?Do I speak the protocol in ar$pro?
  Yes:
    [optionally check the protocol length ar$pln]
    Merge_flag := false
    If the pair <protocol type, sender protocol address> is
        already in my translation table, update the sender
        hardware address field of the entry with the new
        information in the packet and set Merge_flag to true.
    ?Am I the target protocol address?
    Yes:
      If Merge_flag is false, add the triplet <protocol type,
          sender protocol address, sender hardware address> to
          the translation table.
      ?Is the opcode ares_op$REQUEST?  (NOW look at the opcode!!)
      Yes:
        Swap hardware and protocol fields, putting the local
            hardware and protocol addresses in the sender fields.
        Set the ar$op field to ares_op$REPLY
        Send the packet to the (new) target hardware address on
            the same hardware on which the request was received.

我的假设是,在通过 ICMP 进行回声回复之前,主机 2 必须使用 ARP 请求主机 1 的 MAC 地址。

基于 ARP 的 IP 地址到 MAC 地址的映射会缓存一段时间,因此不会对每个传输的单个 IP 数据包发出 ARP 请求。

在通过 ICMP 进行回声回复之前,主机 2 必须知道主机 1 的 MAC 地址。

如果它已经知道它,例如因为它想发送的其他东西而之前的某个时间发送了一个 ARP 请求,因此它在 ARP 缓存中,它就不必使用 ARP 请求该地址。

也许缓存的 ARP 映射已过期并在发送回显回复后一段时间从缓存中删除,并且出于某种原因,它决定需要该地址并再次对其进行 ARP。

或者tcpdump只是改变其输出格式的顺序

不会。Tcpdump 按照从 libpcap 接收数据包的顺序打印数据包,libpcap 按照数据包从操作系统到达的顺序将数据包交给应用程序。

此外,请注意第二个 ARP 请求上的时间戳大于 ICMP Echo Reply 上的时间戳,因此第二个 ARP 请求是在 ICMP Echo Reply 之后发送的 - 几乎 5 秒。