有了MAC为什么还需要IP
端到端的网络
如今只有两台主机,他们之间想要通信,我们顺理成章地在两台主机之间接上了一根网线,这样他们就可以通信了。之后又有主机想要加入通信,但似乎也不是问题,只是每个主机都连接两根网线。可随着更多主机的加入,我们发现主机的网口已经被占满了。于是我们需要一个“集线器”,作为主机间的中间设备。每个主机只需要连接“集线器”,主机间的通信可以通过这个设备转发。
交换机
但这并没有完全解决问题,“集线器”做不到原先端到端的定点传输,还只能是广播转发。为了让“集线器”更加智能,我们设计了MAC地址表,MAC地址则是每台主机的唯一标识。在这一设计下,主机发送消息前会在数据包外附加一层带有本机MAC地址(源MAC地址)和目标主机MAC地址(目标MAC地址)的数据。这全部就称之为帧。帧在到达“集线器”后,根据MAC地址表可以找到目标主机连接在哪一端口,从而定向转发。这种具有转发能力的中间设备,我们称为“交换机”。
交换机刚加入网络时,MAC地址表肯定是空的,又是如何逐步建立起来的?以主机A向主机B通信为例,主机A发出的帧在到达交换机时,交换机会在MAC地址表记录下MAC_A到PORT_A的映射,但因为没有主机B的记录,交换机会将该帧广播给所有可用端口。此后主机B接受到帧,比较自身MAC和帧记录的目标MAC,发现自己是目标主机,于是打包好响应帧(源MAC为MAC_B,目标MAC为MAC_A)并返还给交换机。之后交换机收到响应帧,记录MAC_B到PORT_B的映射,然后因为原先有记录便直接把响应帧通过PORT_A转发给主机A,至此,MAC地址表记录下了A、B的信息。对于其他主机C、D等等,当发现自己不是目标主机就会丢弃帧,自然也不会在MAC地址表留下记录。
路由器
可网络继续扩大,直到路由器的物理端口也被占满了呢?再添加一个交换机,交换机间用网线连接,这是一个解决办法,但每个交换机依然要记录网络拓扑中所有主机的MAC地址。如果网络规模发展至千万级别,MAC地址表将不堪重负。
我们注意到,主机A、B、C、D向主机E、F、G、H通信时,数据第一次肯定通过上图的红线转发出去。自然的,A、B、C、D形成了一个网络区域,对于这一网络区域的任何主机而言,向另一网络区域通信时都只需要统一向一个端口转发即可,至于这个端口外面的网络有多大多复杂,我似乎并不需要在意。
这样,网络区域向网络区域的数据转发工作,就由一个新设备“交换机”来承担。交换机存在于不同的网络区域之间,即上图红线处。被交换机划分出的网络区域我们称之为局域网。局域网内的通信可以由交换机完成,否则要先转发给路由器。那么路由器也就需要自己的MAC地址了,作为这个局域网向外通信的默认MAC地址。
值得注意的是,路由器的每一个端口都有独立的MAC地址。这是因为路由器要为每一个连接到的局域网提供默认MAC地址。
局域网怎么知道数据包是否要发往网外呢?理想的方式是通过地址前缀判断,如果数据包的源、目的MAC地址的固定前缀一样,则表明源、目的主机在同一局域网内。
可这种方式仍有很大的局限性:MAC地址是烧录在设备上的,想凑到同一局域网就必须找到同一前缀的设备;此外设备也很难迁移到其他局域网里。
IPv4
为此,我们构造了IPv4,即一个由4组8位二进制数构成,共32位的二进制动态编号,每组以.
相连。比如11000000.10101000.00000000.00000001
,转换成十进制就是我们熟知的IP地址192.168.0.1
。
再套用地址前缀的理念,当我们规定前缀长度为5时,就有11111000.00000000.00000000.00000000
,两主机的IP分别与该IP作与运算的结果如果相同,就说明两主机处于同一局域网,否则两主机的通信就要借助交换机转发。我们称这种特殊IP为子网掩码,路由器的端口IP称为默认网关。
有了IP的加入,主机在帧的外面还要附加一层带有源IP和目标IP的数据,整体称之为段
。
主机在打包数据前,先判断目标主机是否处于同一子网,是则正常把源MAC和目的MAC打包进段中,不是就把目的MAC改为路由器MAC,也就是告诉交换机要把流量转发给路由器处理。
ARP
我们提到过,路由器每个端口都有独立的MAC地址,以便连接各个局域网。但是问题来了,局域网内的主机只有默认网关,即路由器端口的IP地址,可向外通信时填写的路由器MAC,主机是怎么知道的呢?
通过目标IP寻找目标MAC的过程称为ARP,为了知道目标MAC,源主机会广播一条ARP请求,目标主机比对IP后就会回复ARP响应,其中就带有自己的MAC地址。此外,主机内部有一张ARP缓存表
,用于储存目标地址到目标MAC的映射。在这次的ARP过程中,源主机和目标主机就都记录下了各自的IP和MAC。
同样的,目的IP为外网IP时,路由器端口就会回应这次ARP请求,源主机也就知道了路由器端口的MAC地址。
路由表
有了目的IP(外网主机IP)、目的MAC(路由器端口MAC),发送的段也抵达了路由器。那问题来了,路由器怎么知道转发到哪个端口呢?或者说,转发到哪个子网呢?
类似与MAC地址表,路由器的路由表储存着子网到端口的映射,子网也就通过IP和子网掩码来表示。这里了解一个新的表示方法,IP:192.168.0.0,子网掩码:255.255.255.0;简写为192.168.0.0/24。24也就是子网掩码在二进制下的前缀长度。
至于路由表是如何建立起来的,涉及到的路由算法可参考路由算法(全网最细) - 知乎 (zhihu.com)
总结
至此,从两台主机到亿万台主机网络的发展过程已经概述了一遍。主机、交换机和路由器在网络中各司其职就能织成一张巨大的网络。
站在主机视角上:
- 需要知道源IP和目的IP
- 需要知道子网源码和默认网关,用于判断目的IP是否处于同一局域网,以及向外通信时要找谁转发
- ARP缓存没有目的MAC时需要先通过ARP找到
站在交换机视角上:
- 需要知道目的MAC地址,可以不关心源MAC地址
- MAC地址表没有对应记录时,直接广播
- 收到数据包的同时更新或新增MAC地址表项
站在路由器视角上:
- 需要知道目的IP地址
- 查找路由表来转发,没找到就返回路由不可达的响应包
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!