一步一步学习IP路由流程

技术标签: 路由  arp

TCP/IP协议簇是目前互联网应用最广的协议栈,谈到TCP/IP协议栈就不能不讲一讲IP路由的问题,因为在我们使用的网络通信中几乎每时每刻都在发生着IP路由的事件……。当你在网络世界中还是一位新手的时候,你也许认为设备之间实现IP路由所需的仅仅是一台设备的IP地址而已,如果你真的这样认为那就错了。每台设备在进行IP路由的时候除了必需的IP地址外还需要很多其他信息来完成数据的封装!我将通过以下网络场景提供的案例一步一步地来分析设备在进行IP路由时将会发生哪些通信事件。

 

 

      在这个场景中有两个网络,这两个网络通过一台具有两个以太网接口(F0/0,F0/1)的路由器连接在一起。路由器的这两个端口和你自己电脑上的RJ-45型号的网卡端口是一样的,都是内建在路由器中的。现在我们来看一看当位于网络A的主机A想要和位于网络B的主机B进行通信时都发生了什么?

 

      主机A打开命令提示符(具体方法:开始——运行——cmd),命令提示符(>)后输入ping 1.1.1.5  当“ping”这个指令被计算机执行的时候,TCP/IP协议栈会调用该协议栈互联网层的“ICMP”协议封装“ping 1.1.1.5”这个请求。


ICMP协议封装如下:

ICMP报头 (主机A) Ping 1.1.1.5

      Host A(主机A)若要将这个ICMP协议封装的请求发送给目标主机B(Host B)就必须要使用IP协议来“运输”该请求。这样,IP协议这个时候就充当了一个邮差的角色,将ICMP这个数据包写上发送者(主机A)的IP地址和接收者(主机B)的IP地址,然后就可以根据这个目标地址(主机B的地址)来“投递”这个数据包了。

IP协议封装如下:

IP报头 ICMP报头 (主机A) Ping 1.1.1.5


      经过IP协议封装的数据包只是完成了TCP/IP协议簇网络层上的封装,接下来要完成的是数据链路层的封装。在进行数据链路层的信息封装之前主机A还需启动IP路由进程来判断目标主机B在本地网络还是在远程网络。若主机B在本地网络,说明主机B和主机A在同一个逻辑子网中,也就是同一个IP网段内。若主机B在远程网络则说明主机B与主机A不在同一个网段内,比如本例中,主机A位于网络A而主机B位于网络B。显而易见,在本例的网络场景中主机A会判断出主机B位于远程网络。那么问题是主机A是如何做出判断的呢?
      首先主机A将自己的IP地址和子网掩码作“与运算”。所谓与运算就是无论是二进制的“0”和“1”相与还是二进制的“0”和“0”相与,得出的结果都为“0”,而只有二进制“1”和“1”相与得出的结果为“1”。比如本例中,主机A的IP地址为192.168.0.5,将这个IP地址转换为二进制就是:11000000 10101000 00000000 00000101
      主机A的子网掩码为255.255.255.0,将该掩码转换为二进制就是:11111111 11111111 11111111 00000000 将主机A二进制形式的IP地址和子网掩码作“与运算”的结果是:  11000000 10101000 00000000 00000000
      为了方便查看将这个“与运算”的结果再转换为点分十进制的数就是:192.168.0.0
      这样主机A就通过“与运算”完成了IP路由判断的第一步。接下来的第二步是将目标主机(主机B)的IP地址与发送方(主机A)的子网掩码作“与运算”,比如本例中,主机B的IP地址为1.1.1.5,将这个IP地址转换为二进制就是:00000001 00000001 00000001 00000101
      主机A的子网掩码为255.255.255.0将该掩码转换为二进制就是:11111111 11111111 11111111 00000000 将以上两组二进制的数进行“与运算”的结果是:00000001 00000001 00000001 00000000 将这个“与运算”的结果转换为点分十进制的数就是:1.1.1.0 这样我们就得到了两组“与运算”的结果,分别是:192.168.0.0和1.1.1.0
      对于主机A来说,经过这样一番“与运算”后,如果两个“与运算”结果相同,则说明目标主机B和自己在同一个网络内,即目标主机B在本地网络。相反地,对于主机A来说,经过这样一番“与运算”后,如果两个“与运算”结果不同,则说明目标主机B和自己不在同一个网络内,即目标主机B在远程网络。在本例中,很显然目标主机B对于发送方(主机A)来说在远程网络——也就是在网络B。
      主机A通过以上与目标主机B略显复杂的“与运算”后,完成了路由判断的第一步——判断出了目标主机B在远程网络。接下来主机A需要“思考”的是如何才能够到达主机B所在的网络?主机A首先会查询自己的路由表,看在自己的路由表中能否找到去往目标网络(网络B)的路由条目。为了方便大家理解,我将主机A的路由表输出显示如下:

 


