Internet Protocol

IP 全称为 Internet Protocol,顾名思义,是工作在网络层的一种协议。既然已经有了 MAC 地址,IP 地址就作为一种给网络赋予层次、方便管理的协议而存在。而网络层次的精髓,在于 IP 的路由与转发。

IP 模块

所有支持 IP 的主机或者路由器,都含有处理 IP 的 IP 模块。

IP 模块的工作有两个,一个是处理来自数据链路层的数据,根据自身是否允许路由以及 IP 数据报是否发给自己来进行路由。另一个是封装上层协议并且发送给下层。而路由过程呢,就是前者,判断外来的 IP 数据报是否应该转发。如果转发模块不允许转发 IP 数据报,并且该 IP 数据报不是发给本机的,则转发模块将会丢弃该 IP 数据报。

另外,当该 IP 数据报设置了源站路由选项,则转发模块也会根据路由选项中的 IP 来判断是丢弃还是转发。

一般来说,路由器多用于转发 IP 数据报,而主机多用于接受 IP 数据报,即转发模块不允许转发。

要实现 IP 的路由,则必须要在每一个主机、路由器中存储一张路由表,这样才会更加快捷、方便地知道该 IP 数据报的下一跳是哪一个主机(路由器)。

路由表

下面是我的电脑的路由表:

看一下这张路由表,第一个是 default,说明这一条记录是默认路由,即该主机所在的网络的网关。如果一个 IP 数据报的目的 IP 地址没有存在这张路由表中,则默认发给 default,由它来转发该 IP 数据报。

下面的几项中,有一些 Gateway 中是 link#4 的。这里不同的主机显示的可能不一样,这个就相当于 * ,这个标志,说明其对应的 IP 与本机在同一个网络内,在数据转发模块接收到来自上层协议且目的 IP 为其中一个时,默认直接发送,而不需要进行路由。

路由表相当于一个路由的缓存,所以需要时长地更新。更新的方式有两种,一种是手动更新,即运行 route 命令;另一种就是自动更新,一般使用的协议是 BGP(Border Gateway Protocol)、RIP(Routing Information Protocol)。

路由与转发

路由就是通过路由表来进行 IP 模块的转发的。

数据包在以太网上传输,有多种可选的结构的,可是不管是什么样的结构,传输都是没有方向性的。那么在同一个网络内,以太网上传输的数据包会经过每一台主机或路由器。当它们确认,接收到的数据包不是发给自己的,就会将其通过 IP 转发子模块转发出去。当源 IP 与目的 IP 在同一个网络内时,上图中Gateway字段为*或者link#4的选项就会告诉主机,可以直接发送给目的地址,而不需要网关。

那么路由器是做什么的呢。路由器也可以被看做成一台主机。在同一网络内,它同样也会转发不属于它的数据包。但是当目的 IP 不在同一网络内时,路由器便会充当连接外部网络和该网络的桥梁。所以当路由为默认路由时,路由器会直接转发数据包而不会做处理。

转发时的目的 IP

其实一直有一个问题,我很困惑,那就是在 IP 报文传输、转发的过程中,源 IP 和目的 IP 是不会因为转发而改变的。那么就会有一个问题:当我们的数据报通过网关在公网中传输时,源 IP 不变,那么目的 IP 在返回的数据报目的 IP 该是什么呢。这么多的局域网,又如何区分呢。

这里,就有一个重要的转换,网络地址转换(Network Address Translation),简称 NAT 。NAT 有两种方式,一种是基本网络地址转换(Basic NAT),另一种是网络地址端口转换(NAPT)。前者要求每一个连接都要对应一个公网 IP 地址,后者则是在路由器转发到公网是,将 IP 地址改写,在路由器内部,使用端口来对应内网源主机。

有了这个,就理解前面的 IP 不变了。使用 NAT 后,我们的数据包经过了路由器的处理之后重新封装了,已经不是原来的 IP 数据报了,而目标 IP 可能也已经变成对方路由器的公网 IP 了。

而在主机和路由器之间,以及路由器和目的主机的路由器之间,无论经过多少跳,多少次转发,都不会改变源 IP 和目的 IP,这样就能理解源 IP 和目的 IP 不会改变了。

IP 重定向

当主机的路由表过期了,发送的数据包发错了怎么办?这就有了 ICMP 包来做重定向,是主机重新发送数据包到正确的 IP ,同时来更新路由表。

当我们的主机在发送数据包后,某一跳的路由发现,其实可以有更好的路线发送数据包,便会在收到数据包后回复一个 ICMP 的包,来告诉上一跳的主机或路由器,重新发送给新的路由,同时丢弃该数据包。这就是 IP 重定向了。

注意:一般来说,主机只能接受 ICMP 重定向报文,而路由器只能发送 ICMP 重定向报文。