这片文章不是从内核的角度来分析数据包的处理流程,所以,对于想要从内核了解的人会失望了,本文的目的等同于基础知识的普及,能够让大家对网络书上的知识有一个现实的认识。
主机在发送数据包的时候,是从协议栈的上层到下层依次封装数据包(网络基础知识可以参看这本书<<TCP/IP详解 卷一:协议>>)。现在,以一个ICMP数据包的发送过程为例来讲解,在Packet Tracer中模拟ICMP通信,网络结构图如下所示:
其中PC0的配置如下:
IP: 192.168.100.2
NETMASK: 255.255.255.0
GATEWAY: 192.168.100.1
其中PC0的配置如下:
IP: 192.168.100.3
NETMASK: 255.255.255.0
GATEWAY: 192.168.100.1现在PC0发起一次ping请求,ping 192.168.100.3,通过Packet Tacer,我们查看数据的处理流程:
ICMP不属于TCP和UDP,它是直接封装在IP数据包中的,因此,可以大致算成网络的第三层(layer 3),其实ping程序应该算作应用层的应用程序。在第三层有如下处理过程:
(1) ping应用程序构造一个ICMP请求数据包,包括ICMP头和对应的数据。
(2) ping进程将数据包发送给下层处理程序,下层处理程序会根据目的IP来查找路由表,决定是从哪个网口转发数据包,同时,如果用户没有指定源ip,
处理程序就会使用对应网口的ip作为源IP。
(3) 查找路由表之后,就会知道目的ip是否与源ip在同一个网段,如果是在同一网段,目的MAC就使用目的IP的MAC作为目的MAC,如果不在同一网段,
就会使用默认网关的MAC作为目的MAC。
在windows下,路由表的结构如下:
命令:route PRINT
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 192.168.100.1 192.168.100.72 276
127.0.0.0 255.0.0.0 在链路上 127.0.0.1 306
127.0.0.1 255.255.255.255 在链路上 127.0.0.1 306
127.255.255.255 255.255.255.255 在链路上 127.0.0.1 306
169.254.0.0 255.255.0.0 在链路上 169.254.90.209 276
169.254.90.209 255.255.255.255 在链路上 169.254.90.209 276
169.254.255.255 255.255.255.255 在链路上 169.254.90.209 276
192.168.100.0 255.255.255.0 在链路上 192.168.100.72 276
192.168.100.72 255.255.255.255 在链路上 192.168.100.72 276
192.168.100.255 255.255.255.255 在链路上 192.168.100.72 276
224.0.0.0 240.0.0.0 在链路上 127.0.0.1 306
224.0.0.0 240.0.0.0 在链路上 169.254.90.209 276
224.0.0.0 240.0.0.0 在链路上 192.168.100.72 276
255.255.255.255 255.255.255.255 在链路上 127.0.0.1 306
255.255.255.255 255.255.255.255 在链路上 169.254.90.209 276
255.255.255.255 255.255.255.255 在链路上 192.168.100.72 276
===========================================================================
永久路由:
网络地址 网络掩码 网关地址 跃点数
0.0.0.0 0.0.0.0 192.168.100.1 默认
在Linux下,路由表的结构如下:
命令:route -A inet (IPv4) route -A inet6 (IPv4)
或者 ip -f inet route (IPv4) ip -f inet6 route (IPv6)
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
192.168.30.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth2
0.0.0.0 192.168.100.1 0.0.0.0 UG 0 0 0 eth2
windows的路由表是从下往上查找,而Linux的路由表是从上往下查找,最后都到默认网关。
第三层处理完毕后,数据包转到第二层,第二层的处理如下:
在第二层(数据链路层),需要构造数据包的目的MAC,这个过程由ARP处理程序来完成,它会先查找ARP表,看是否有对应的IP-MAC对,有的话,将对应IP的MAC填入数据包目的MAC头中,然后直接发送。如果没有,就暂时将上层ICMP数据包缓存,然后ARP程序向全网发送ARP请求包,来得到IP对应的MAC,这里的IP只会是网关或局域网其他机器的IP,也因此,导致了ARP的广播只会在一个局域网内进行。如果在规定的时间内,ARP响应包还没回来,那么ICMP就会因超时而发送失败。
在windows下,ARP表的结构如下:
命令:arp -a
接口: 192.168.100.72 --- 0xb
Internet 地址 物理地址 类型
125.223.113.5 00-0f-e2-19-78-a9 动态
192.168.100.1 00-0f-e2-19-78-a9 静态
192.168.100.8 08-57-00-24-09-bb 动态
192.168.100.21 b0-83-fe-55-e6-b8 动态
192.168.100.23 74-27-ea-1a-35-87 动态
192.168.100.29 b0-83-fe-55-36-be 动态
192.168.100.35 b0-83-fe-56-14-2e 动态
192.168.100.54 74-27-ea-1a-44-ed 动态
在Linux下,ARP表的结构如下:
命令:arp -a
? (192.168.100.72) at 00:23:24:44:72:1f [ether] on eth0
? (192.168.100.63) at 74:27:ea:1a:3d:40 [ether] on eth0
同样,在路由器中也有路由表和ARP表,从数据处理过程来说,一台主机和路由器的功能是相似的。
得到了ARP响应后,主机将对应的IP-MAC存入arp表中,下次再发送数据,就可以直接从表中去MAC,不需要再发送arp请求了。利用这一特性,可以实现ARP攻击,见我的另一篇博文Linux网络环境下的ARP攻击 。
至此,数据处理流程叙述完成,如果有错误的地方,还请大家指出,批评建议都很欢迎。