C:\>route print
Active Routes:
Network Destination         Netmask             Gateway          Interface         Metric
               0.0.0.0             0.0.0.0            192.168.0.1      192.168.0.5         10
             127.0.0.0          255.0.0.0            127.0.0.1         127.0.0.1           1
           192.168.0.0     255.255.255.0      192.168.0.5      192.168.0.5         10
           192.168.0.5   255.255.255.255       127.0.0.1         127.0.0.1           10
         192.168.0.255   255.255.255.255   192.168.0.5      192.168.0.5         10
             224.0.0.0           240.0.0.0         192.168.0.5      192.168.0.5         10
       255.255.255.255  255.255.255.255   192.168.0.5      192.168.0.5         1

Default Gateway: 192.168.0.1

      从主机A路由表的输出显示中我们没有找到与目标主机B所在的网络相匹配的具体路由,也就是说主机A没有到达1.1.1.0这个网络的路由。但是我们注意到在该路由表的最后一行输出的是:  Default Gateway(默认/缺省网关): 192.168.0.1 路由表最后一行的输出说明主机A在没有找到能够到达目标网络的具体路由的情况下,会将发往目标网络的数据包发送到默认/缺省网关(192.168.0.1),由这个默认/缺省网关再将该数据包转发到目标网络。
      好了,现在主机A知道了默认网关(192.168.0.1)是自己的下一跳地址,主机A开始执行封装。封装信息如下:
 

目的MAC:
下一跳设备的MAC
源MAC:
主机A的MAC地址
源IP:
192.168.0.5
目的IP:
1.1.1.5
ICMP报头 (主机A)
Ping 1.1.1.5

     
      在以上所封装的寻址信息当中,主机A唯一不知道的就是“下一跳设备的MAC地址”,这里的“下一跳设备MAC地址”是指主机A的默认网关192.168.0.1的F0/0接口的MAC地址。这里容易让人产生一个困惑,主机A的目的IP地址是主机B,那么为什么主机A封装的链路层的目的MAC地址却是路由器F0/0的MAC地址呢?原因是当初人们在设计数据链路层时主要考虑如何解决一条线路上相邻两端设备之间的通信。
      从这个网络场景中我们看到主机A和主机B从各自所处的物理位置上看并不属于相邻的两台设备(中间隔着一台路由器)。既然主机B并不是主机A直接相邻的设备,那么主机A在数据链路层封装的目的MAC地址当然就不可能是主机B了。主机A通过IP路由的流程判断和查询路由表知道要想到达主机B就必须将数据包发给路由器A的F0/0接口(F0/0接口也是主机A到达主机B必经的直接相邻的接口),因此F0/0的MAC地址就成为主机A在数据链路层封装的目的MAC地址。在本例中假如主机A要给Server A发送数据而不是给主机B,那么主机A在数据链路层封装的目的MAC地址就是Server A的MAC地址,因为Server A与主机A是彼此直接相邻的设备。那么对于主机A来说它是否知道路由器F0/0接口的MAC地址呢?主机A是不知道的。所以接下来主机A需要做的是如何才能找到F0/0接口的MAC地址以完成数据链路层的封装成帧。首先主机A查看自己的ARP缓存表,每台主机/电脑都有这个ARP缓存表,该缓存表记录着与自己发生过通信的所有的直接相邻设备或主机的硬件地址(MAC地址),ARP缓存表经过一段时间会自动删除,比如Windows 的动态 ARP 缓存条目不超过 10 分钟就会被删除。如果主机A与路由器之前曾发生过通信,主机A自然能在ARP缓存表中找到路由器F0/0的硬件MAC地址,可是如果这是主机A与路由器的第一次通信,则主机A会向网络A上发送发送ARP广播请求数据包,该ARP请求包包含的关键信息如下:

 

