三层网络
一般主机都会配置一个ip地址比如192.168.1.2,如果这台主机要给192.168.1.3的主机发送数据,就会使用ip数据包标记原地址为192.168.1.2,目标地址是192.168.1.3。ip数据包就是三层数据包,它是二层数据包的”载荷”。因此三层网络能通信的前提是二层网络可达,如果二层网络不可达,那么就需要有设备能够连接2个不同的二层网络(比如云的VPC对等连接)
子网 & 子网掩码
通常会看到这样的ip地址写法,192.168.1.2/24,其中/24代表子网掩码24位,也就是子网是192.168.1.x,其原理是将ip地址转化为32位整数,与子网掩码进行按位与
unsigned int32 ip =0x0A000001; //10.0.0.1
unsigned int32 mask = 0xFFFFFF00; // 24位掩码
unsigned int32 subnetNumber = ip & mask; //按位与
subnetNumber == 0x0A000000 // 10.0.0.0
arp地址解析
子网内的计算机之间想要通信只有3层网络地址是不够的,因为3层数据包最终要依靠2层数据包进行发送。arp协议就是用来解析ip和mac(二层地址的对应关系),arp是一个二层广播数据。
上图是我自己的机器,下图是ping同子网的机器(192.168.0.109)的arp数据包
可见同子网arp会直接发包询问,下图是尝试ping 192.168.1.100(跨子网),可见根本不发arp包。意味着ip协议栈认为跨子网通信需要查询的是路由表,而不是发arp包查询到mac后自己直接组织二层包去发
路由表和网关
当跨子网通信时,ip协议栈首先要查路由表,看看这个目标地址应当将包发给谁(通常来说就是网关)
上图就是我自己电脑的路由表,可见默认都是要发给网关(就是家里买的路由器),在arp记录中,网关的ip和mac的对应关系为: 192.168.0.1: 7c-b5-9b-2c-a9-55
刷新个网页看看发的包
可见二层网络的目标mac就是网关(家里买的路由器),三层网络目标是网站的地址,数据到了网关后,网关自然根据自己的路由表规则再把数据扔给联通,联通的路由器再逐个转发最终到了目标地址
总结
总结一下,跨子网arp不发包,因此不可能得到跨子网目标主机的mac地址,ip协议栈要求跨子网查路由表,根据查表的结果,将二层网络地址写成路由表的下一条的ip对应的arp记录mac地址后发包(三层源和目标保持正确)