声明:由于此文章本人先发表于网易,后由网易copy过来,故若出现图片无法显示现象,可到如下地址阅读此文章:http://zqdiadra.blog.163.com/blog/static/656710672010921101237/,另附上本人制作的PDF实验笔记。

实验目的:

    TCP/IP卷一中代理ARP一节下有这么一段话:主机123.1.1.1需要向主机34.1.1.4发送数据包,但是它没有配置缺省网关信息,因而也就不知道如何到达路由器。这时它可以向34.1.1.4发送一个ARP请求;本地路由器收到这一请求,并且路由器知道如何到达网络34.1.1.0,因此路由器将回复以上请求,其中把自己的数据链路标识符作为ARP回复数据包中的硬件地址。

    对于该段话描述,本人产生很大的疑问,后经网上搜索一些资料,又产生更多的疑问:

  1. 没有缺省网关的主机是否会发出ARP请求?

        如果按书中所说,主机只需要将ARP请求发出来,接着就会得到网关路由器的应答,也就意味着主机能形成所有IP与网关路由器接口的MAC地址的对应关系。这也就是说,当主机想要进行数据通信的时候,它的数据帧中的所有报头信息是完全的,它只要像扔出ARP请求数据那样扔出其它数据包,它就是能正常上网的。但在实际情况中,未配置缺省网关的主机是无法上网的。这两种结果是相互矛盾的。
        后经向老师请教,遂得知该段话并不严谨,实际主机是不会发出ARP请求的,但用路由器模拟的主机是可以的。
  2. 关闭代理后,不同网段是否能正常通信?

        既然通过代理ARP可以是两个网段通信,那么当关闭代理ARP时,两个网段是否能正常通信?此时,数据帧里的信息怎么打?
  3. ARP请求是否能跨网段传递?

        资料显示,在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的MAC地址。而在TCP/IP协议栈中,网络层和传输层只关心目标主机的IP地址。这就导致在以太网中使用IP协议时,数据链路层的以太网协议接到上层IP协议提供的数据中,只包含目的主机的IP地址。于是需要一种方法,根据目的主机的IP地址,获得其MAC地址。这就是ARP协议要做的事情。所谓地址解析(address resolution)就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。另外,当发送主机和目的主机不在同一个局域网中时,即便知道目的主机的MAC地址,两者也不能直接通信,必须经过路由转发才可以。所以此时,发送主机通过ARP协议获得的将不是目的主机的真实MAC地址,而是一台可以通往局域网外的路由器的某个端口的MAC地址。于是此后发送主机发往目的主机的所有帧,都将发往该路由器,通过它向外发送。这种情况称为ARP代理(ARP Proxy)。
        疑问点是,如果ARP不能跨网段传递,那么在和远程主机通信时,数据帧中的信息又是怎么打的?

    因此实验目的主要是为了解决上述疑问,另外通过抓包学习ARP结构,推测数据的路由转发过程。

 


 

实验设计:

    用路由器R1、R2、R4模拟主机,R3为路由器。

  1. 研究123.1.1.0/24网段内,ARP表的形成过程及ARP数据包信息结构。
  2. 开启R3的代理功能、和关闭R3的代理功能,ARP表是否有区别。
  3. 开启所有路由器的路由功能,研究无路由协议时ARP表状况;有路由协议时,开启和关闭R3代理功能两种情况下,ARP数据表情况。

 


 

实验拓扑图:

代理ARP实验 - 守望天空 - 凝望天际 体会孤独

 


 