发送方IP地址(192.168.0.5) 发送方MAC地址(主机A MAC地址)
目的IP地址(192.168.0.1) 目的MAC地址(000000000000)


      以上ARP请求包中封装的三项信息都是已知的,只有“目的MAC地址”这一信息是未知的(全“0”填充)。当该ARP请求包发送到网络A上时,网络A上的设备接收该ARP包并查看该ARP包内的具体封装信息。因为该ARP包中封装的目的IP地址是192.168.0.1,所以只有具有192.168.0.1这个IP的接口或设备才应答该ARP查询请求,应答者会将自己的硬件MAC地址封装到这个ARP应答数据包中。这个ARP应答数据包(本例中由路由器F0/0接口发出ARP应答)封装的关键信息如下:

 

发送方IP地址(192.168.0.1) 发送方MAC地址(F0/0接口MAC地址)
目的IP地址(192.168.0.5) 目的MAC地址(主机A的MAC地址)

   
      主机A通过ARP协议解析出路由器F0/0接口的MAC地址从而完成了数据链路层的封装。通过主机A这个解析过程大家可以看到主机A在第一次与默认网关通信时的确是费了一番周折,为了找到默认网关F0/0接口的MAC地址也“耽搁”了一些时间,这也是为什么我们在第一次ping网络上某台主机/设备的时候通常会看到第一个数据包会出现“request timed out!”(请求超时!)的情况。最后主机A完成MAC地址解析后将该帧发送到网络A上,该帧的具体封装如下:

 

目的MAC:
路由器F0/0接口
源MAC:
主机A的MAC地址
源IP:
192.168.0.5
目的IP:
1.1.1.5
ICMP报头 (主机A) Ping 1.1.1.5


      因为该帧的目的MAC地址是F0/0的MAC地址,所以只有路由器的F0/0接口接收并处理该数据帧。路由器将该帧解封装并查看网络层的封装信息,路由器看到该数据包网络层封装的目的地址是1.1.1.5。路由器为了将这个数据包转发到1.1.1.5,使用前面提到的“与运算”的方法进行计算,依据计算结果判断目标地址1.1.1.5对于路由器自己来说在本地网络还是在远程网络。路由器所做“与运算”过程简述如下:

      路由器的F0/0接口上的IP地址192.168.0.1与F0/0接口的子网掩码255.255.255.0作“与运算”得到“结果1”;目标地址1.1.1.5与路由器F0/0接口的子网掩码255.255.255.0作“与运算”得到“结果2”;“结果1”与“结果2”并不相同,证明目标地址1.1.1.5并不处在路由器的F0/0接口所在的网络A。
      路由器的另一个接口F0/1的IP地址1.1.1.1与F0/1接口的子网掩码255.255.255.0作“与运算”得到“结果3”;目标地址1.1.1.5与F0/1接口上
的子网掩码255.255.255.0作“与运算”得到“结果4”;“结果3”与“结果4”相同,证明目标地址1.1.1.5处在路由器的F0/1接口所在的网络B。这也就意味着路由器B只需将发送给1.1.1.5的数据包从F0/1接口发出去就OK了。我们将路由器的这种路由称为直接路由。

      路由器得出上述结论后立刻执行封装,封装的具体信息如下:

