21.3 二/三层地址转换 --- ARP

下一个与以太网通信相关的协议是ARP。在以太网层面,每个主机都有一个以太网地址。但是为了能在互联网上通信,你需要有32bit的IP地址。为什么需要IP地址呢?因为IP地址有额外的含义。IP地址的高位bit包含了在整个互联网中,这个packet的目的地在哪。所以IP地址的高位bit对应的是网络号,虽然实际上要更复杂一些,但是你可以认为互联网上的每一个网络都有一个唯一的网络号。路由器会检查IP地址的高bit位,并决定将这个packet转发给互联网上的哪个路由器。IP地址的低bit位代表了在局域网中特定的主机。当一个经过互联网转发的packet到达了局域以太网,我们需要从32bit的IP地址,找到对应主机的48bit以太网地址。这里是通过一个动态解析协议完成的,也就是Address Resolution Protocol,ARP协议。

当一个packet到达路由器并且需要转发给同一个以太网中的另一个主机,或者一个主机将packet发送给同一个以太网中的另一个主机时,发送方首先会在局域网中广播一个ARP packet,来表示任何拥有了这个32bit的IP地址的主机,请将你的48bit以太网地址返回过来。如果相应的主机存在并且开机了,它会向发送方发送一个ARP response packet。

下图是一个ARP packet的格式:

它会出现在一个以太网packet的payload中。所以你们看到的将会是这样的结构:首先是以太网header,它包含了48bit的目的以太网地址,48bit的源以太网地址,16bit的类型;之后的以太网的payload会是ARP packet,包含了上图的内容。

接收到packet的主机通过查看以太网header中的16bit类型可以知道这是一个ARP packet。在ARP中类型值是0x0806。通过识别类型,接收到packet的主机就知道可以将这个packet发送给ARP协议处理代码。

有关ARP packet的内容,包含了不少信息,但是基本上就是在说,现在有一个IP地址,我想将它转换成以太网地址,如果你拥有这个IP地址,请响应我。

同样的,我们也可以通过tcpdump来查看这些packet。在网络的lab中,XV6会在QEMU模拟的环境下发送IP packet。所以你们可以看到在XV6和其他主机之间有ARP的交互。下图中第一个packet是我的主机想要知道XV6主机的以太网地址,第二个packet是XV6在收到了第一个packet之后,并意识到自己是IP地址的拥有者,然后返回response。

tcpdump能够解析出ARP packet,并将数据打印在第一行。对应ARP packet的格式,在第一个packet中,10.0.2.2是SIP,10.0.2.15是DIP。在第二个packet中,52:54:00:12:34:56对应SHA。

同时,我们也可以自己分析packet的原始数据。对于第一个packet:

  • 前14个字节是以太网header,包括了48bit目的以太网地址,48bit源以太网地址,16bit类型。

  • 从后往前看,倒数4个字节是TIP,也就是发送方想要找出对应以太网地址的IP地址。每个字节对应了IP地址的一块,所以0a00 020f对应了IP地址10.0.2.15。

  • 再向前数6个字节,是THA,也就是目的地的以太网地址,现在还不知道所以是全0。

  • 再向前数4个字节是SIP,也就是发送方的IP地址,0a000202对应了IP地址10.0.2.2。

  • 再向前数6个字节是SHA,也就是发送方的以太网地址。

  • 剩下的8个字节表明了我们感兴趣的是以太网和IP地址格式。

第二个packet是第一个packet的响应。

学生提问:ethernet header中已经包括了发送方的以太网地址,为什么ARP packet里面还要包含发送方的以太网地址?

Robert教授:我并不清楚为什么ARP packet里面包含了这些数据,我认为如果你想的话是可以精简一下ARP packet。或许可以这么理解,ARP协议被设计成也可以用在其他非以太网的网络中,所以它被设计成独立且不依赖其他信息,所以ARP packet中包含了以太网地址。现在我们是在以太网中发送ARP packet,以太网packet也包含了以太网地址,所以,如果在以太网上运行ARP,这些信息是冗余的。但是如果在其他的网络上运行ARP,你或许需要这些信息,因为其他网络的packet中并没有包含以太网地址。

学生提问:tcpdump中原始数据的右侧是什么内容?

Robert教授:这些是原始数据对应的ASCII码,“.”对应了一个字节并没有相应的ASCII码,0x52对应了R,0x55对应了U。当我们发送的packet包含了ASCII字符时,这里的信息会更加有趣。

我希望你们在刚刚的讨论中注意到这一点,网络协议和网络协议header是嵌套的。我们刚刚看到的是一个packet拥有了ethernet header和ethernet payload。在ethernet payload中,首先出现的是ARP header,对于ARP来说并没有的payload。但是在ethernet packet中还可以包含其他更复杂的结构,比如说ethernet payload中包含一个IP packet,IP packet中又包含了一个UDP packet,所以IP header之后是UDP header。如果在UDP中包含另一个协议,那么UDP payload中又可能包含其他的packet,例如DNS packet。所以发送packet的主机会按照这样的方式构建packet:DNS相关软件想要在UDP协议之上构建一个packet;UDP相关软件会将UDP header挂在DNS packet之前,并在IP协议之上构建另一个packet;IP相关的软件会将IP heade挂在UDP packet之前;最后Ethernet相关的软件会将Ethernet header挂在IP header之前。所以整个packet是在发送过程中逐渐构建起来的。

类似的,当一个操作系统收到了一个packet,它会先解析第一个header并知道这是Ethernet,经过一些合法性检查之后,Ethernet header会被剥离,操作系统会解析下一个header。在Ethernet header中包含了一个类型字段,它表明了该如何解析下一个header。同样的在IP header中包含了一个protocol字段,它也表明了该如何解析下一个header。

软件会解析每个header,做校验,剥离header,并得到下一个header。一直重复这个过程直到得到最后的数据。这就是嵌套的packet header。

Last updated