实验过程:

    基本的配置信息我就不写了,现在捡要点说。

  1. 主机在没有缺省网关的情况下是不会发出数据包的,下图是抓取的虚拟机中windows主机以太网接口数据。 
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        简要说明一下该过程,在×××信息以上,是配置有缺省网关的时候,192.168.100.0网段是可以ping通的,×××信息之后是删掉缺省网关信息之后的ping,此时,192.168.100.0网段就不通了,未抓取到去往192.168.100.0的ping包,说明主机根本未产生该种数据包,也为进行过ARP的查询,因此也说明了卷一中那段话是有问题的。
        然后再说一下no ip routing这条命令,这是用路由器R1、R2、R3模拟主机时所使用的,这条命令也许就是路由器模拟主机与真实主机之间区别的关键命令。no ip routing就是禁用了路由器的路由功能。当网络设备接收到数据的时候,首先就是要进行路由匹配来进行选路的,如果没有匹配项,数据将会被丢弃。因此,在使用no ip routing命令模拟主机之后,路由器将不能在进行路由匹配工作,从严格意义来说,应该是任何数据包都无法发出的,这就与要用其模拟主机的目的不符。所以,对no ip routing的理解应该是:对于该路由器自身产生的流量,无条件发出,对于接收到的流量,不进行路由转发。这就解释了为什么主机在没有缺省网关的情况下不能正常通信,而路由器模拟的主机在没有缺省网关的情况下可以正常通信。
        另外,根据资料,真实的主机自身是存在主机路由表(可参考
    http://wenku.baidu.com/view/e648e67101f69e314332944a.html)的,该表项中包括本机回环地址、本机局域网网段路由等,因此,在不配缺省网关的情况下,主机无法与外界进行通信。同时这也表明,数据转发的第一步是要进行路由匹配。
  2. 在R1上ping R2的地址,进行抓包,获取ARP包信息如下:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        上面的小框为简明信息,包括源地址、目标地址、协议、简明信息。在下面的具体数据信息中,二层头部中的源地址为ca00.04a0.0000,目标地址为二层广播地址,上层的ARP信息中表明其是一个请求信息,硬件地址类型为以太网、协议地址类型为IP、硬件地址长度为6字节、协议地址长度为4字节、操作类型为请求。注意下面的目的MAC地址,此处为全0,与二层头部中使用广播地址不同。
        
        ARP应答消息抓包如下: 
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        应答时使用的是单播地址,且在ARP包信息中,源/目地址均会明确的注明。
  3. 在R1、R2、R4为模拟主机,R3开启代理ARP功能的情况下,首先看看arp表的情况,如下图:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        34.1.1.0/24网段的MAC地址均为R3 F0/0口的MAC地址,对于R3的两个接口进行抓包,其结果如下:

        R3 F0/0口
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        这是一个请求34.1.1.4的MAC地址的ARP请求包,再看随后的第59条ARP的应答信息,表明34.1.1.4的MAC地址为ca04.04a0.0000,该地址是R3 F0/0接口的MAC地址,即使用了代理ARP。

        R3 F1/0 
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
     
        由此可看出,当数据跨网段传递后,路由器并未告诉目的地址34.1.1.4,123.1.1.1要查询其MAC,反而表明是它自己(34.1.1.3)要查询其MAC。再随后的两条ARP信息,是因为ping需要回包,而R4当时并没有123.1.1.1的MAC地址故发送了请求,同样路由器返回了自己接口的MAC地址。
  4. 下面再ping一下该网段内不存在的地址,假设为34.1.1.5,抓包如下:

        R1 F0/0
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        R3 F1/0
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
       
        由抓包结果可知,对于34.1.1.0/24网段内的一个不存在的主机地址,路由器依然会告诉123.1.1.1自身接口的MAC地址,然后在34.1.1.0/24网段内发送ARP请求。因此这种情况下,R1并没有丢弃数据,数据被发送到R3后才被丢弃。如图中的ping包,R1已形成数据包,并发送了ping请求,达到R3后,因R3查不到34.1.1.5的MAC,故丢弃了该数据包。
        对于实际的情况而言,如果R1收不到ARP应答,则后续包就不会产生,如下图:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

        上图中均为由ping引起的路由器在另一网段内的ARP请求信息,而ping包却未形成。
     
  5.  
    当关闭代理ARP功能之后,34.1.1.0/24网段便不再可达,如下图,R1的ARP请求无人应答:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
      
    3、4、5说明一条ARP信息是无法跨网段传播的。
  6. 在全部开启路由功能的情况下,无论是否开启R3打代理ARP功能,R1的arp表项只有3条,而且一直是同网段内的三条,如下图所示:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
     
        R1上抓包结果如下所示:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
     
        此图为在R1上多次使用clear arp-cache命令后所产生的结果,仔细观察可发现,这些包与传统的ARP请求应答包还是有很多不同的,详见第8点。
        在随后的ping实验中,无路是否开启代理ARP功能,R1去往34.1.1.0/24的数据目的MAC地址也一直都是R3 F0/0接口的MAC地址。如图:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

  7. 接下来,在开启路由功能的情况下,用R1 ping 34.1.1.5,抓包结果如下:
        R3 F0/0
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
     
        R3 F1/0
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
       
        同样可看出,R1的形成了ping包并全部发送给了R3,R3发出了ARP请求,但无人应答,因此丢弃了全部的ping请求。
       
        在此,首先说明一个我目前仍然存在的疑问:那就是在随后的开启路由功能的实验中,R1去往34.1.1.4的数据包的二层头部中使用的还是R3 F0/0接口的MAC地址,这与代理ARP很相似,因为如果不这样做的话,二层头部信息将会是不正确的,所以我怀疑它是不是真正的代理ARP的情况。
        结合一下路由转发规则和数据封装过程说明一下。首先,数据自上而下进行封装,跳过上几层不考虑,它需要一个三层的头部,其中需要源、目IP地址信息,然受是一个二层头部,需要源、目的硬件地址信息。当路由器收到一个需要路由的数据包时,首先他会解封并读取数据中二层地址信息,确定该信息是不是转给它自己的(不是自己的硬件地址将丢弃)(由此也可知为什么在5中,当关闭代理ARP的时候,两网段便不能再通信了),然后读取三层地址信息,查询自己的路由表,确定需要将数据从哪里转发出去,然后重新生成二层头部将数据转发出去。如下图所示,在路由器路由表中,可查询到去往某个网段的下一跳及出接口信息,基于这些信息可在CAM表中查询到与之相对应的MAC地址信息。也就是说,当R1要向34.1.1.4发送数据时,在三层头部中封装的信息为:34.1.1.4(目)、123.1.1.1(源),在查询过路由表后,确定下一跳为123.1.1.3,因此将其硬件地址信息封装在二层头部中,由下一个路由器决定该数据的后续处理过程。所以,以这么一个过程来看的的话,路由环境下的这种情况不能被称为代理ARP。另外几点佐证是:首先,在开启路由功能的情况下,ARP表中不会有其他网段的ARP映射信息,同样主机在配置缺省网关后,也不会存在其它网段的ARP映射关系,换句话说,就是这种情况下,是不可能得到第3点中的那张代理ARP表的;再者,无论R3 F0/0上的代理功能是否开启,它均不会对两个网段之间的通信产生任何影响,包括诱发新的数据包的产生(这一点是比较有说服力的理由)。
        但是话又说回来,如果不将路由环境下的情况视为代理ARP,那么代理ARP的功能似乎只能存在于“实验情况”以及卷一中的“透明路由器”情况之下,这又似乎让它缺乏实际的存在价值。所以,这让我怀疑我的判断。
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

  8. 在开启路由功能后,抓到了很奇怪的ARP包,如下:
    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
     
        首先看简明信息,123.1.1.1的MAC地址是ca00.04a0.0000,操作类型字段也表明这是一个ARP应答消息,但是在此之前,却没有关于123.1.1.1的ARP请求信息。作为一个应答ARP消息,其二层头部目的地址却是广播地址,另外,ARP信息中源、目的IP均为123.1.1.1,目的MAC地址为ffff.ffff.ffff。很像是一个无故ARP,但是却与无故ARP的特定有着很大的区别。首先无故ARP是一个ARP请求消息,而此包是一个应答包;其次,在ARP消息字段中目的MAC地址应该是0000.0000.0000,而此处是ffff.ffff.ffff;再者,无论是开启还是关闭无故ARP功能,使用clear arp-cache命令后都能抓到该包。同样,123.1.1.2与123.1.1.3也都发出过该包。在某人博客上,将其也归为无故ARP,但是未作详细解释,故不是很有说服力,详见http://zhangxiaoshi82.blog.163.com/blog/static/43100801200782065734617/,该blog中包含有无故ARP的抓包图(我并未抓到无故ARP的包)。
       
    随后,在与老师探讨过该问题后,我便再次进行实验,将路由器一个个分别配好,经抓包发现,当路由器接口开启后,它便会发出两条此类ARP应答广播,抓包如下图:

    代理ARP实验 - 守望天空 - 凝望天际 体会孤独

       
    因此,说该ARP为无故ARP也不为过,但是,与此同时又出现了新的问题。仍旧看上图,可以发现R1、R2竟然都向路由器R3发出了ARP请求?!卷一中讲无故ARP的用途的时候便有这么一条:无故ARP可用于通告自身的数据链路标识符,以便其它设备学到。但是奇怪的是R1、R2、R3都通告了自己的数据链路标识符,却都没有更新自己的CAM表。因此该消息是否为无故ARP,真的的无从判断。
        另外还有一点奇怪的是,R1、R2都像节点路由器R3发出ARP请求,但是R1、R2之间却未出现过ARP请求,而且R1、R2的ARP表中均不包含对方的表项。但是当用R1 ping R2之后,无论如何用clear arp-cache清表,却都无法再将对方的表项清楚,抓包结果见第6点第2幅图。此点可能与CEF有关,因为当关闭CEF后,将接口shutdown然后再开启,ARP表项便只有它自己;但当开启CEF功能的时候,ARP表中就包含它自己(非节点)与节点路由器,节点路由器上则有全部的邻居ARP表项。但是同样,在路由环境下,无论CEF是开启还是关闭,clear arp-cache命令均无法达到清表的目的

    代理ARP实验 - 守望天空 - 凝望天际 体会孤独
       
       
    从简明信息上看,这应该是一个请求包,操作类型字段也证明了这一点,但是它的二层头部地址却是一个单播地址。另外,ARP消息中目的MAC地址信息是存在的,而不像普通ARP请求那样全被设置为0。其后who has 123.1.1.3? tell 123.1.1.1也是如此。这同样很让人费解,既然知道了对方的MAC,为何还要进行查询。随后我考虑会不会是CEF的问题,但是当关闭CEF功能的时候此现象依然存在。而后我想到,既然能存在CEF这么一种机制来实现快速转发,那么会不会存在另外一张表来使的路由器绕过ARP查询这一步,也就是说当我清ARP缓存的时候,路由器便要发送ARP请求,但是当它进行数据转发的时候使用了另外一张表,从而获得了MAC地址,因此便形成了一个目的明确的单播请求。当然一切都只是猜测,剩下的疑问留待以后解决。

 

 


 

    最后,很想写点总结,但是发现解决了一些问题,同时又产生了很多新的问题,因此,总结无从写起。所以在最后,还是写下仍然存在的疑问吧,方便以后回顾。

存疑点

  1. 路由模式下是否存在代理ARP?参考第7点。
  2. 为什么路由模式下,会自发进行ARP查询?为什么只与节点路由器进行查询。
  3. 单播ARP请求及类似于无故ARP的广播ARP应答,参考第8点。

 


    因为本人水平有限,故文章中可能有些错误的地方,欢迎大家指出以及提供些宝贵的意见。