目的MAC:
主机B的MAC地址
源MAC:
路由器F0/1接口
源IP地址
192.168.0.5
目的IP地址
1.1.1.5
ICMP报头 (主机A) Ping 1.1.1.5


      在以上路由器封装的具体信息中的目的MAC地址是主机B的MAC地址。如果路由器在ARP缓存表中并未查到主机B的硬件MAC地址,则路由器仍然会像主机A查询路由器F0/0接口硬件MAC地址一样发送ARP请求来查询主机B的MAC地址。关于路由器对主机B 硬件MAC地址的查询过程在这里就不再重复了。
      这样主机B就收到了该数据帧,主机B对该帧进行解封装看到了网络层封装的目的IP地址,知道这个数据包的目的地是自己后,主机B继续对其拆封装并查看ICMP报头内的信息得出结论:这是一个请求自己进行反馈的数据包,需要自己将这条“数据包已到达主机B”的信息回馈给主机A。因此主机B为了将回馈信息顺利送达主机A需要经过如封装:

目的MAC:
路由器F0/1接口
源MAC:
主机B的MAC地址
源IP:
1.1.1.5
目的IP:
192.168.0.5
ICMP报头 对(主机A) Ping 1.1.1.5的应答


      主机B在发送应答数据包时封装的目的MAC地址是路由器F0/1接口的MAC地址,这也是主机B通过路由判断和与运算得出的结论,对于主机B来说路由器F0/1接口是它的下一跳。
      路由器F0/1接口在收到主机B发来的数据包后为了将其转发给主机A再次进行封装,具体的封装信息如下:

目的MAC:
主机A的MAC地址
源MAC:
路由器F0/0接口
源IP:
1.1.1.5
目的IP:
192.168.0.5
ICMP报头 对(主机A) Ping 1.1.1.5的应答


      从主机A到路由器再到主机B执行的封装过程中我们可以看出网络层封装的信息是始终不变的:源IP是192.168.0.5 目的IP是1.1.1.5。始终变化的是一跳一跳的硬件MAC地址。从主机B到路由器再到主机A执行的封装过程中我们同样可以看出网络层封装的信息也是始终不变的:源IP是1.1.1.5目的IP是192.168.0.5。始终变化的还是一跳一跳的硬件MAC地址。
      以上我们在IP路由封装的过程中得到的这一结论并不适用于另外一个网络技术——NAT(网络地址转换)。关于NAT我们将在其他的文章中继续讨论。

来源:网络


智能推荐

一步一步DirectAccess

百科-------------------------------------------------------------------------------------------- Direct Access 称为直接访问,它是Windows 7和Windows Server 2008 R2中的一项新功能。凭借这个功能,外网的用户可以在不需要建立×××连...

一步一步CCNA之二:路由器特权模式

上节我们简单介绍了路由器用户模式,同时进入了路由器特权模式(在用户模式下输入【enable】进入特权模式)。本节我们主要介绍特权模式下相关内容。 1.特权模式下命令列表如下,在特权模式下输入【?】即可列出。按下【空格键】分页显示内容,按下【回车键】逐行显示内容。顺便提一下,输入任何命令之后都可以输入【?】以得到接下来可以输入的命令列表。 2. 【show】命令。输入【show ?】,显示可以显示的...

一步一步CCNA之四:路由器端口配置

上一节我们简单介绍了全局配置模式以及一些有用的配置,本节我们配置路由器端口,同时将两个路由器端口连通。 1.输入【interface fastEthernet 0/0】进入0/0端口,输入【ip address 192.168.0.5 255.255.255.0】配置该端口IP以及子网掩码,注意,这里子网掩码是必须的。最后输入【no shutdown】开启该端口。这里需要说明一下,路由器的端口默认...

下一步学习计划

  搞了这么久,看了自己以前制定的工作计划,大体上算是完成了,在数据结构方面又做了进一步的研究,但是距自己对自己的要求还有一大段距离,特别是算法方面,还有待加强。为此,下一步的学习计划如下: a:复习以前自己所写的知识,总结总结,抽象出概念。 b: 学习算法的东西,不只是数据结构课本上的算法,这种东西都要强化训练,包括DP,贪心,背包问题,搜索等等,都需要自己强化训练。 c:关...

学习FPGA,踏上一步台阶

学习FPGA的过程中,要想踏上一步台阶,需要注意一下几点: 时序约束的原因和使用方法,能熟练正确的应用最基本的时钟周期约束,时序例外约束,异步时钟域约束,同步复位的约束,高扇出约束。         清楚FPGA芯片内部时钟资源分布,能够知道自己的逻辑和约束能否让编译器用比较优化的走线布局布线。         清楚内...

猜你喜欢

NPE进一步学习

2016-04-22,14:38:32续 NPE代码中的系数归一化,其实就是等价于LRC求出来的系数。!!! 我们先看看第一组:(每类重构系数归一化) 上图显示,(1)第24个样本的同类重构残差要远大于最相似的异类重构残差。这说明,会被识别错误。             &nbs...

前端学习第一步

这是本人的第一篇博客,来说说前端学习的一些基础中的基础——html。俗话说:“工欲善其事,必先利其器”,下面来做一些简单的介绍。 一、前端的开发工具     事实上,前端的开发工具门槛很低,甚至你用记事本就可以完成一次网页的编写(当然是很令人疲惫的,不过可以加深学习 的印象)。那么现在一些比较常用的软件是什么呢? 1.Hbuild...

微服务

 微服务,关键其实不仅仅是微服务本身,而是系统要提供一套基础的架构,这种架构使得微服务可以独立的部署、运行、升级,不仅如此,这个系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面,统一的权限管理,统一的安全策略,统一的上线过程,统一的日志和审计方法,统一的调...

ubuntu16.04安装docker

教程来自官网:https://docs.docker.com/install/linux/docker-ce/ubuntu/#extra-steps-for-aufs 这个很流行,而且我也喜欢这个概念,我喜欢新鲜的东西(可以说相当的井底之蛙了)。所以尝试安装: 首先是仓库的选择,两种,核心在4之上可以用overlay2,也比较推荐用这个,特别是16.04及以上版本已经默认是包含了overlay2了...

金融业预警| 黑客如何大摇大摆把钱从银行划出去?

   某年某月某日,几名蒙面大汉冲进一家银行,一声枪声响起。其中,一名劫匪对银行柜员大喊:“把所有钱都交出来!” 银行工作人员一副生无可恋的表情:“先生,不好意思,所有的钱刚才被一个黑客转走了。” 这可以是一个故事,也可能是现实。 今年2月,第一个利用SWIFT(环球银行金融电信协会)系统进行网络金融盗窃的攻击事件被发现,攻击者成...

问答精选

Homepage Slow to Load

When I go to the homepage of my website after clearing my cache and history, it oftentimes takes up to 10 s to load, but it is sporadic. Sometimes it loads quickly; other times it does not. Because we...

Syntax on Preg_match

I'm swapping a program out that is several years old, and updating the PHP, and MySQL deprication, and am getting jammed up on syntax for preg_match versus ereg. I tried putting slashes everywhere, an...

Windows batch file to check for a directory before application launch

How can I check if an NTFS drive exists before launching an application. If it's not present I'd like to display an error message. This is what I've got, but I'm no good at scripting. itunes.bat Messa...

Oracle REGEXP_SUBSTR will not match the dot character

I'm trying to extract information from strings like: to info like: Currently I'm not able to parse correctly when the module_name part contains . chars. See table below. The example below show how I e...

How to remove multiple spaces and new lines from a string in PHP?

I have a form with a text area, I need to remove from the string entered here eventuals multiple spaces and multiple new lines. I have written this function to remove the multiple spaces This function...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答