网络层简介
1. 概念
为解决经由多条链路的交付问题,从而设计了网络层。其主要负责主机到主机的交付,并且在分组经过路由器时负责为其选择路由。
实际中,互联网中的设备间的连线错综复杂,如何从A到B会经过很多链路,在这个模型中路由器担当交换机的作用,当一个分组从a端口到达该路由器后,会通过另一个端口b转发到另一个交换机或终点设备上。这个处理过程称为交换(switching)。
2. 交换
那要如何实现交换?
方法一,电路交换。即在报文传递前从源点到终点建立一条物理电路,这种技术在物理层使用,而不在网络层使用。
方法二,分组交换(packet switching)。实际中网络层使用的技术,报文的源点逐个发送被分割成一个个分组(datagram数据报)的报文,然后终点逐个接收,全部到齐后,再由终点的网络层交给上层。在分组交换网中,选择路由的方式有两种:数据报方式和虚电路方式。
3. 分组交换
3.1 无连接
开始时,网络层被设计为无连接服务(connectionless service),同一个报文的分组间没有关系,从A到B的路径可能不同,即路由可能不同,顾到达B时顺序可能会变,还可能会有部分分组丢失。
当一个分组来到路由器时,路由器会读取该分组的目的地址,然后查询自己的路由表,找到输出端口,完成分组交换操作。若该报文需要被丢弃时,读取该分组的源地址,同样根据路由表,向源地址发送差错消息。
所以在无连接分组交换网中,转发判决的依据是该分组的目的地址。
3.2 面向连接
而在面向连接的服务中,同一报文中的所有分组间是有关联的。在一个报文的所有数据报在发送前,需要建立一条虚连接。此时分组除要包含源和目的地址外,还需要有一个流标号(flow label),就是一个虚电路标识符(virtual circuit identifier),用来制定这些分组应当使用的虚路径。
建立面向连接的服务的三个步骤:建链、数据传输、拆链。
建链阶段,源点和终点间需要交换两个分组:请求分组和确认分组。请求分组从源点到终点,携带源地址和目的地址。当一个请求分组来到一个路由器时,路由器可以填写入端口、入标号和出端口,其中入标号是路由器自主分配的。
最终请求分组来到终点,终点给分配一个标号后,发送确认分组。当确认分组来到一个路由器后,路由器可以根据目的地址和源地址确认原先已经填写部分的一条路由表项,并将它补齐出标号。最后一个路由器将确认分组发给源点并附上入端口,这个入端口就是一开始在建链阶段生成的。
此时源点知道了该用哪个标号发,终点知道了从哪个标号来的,中间链路中的路由器知道了当某一个标号来时,该如何进行转发操作。此时建链阶段就结束了。
数据传输阶段,某一分组来到一个路由器后,路由器根据标号选择出端口,并将标号由入标号改为出标号,再进行转发。
拆链阶段,由源点向终点发送拆链分组,终点向源点发送证实分组,依然是一个Request后Response的设计。
目前来说,无连接服务依然占主要地位。
4. 网络层各部分提供的服务
在源点,网络层提供四种服务:分组化处理、查找下一跳的逻辑地址(IP)、查找下一跳的物理地址(MAC)、对数据报进行必要的分片处理。
首先将从上层得到的报文进行分组化处理,即增加报头,填入一些数据,包括源地址,而目的地址由上层给出。
然后根据生成的数据报中的目的逻辑地址,通过路由表来选择下一跳的逻辑地址,然后使用ARP(地址解析)协议在表中查找下一跳的逻辑地址和物理地址之间的映射关系。
最后由于不同的数据链路层对于帧的长度有不同的要求,需要查找MTU(最大传送单元)表来确定需要分割数据报。如果有分片操作,则需要将每一个分片前都增加首部,还需要在首部中填入数据以指明该数据片在整个数据报中的位置。
在路由器上,网络层提供四种服务:检查数据报的有效性、查找下一跳的逻辑地址、查找下一跳的物理地址、分片处理。有效性指的是首部有没有损坏,是否被交给正确的路由器。由于转发设计两个端口,所以两个端口对应的数据链路层可能不同,所以需要查询MTU表确认是否需要分片。
在终点,网络层提供服务:检查有效性、拆包、重装。检查有效性后要将报文头部去掉从而取出有效数据,当所有的数据报文都到齐后,进行重装再交给上层。若重组定时器超时,则所有数据包会被销毁,并发送一个差错报文,以提醒源点需要重发。
5. 不完全的实现
有些服务在网络层只是部分实现,或者没有实现。有些服务是由一些辅助协议来提供,或者通过其他之后加入的协议实现。
差错控制(error control)包括对损坏、丢失以及重复的数据报进行检测的机制,以及检测后的纠错机制。网络层没有提供真正意义上的此机制。由于网络层有分片,如果有差错控制会比较低效。在网络层报文的报头中有校验和字段,不过只是针对报头设计的,由于报头在每个路由器上都会有数据变化,所以校验和也需要重新计算。辅助协议是ICMP。
流量控制(flow control)用于调整源点发送的数据量以免接收方超载。当前网络层没有考虑此功能。
拥塞控制(congestion control)是避免有过多的数据报出现在因特网中的某一个区域内,此时某些路由器可能会丢弃一些数据报。丢失后需要重传,结果变成滚雪球,越来越拥塞,最终系统崩溃。
在无连接网络中,路由器会选择那些造成拥塞的方向,在反方向的报文中设置一个bit作为拥塞警告,以通知源点放慢速度。ICMP同样有拥塞控制的功能,当有拥塞发生时,路由器会发一个特殊的扼流分组(choke packet)给源点。还有一种方法是给分组设定优先级。
在面向连接网络中,拥塞控制较简单。可以通过建立一条额外的虚电路分压。另一种方法是在建链阶段提前协商,有需要建立虚电路的路由器根据自己现有的通信量和自己能承受的最大通信量比较,从而决定是否可以建立虚电路,以及虚电路的通信量的最大值。
服务质量(quality of service,QoS),主要针对对质量有高要求的多媒体通信。大多在上层实现。
路由选择(routing)。由路由选择协议完成,帮助主机和路由器建立自己的路由表,并维护和更新这些表。可划分为两类:单播和多播的。
安全性。为了在无连接的网络层提供安全性,需要用另外一些虚拟层来把无连接服务转变为面向连接的服务,这个虚拟层称为IPSec。
IPv4地址
IPv4地址指的是version=4的IP协议所定义的逻辑地址,共32bit,它唯一地且全球地定义了一台主机或路由器与因特网之间的一个连接。唯一性表现在每个地址只能定义一个到因特网的连接,若设备有两个连接,就需要有两个地址。全球性表现在任何要连接到互联网的主机都必须采用的地址系统。地址空间为2^32。
1. IP地址的记法
二进制记法(基2):10000000 00001011 00000011 00011111,IPv4地址的本来面目。
十进制记法(基256):128.11.3.31,常用方式。
十六进制记法(基16):0x800B031F,常用于网络编程。
若需要计算某段的地址数,可按照不同的计数法来进行加减。
2. 分类编址
2.1 分类
IP地址空间分为5类:ABCDE。
A类共2^31个地址,占50%。
B类共2^30个地址,占25%。
C类共2^29个地址,占12.5%。
D类共2^29个地址,占6.25%。
E类共2^29个地址,占6.25%。
比例就是:8:4:2:1:1。
按照二进制记法时,第一位是0表示A类;否则判断第二位是否是0,是表示B类;否则判断第三位是否是0,是表示C类;否则判断第四位是否是0,是表示D类,否表示E类。
按照十进制记法时,对于第一个字节,A类是0127;B是128191;C是192223;D是224239;E是240~255。
当然某些特殊地址落入了A和E,是例外情况。
个人认为二进制记法更直观更好记。
对于ABC三类,IP地址可划分为网络标识(net-id)和主机标识(host-id)。
A类:第1个字节是网络标识,后3个是主机标识。
B类:前2个字节是网络标识,后2个是主机标识。
C类:前3个字节是网络标识,后1个是主机标识。
2.2 地址类和地址块
分类编址的一个问题是每类地址都被划分为固定数目的地址块,每个地址块的大小是固定的,不灵活。
A类网络标识是第1个字节,且第一位必为0,所以只有7bit可以定义网络标识,27=128理想情况可以指派给128个机构组织使用。每个地址块包含224个地址,也就是可以分成这么多的主机标识。
同理,B类有16-2=14bit表示网络标识,214=16384。每类地址包含216=65536个主机标识。
C类有24-3=21bit表示网络标识,每类地址块有2^8=256个主机标识。
AB被浪费,C不够用。
D类只有一个地址块,用来进行多播。用以定义一组主机,若某个组被指派了一个D类地址,则该组的每一个主机都会在正常地址(单播地址)的基础上增加一个多播地址。
E类只有一个地址块,是保留地址。
2.3 两级编址
如前所述,分类编址中指派给一个组织的是一个地址段,有ABC类三种。对于同一个网络内的所有主机而言,都应该是属于同一个地址段的,它们之间用主机标识表明身份。若网络地址为n位,则主机地址为32-n位,n的值根据所属ABC类来取值8,16,24。这就是两级编址,电话号码分区号+本地号也是同样道理。
一个地址块有三要素:地址数、首地址和末地址。首先需要判断是属于哪一类,从而得知n和32-n,也就可以算出地址数=2^(32-n)。首地址就是后面32-n位全为0,末地址就是全为1。
首地址被称为网络地址,不会指派给任何主机,而是用来代表这个网络。比如200.11.8.45这个地址是C类,则n=24,所以它的网络地址是200.11.8.0/24,斜杠后面是n值。
2.4 一个应用
由于网络地址是一个网络地址块的标识,所以它可以被用来为分组选择路由。当某个分组来到路由器后,路由器根据目的地址计算得到目的地址的网络地址,然后查找路由表,找到对应该网络地址的端口,然后将该分组进行转发。
常用的算法是使用网络掩码(network mask)。这是一个32bit的数,前n位是1,后32-n是0。ABC各对应一个掩码。路由器根据目的地址的类别来选择一个掩码与目的地址进行按位与运算,从而得到网络地址。
2.5 三级编址:子网划分
对于AB两类,地址块太大,所以拥有这两类的组织可以将地址块划分成多个较小的子地址块,并与其他组织进行共享。这种思想称为子网划分,每个被划分的子网都有对应的子网地址。这样地址就分成了网络地址、子网地址、主机地址三级,类似的电话号码可分为国家码、地区码、用户码。
之前提到的网络掩码是针对网络地址的,当有子网划分时,对于子网也需要有一个网络掩码。子网由子网标识和主机标识两部分组成,子网标识增加了网络标识的长度,也同时减少了主机标识的长度。当一个网络划分成s个子网且每个子网的主机数相同时,每个子网标识计算公式如下,s必须是2的乘方。log2s计算的是上图“变化”的bit位数。
路由器此时会根据子网标识来选择对应的端口,从而到达子网。同样是使用掩码进行与运算。
2.6 超网
然而对于C网来说,问题是地址块内的地址数太少,需要将多个C类地址块合并成一个大的地址段。
所以超网掩码和子网掩码正好相反,若要将c个地址块合并,则需要n-log2c来得到超网掩码。
但这样的话会带来两个新问题:由于c必须是2的乘方,超网构造时会有冗余。同时对于路由选择来说变得复杂了。
3. 无分类编址
子网和超网的构造并没有从实际上解决地址耗尽的问题,利用效率也不高,还使得地址分配和路由选择变得更加困难。最终的解决办法是使用更大容量的地址空间,即新的版本IPv6。临时的解决方案是改变地址的分配方法,称为无分类编址,也就是说类别取消了。地址块变成了可变长度的。
3.1 两级编址
与分类编址中的思想相同,地址被分为网络地址和主机地址,也称前缀和后缀。前缀的长度n取决于地址块的大小,取值范围是0~32。n称为前缀长度,32-n称为后缀长度。
在分类编址中,若给定一个地址,可得知它属于哪类从而得知它的网络地址。但是在无分类编址中,仅凭一个地址是无法确定前缀的,需要增加一个前缀长度n,放在地址后面,用斜线隔开它们,称为斜线记法,正式名称是无分类域间路由选择(classless interdomain routing)或CIDR记法。由此也可以得到对应的掩码是多少。
某个地址块内的地址数同样是2^(32-n)。而首地址则是这个地址块内的任意地址与掩码的按位与的结果。
举例110.23.120.14/20,求这个地址块的三要素:首地址、末地址、地址数。地址数=2^(32-20)=4096。因为20>16&&20<24,所以前两个字节保持不变,第四个字节归0,主要是求第三个字节。120的2进制表示是0111 1000,前缀长度是20,所以在第三个字节中,只有前四个bit是属于前缀的,后面的都要归0,所以就可以得知首地址是110.23.112.0/20,而末地址就是后面全置1,是110.23.127.255。
3.2 地址块的分配
分配地址块三原则:
1.申请的地址数N必须是2的乘方。主要是为了使前缀长度n是一个整数。
2.对于一个地址块来说,根据地址数就可以求出前缀长度的值。其中1和2是互相牵制的。
3.必须是地址空间中连续的未分配地址才能被分配给申请的地址块。同时选择的起始地址必须能够被地址块的地址数整除。如果不能整除,根据1和2的约束,可以推测出若使用该起始地址,地址块内的地址数一定小于申请的地址数。
分类编址是无分类编址的一个特例,如ABC类的前缀长度分别是8,16,24,可以直接转换成无分类编址。
3.3 子网划分
与分类编址中的子网划分类似。
子网设计的三原则:
1.每个子网络的地址数应当是2的乘方。
2.每个子网络的前缀长度应当是如下所示,其中N是总地址数,Nsub是每个子网的地址数,n是原先的前缀长度:
3.每个子网络的起始地址应当能够被它的地址数整除。遵循这一原则,需要首先为大的子网络指派地址。
举例起始地址是14.24.74.0/24的地址块,需要分配三个地址块,地址数分别是120,60,10。
首先该地址块共有2^(32-24)=256个地址,首地址是14.24.74.0/24,末地址是14.24.74.255。
然后按照各子网的地址数从大到小分配。第一个子网需要120个地址,不是2的乘方,增加到128,是2的7次方,可知该子网的前缀长度是24+1=25,其实也可以用32-7=25算出。首地址是14.24.74.0/25,末地址是14.24.74.127/25。
然后是第二个子网需要60个,补齐到64,是2的6次方,前缀是32-6=26。首地址是14.24.74.128/26,末地址是14.24.74.191/26。
最后是第三个子网需要10个,补齐到16,是2的4次方,前缀是32-4=28。首地址是14.24.74.192/28,末地址是14.24.74.207/28。
4. 特殊地址
分类编址中某些地址被用作特殊用途,无分类编址继承了部分策略。
全0地址,0.0.0.0/32。被保留用于某主机不知道自己的IPv4地址,但需要发送一个IPv4分组时。通常是用在主机正在启动的时候。此时主机为了得到IPv4地址,向DHCP服务器发送一个IPv4分组,并用全0地址作为源地址,二用受限广播地址作为目的地址。
全1地址:受限广播地址,255.255.255.255/32。被保留用作当前网络的受限广播地址。一个主机想要将报文发送给网络中的所有主机,可使用此地址作为IPv4分组中的目的地址,但是路由器会将此类地址的分组忽略,这样广播只局限在本地网络中。
环回地址,127.0.0.0/8,用作测试机器的软件。使用时,分组不会离开机器,只是简单地由协议软件返回。此地址只能用作目的地址。如ping程序可以使用此地址测试IPv4软件是否接受和处理分组。客户进程可以用此进程给本机上的服务进程发送一个报文。
专用地址,这些地址不会在全球被识别。要么用于隔绝其他网络的情况下,要么就用于具有网络地址转换技术的连接(NAT)。包括10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16。
多播地址,224.0.0.0/4。
此外每个地址块中有些地址有着特殊用途的,但是此机制只是推荐不作强制使用。如地址块的首地址定义为网络地址。如地址块的末地址可用作直接广播地址,路由器会用这个地址发送给某个特定网络上的所有主机,此地址只能作目的地址。
5. NAT
又有新问题:分配的地址段定死了,若某用户需要增加地址,则之前分配给他的地址段的前后均已使用,无法扩容。但是在一个小型网络中,绝大多数时间只有一部分计算机需要同时接入因特网,也就是说,分配的地址数可以小于网络中的计算机数。
在网络内部,可以使用专用地址来进行内部通信,然后全球通信使用分配的地址。
网络地址转换(network address translation,NAT)可用于提供在专用地址和全球地址间的转换,同时也支持虚拟专用网络。一般网络通过一个具有NAT软件的路由器与全球网络连接。当外出的分组通过此路由器时,源地址被换成全球NAT地址,当进入的分组通过此路由器时,目的地址被换成相应的内部专用地址。
NAT路由器使用转换表来解决地址转换对应问题。
简单的方法,一个专用地址映射一个全球地址,当发送时将专用地址替换成全球地址,并记录在表中;当接受时根据表内记录,将全球地址替换成专用地址。但是有问题:通信必须总是由专用网络发起,不能运行服务器程序来为网络之外的客户端提供服务;一台主机不能同时访问两个外部服务器程序;两台主机也不能同时访问一个相同的外部服务器程序。
为了允许多对多的映射关系,需要在转换表中增加更多内容,此时表内有五部分:专用地址,专用端口,外部地址,外部端口,传输层协议。增加专用端口用以更好的区分,那么同时使用的专用端口就不可以相同,必须是唯一的。
IP分组的交付和转发
交付指的是在网络层的控制下,底层各网络对分组的处理方式,包括直接交付和间接交付。转发指的是把分组交付到下一站的方式,包括基于分组目的地址的转发和基于附加在分组上的标记的转发。
1. 交付
直接交付:分组的重点是一台与交付者连接在同一网络上的主机。通常发生在源点和终点属于同一物理网络,或者最后一个路由器与目的主机之间。
发送通过提取终点的网络地址(用掩码),然后与自己所连接的网络的地址比较,若匹配则是直接交付。此时,发送方可直接通过目的IP地址找出对应的MAC地址,然后网络层将IP和MAC地址都交给数据链路层,完成实际交付。IP和MAC地址间的映射通常由ARP实现。
间接交付:源点和终点不在同一网络上。间接交付原理上是多个直接交付。发送方使用目的IP地址和路由表来查找下一跳路由的IP地址,同样是使用ARP找到对应的MAC地址,然后进行交付。这样一步一步,到达终点。
2. 转发
2.1 基于目的地址的转发
这是一种传统方式+当前主流,适用于无连接的协议,此时转发的基础是IP数据报的目的地址。路由器主要通过路由表来判断如何转发。路由表有多种构造方法。
基于路由的路由表:分组由A到B,需要将经过的所有结点均写入路由表。
下一跳方法:路由表中只保存下一跳的地址,而不是保留完整路由的信息。
特定网络方法:另一种简化查找过程的方法,此时路由表不是对连接在同一个物理网络上的每一台主机都设置一个表项,而是只用一个表项来定义目的网络本身的地址。
特定主机方法:正好与特定网络方法相反,目的主机的地址在路由表内都要给出。这样可以给特定的目的主机指定路由,主要用在像检查路由或提供安全措施这样的特殊情况下。
默认方法:A连接的网络上有两个路由器R1和R2,其中经过R1可到到B,经过R2可到达网络其余部分。此时主机A的路由表就不需要把整个网络都罗列出来,而是除去到达B之外,其余路由均用一个成为默认的表项来表示,通常定义网络地址为0.0.0.0。
2.1.1 使用分类编址时的转发
2.1.1.1 无子网划分的转发
使用分类编址时,全球互联网中绝大多数路由器都没有涉及子网划分。子网划分是在一个组织内部进行的。此时一个典型的转发模块对于每种单播类型(ABC)各对应一张表,若有多播,则需要一张对应处理D类的表。
每张路由表的三要素:
1.目的网络的网络地址,此时使用的是特定网络转发。
2.下一跳地址,间接交付时告诉分组应当交付到的路由器,直接交付时为空。
3.接口号,定义分组应当从哪个输出卡发送出去。
所以最简单的场景如下。从分组中提取目的IP地址,判断类别(ABC,若DE则走另外流程),从而得到网络地址,然后到找到对应类别的路由表,找到网络地址相对应的下一跳IP地址和接口号,再通过ARP协议找到下一跳IP地址映射的MAC地址。如果没有找到对应的下一跳IP地址,则使用默认的。
2.1.1.2 有子网划分的转发
处理子网划分的路由器不是在该组织站点的边界上,就是在站点边界的里面。如果使用了可变长度的子网划分,则需要多张路由表,否则只需要一张。
最简单的场景如下。从分组中提取目的IP地址,并同子网掩码(子网划分是不可变长度的,所以子网掩码是固定的)进行按位与运算,得到子网地址,在路由表中查找,得到下一跳地址和接口号,然后通过ARP找到下一跳的MAC地址。找不到下一跳地址的则使用默认的表项。
2.1.2 使用无分类编址时的转发
无分类编址时,地址空间是完整的,没有划分类别。所以为了找到目的地址的网络地址,需要在路由表中包含掩码(/n),所以无分类编址的路由表至少有四列。
应用时,从上到下依次取每个表项的掩码,去和目的地址做按位与运算,若和网络地址相符合,就可得到下一跳地址和接口。找不到符合的则使用默认的表项。
如果路由表的规模过大,可能会造成搜索时间过长。
一种方法是将临近的几个地址块聚合成一个大的地址块,由R1来区分具体是哪个地址块,而与R1链接的R2则只在路由表中记录到这个大的地址块的网络地址就可以了。这种方法称为地址聚合。
另一个需要注意的原则是最长掩码匹配,此原则指出路由表要按照从最长掩码到最短掩码来排序,如/27,/26,/25。相当于是先精确匹配,再模糊匹配。当然这样搜索还是在列表中按序搜索,如果想要减少查找时间,一种解决办法是改变查找的数据结构,不使用列表而是诸如树或二叉树之类。
还有一种方法是多级路由选择,在路由表中建立分等级概念。类似于分类编址中的有子网划分的算法,不过此时等级的划分是无限制的。
还有就是可以依据地理上的分布来进行表项的聚合。
2.2 基于标记的转发
比基于目的地址的转发简单,路由表中只需记录接口和下一个标记。当一个分组到达一个路由器时,根据携带的标记,在路由表中按此标记进行索引,直接可得到接口和下一个标记。
IPv4分组格式
IP是一种不可靠的无连接数据报协议。如果可靠性很重要,需要结合可靠的协议如TCP配合使用。
1. 数据报
网络层的分组称为数据报datagram。IPv4数据报格式如图。首部的长度是20~60byte,包含有关路由选择和交付的信息。习惯上,在TCP/IP中都是以4byte为一段来表示首部。
版本(VER):共4bit。目前版本是4,将来可能会可以使用6。IP软件根据这个字段来判断该数据报是否和自己的版本相同。
首部长度(HLEN):共4bit。单位是4byte,因为首部长度是2060byte,所以该字段的取值是512。
服务类型:共8bit。指明了该如何处理数据报。之前定义了数据报的优先级和服务类型。
新的解释是,定义了一组区分服务,前6bit是码点子字段,后2bit保留。
当最右边的3位是0时,最左边3位定义为优先级(与原来兼容),此优先级定义了在出现一些问题(如拥塞)时数据报的优先级。
当最右边的3位非全0时,6bit定义了56 (64-8)种服务。类别1,码点是XXXXX0,是由因特网管理机构(IETF)指派的优先级,共24种。类别2,码点是XXXX11,由本地管理机构指派的优先级,16种。类别3,码点是XXXX01,临时或试验的指派,16种。
总长度: 共16bit。单位是byte,定义数据报报头+数据的总长度。可推断,IP数据报的长度范围是2^16-1=65535byte,其中还包括20~60byte的首部。如果物理网络不能把数据报封装成帧,则需要分片操作。
某些时候,封装在数据报中除了首部、数据外,还有一些填充,如以太网协议对帧的范围有46~1500byte的要求,所以用此字段可以识别出哪些是数据,哪些是填充。
标识:16bit。
标志:3bit。
分片偏移:13bit。以上三类用于分片,详见下一节。
生存时间:8bit。数据报不可以一直在网络中传输,否则会造成浪费。之前的设计是一个时间戳,经过路由器进行递减,然而所有路由器不可能进行时钟同步,总的耗费时间也不好估计。
当前此字段设置成数据报所经过的最大跳数(路由器),数值大约是任意两台主机间的最大路由器数的2倍,没经过一个路由器要减一。当为0时,路由器要抛弃该数据报。
另一个用途是源点限制分组的转发范围,如设置成1则该分组只能在局域网中转发。到达第一个路由器时就会变为0被抛弃。
协议:8bit。定义了此IP层服务的高层协议,指明了此分组必须交付给哪个最终目的协议。1代表ICMP,2代表IGMP,6代表TCP,17代表UDP,89代表OSPF。
首部校验和:16bit。
源地址:32bit。此字段始终不变。
目的地址:32bit。此字段始终不变。
选项+填充:0~40byte。首部此时共有20byte,若某首部的长度大于20byte,则说明后续有该字段。
2. 分片
路由器会从收到的帧中拆解出IP报文,然后再封装成另一个帧发送。接受帧的格式与长度与经过的物理网络使用的协议有关,发送帧的格式与长度与将要经过的物理网络使用的协议有关。
不管是什么物理网络,一定会对经过帧的最大长度做出限制,出去帧的首部和尾部,剩下的对于IP报文的限制来说,称为MTU。如以太网局域网的这个值是1500byte。
由于IP数据报的最大长度为65535byte,若物理网络的MTU比此值小,则需要对数据报进行分片(fragmentation)。
源点通常不会分片,因为在传输层已经把数据划分成IP和源点使用的数据链路层可接纳的大小。分片后首部大部分相同,有些字段会变化。若已分片的数据报遇到更小MTU的网络,还会再进行分片。
分片可以在源点或途中的路由器中进行,但重装只能在墓地主机上进行。一方面现阶段IP是无连接的,各分组路由不同,中途无法重装。另一方面若要做的话会降低效率。
分片时,首部的必要部分必须复制到所有分片,选项字段可以选择不复制。标志、分片偏移、总长度需要改变。校验和需要重新计算。也就是说,只有数据报中的数据是分片的。
三个分片相关字段:
标识(identification):16bit。此标识和源IP地址必须唯一确定数据报。IP协议使用计数器来生成标识。数据报分片时,该字段要复制到所有分片中。故所有分片均有相同的标识,也是原始的数据报的标识号。在终点时用于重装数据报。
标识(flag):3bit。
第1bit保留。
第2bit称为“不分片”位,为1则机器不可对该数据报分片。若无法通过任何物理网络发送该数据报,则需要丢弃,并向源点发送ICMP差错报文。为0说明可分片。
第3bit是“还有分片”位,为1表示这个数据报不是最后的分片,为1表示是最后的分片或者是唯一分片,用于重装时的判断。
分片偏移:13bit。表示分片在整个数据报中的相对位置,并且是按照原始数据的偏移量,单位是8byte。以8byte为单位也迫使数据报没进行一次分片,第一个分片的字节数量一定能够被8除尽。
当二次分片时,分片偏移也是永远相对于原始数据的。
在终点进行重装的算法如下:
0.依据标识来讲分片归类。
1.依据第一个分片的分片偏移字段值为0来选出第一个分片。
2.把第一个分片的数据长度除以8,就是第二个分片的分片偏移值。
3.把第一个和第二个分片的数据长度除以8,就是第三个分片的分片偏移值。
4.以此类推,直到看到一个分片的“还有分片”位为0,即为最后一个分片。
3. 选项
IP数据报的首部固定部分是20byte,可变部分是0~40byte。选项部分可用于网络的测试和排错。
如图所示,选项的格式是:1byte的类型字段,1byte的长度字段,可变长度的值字段。这三个字段经常被称为TLV(type-length-value)。
类型:8bit,包括三个子字段。
1.复制:1bit。控制选项在分片是否出现,为0则必须且只须复制到第一个分片,为1复制到所有分片。
2.类别:2bit。定义选项的一般用途。00表示用于数据报的控制。10表示用于排错和管理。其余未定义。
3.编号:5bit。定义了选项的类型。目前仅使用了6类。
长度:8bit。定义选项的总长度。可以不出现。
值:包含某些特定选项所需的数据。可以不出现。
6种选项类型中,2种是单字节选项,不需要长度和值字段。其余均需要长度和值字段,是多字节选项。
无操作选项:1byte。用作选项间的填充,以便于对齐。
选项结束选项:1byte。用于选项字段结束的填充,只能作最后一个选项且只能用一次。接收器根据此选项来开始操作净荷数据。也就是说如果对齐选项需要超过1个字节,那么必须先填充一些无操作选项,再在最后加一个选项结束选项。
记录路由选项:记录处理数据报的因特网路由器。可以列出最多9个路由器的IP地址,算法是这样的:数据报选项部分是40byte,刨除类型和长度字段2byte,剩余38byte,而一个IP地址需要4byte,那么最大可填入9个IP地址。
此时在值字段中,需要引入一个指针字段用于表示第一个空项的偏移量,即指向第一个可用的空项。当数据报离开源点时,这些IP地址字段都是空的,指针字段的值为4,指向第一个空字段。在经过路由器时,路由器会比较长度字段和指针字段,若指针字段大于长度值,则选项已满,不做改变。否则,路由器要在当前空字段中填入自己的出口IP地址,然后再把指针字段+4。
严格路由选项:被源点用来预先制定数据报在因特网中传送时的路由。若指定了该选项,则数据报就必须经过在选项中定义的所有路由器。若某路由器IP地址不在表中,则一定不通过该路由器。若通过了,则这个路由器要丢弃该数据报并发送差错报文。若数据报到达终点时有些IP地址未经过,依然丢弃并发送差错报文。
此时在值字段中,依然有一个指针字段,区别在于此种情况下所有的IP地址在源点时就已经填好。路由器比较指针值和长度值时,若指针值大,则数据报已通过了所有预设的路由器,不可再转发,必须丢弃并发送差错报文。若指针值小,则路由器比较该帧(数据链路层)的目的IP地址是否与自己的入口IP地址一致,相等则进行操作并用该帧的目的IP地址来替换指针所指向的IP地址,还要将指针值+4,并且指针指向的IP地址作为下一次转发的目的IP地址。不相等就丢弃并发送差错报文。
不严格路由选项:条件放宽为,表中列出的路由器必须经过,但数据报还可以访问其他的路由器。
时间戳选项:用来记录路由器处理数据报的时间。时间是从午夜开始以毫秒计时的全球通用时间。有助于用户和管理者对因特网上的各路由器的行为进行跟踪。能够估计数据报从一个路由器到另一个路由器所需时间,估计是因为时钟可能不同步。
除了要有指针字段外,还需要4bit溢出字段,4bit标志字段。溢出字段用来记录因缺少可用字段而无法增加时间戳的路由器数量。标志字段为0,则只记录时间戳。若为1,则需要增加出口IP地址和时间戳。若为3,则IP地址是预先给出的,路由器需要用自己的入口IP地址来检查给定的IP地址,匹配的话要用出口IP地址来覆盖该地址。
4. 检验和
二进制反码加法:用n位来表示从0~2^n-1之间的无符号整数,如果一个数多于n位,则多余的最左边的位被驾到最右边的位上(绕回)。
在发送端,把分组划分为k段,每段的长度都是n位。用二进制反码加法把这些段相加。把最终结果去反码就得出校验和。
在IP分组中,针对分组首部进行计算,n=16,首先把校验和字段置0,计算出结果后再更改。
在接收端,把分组划分为k段,每段的长度都是n位。用二进制反码加法把这些段相加,然后再取反码,若结果为0,则接受此分组,否则拒绝。
安全性
有三个安全问题是特别应用于IP协议的:
分组窃取:被动攻击,入侵者截取并复制一个IP分组。难以检测,但若对分组进行加密则可令攻击者无功而返。
分组篡改:攻击者先截取,再改变其中内容,最后发送给接收方。可以被数据完整性机制检测。
IP伪装:攻击者伪装成另一个人,创建一个携带另一台计算机的源地址的IP分组。可通过起源鉴别来防范。
使用IPSec协议来保护:
定义算法和密钥。
分组加密:对应分组窃取攻击。
数据完整性:对应分组篡改攻击。
起源鉴别:对应IP伪装攻击。
简化IP软件包
忽略选项的处理,可以简单地认为IP软件包包含了八个组件:首部添加模块、处理模块、转发模块、分片模块、重装模块、路由表、MTU表、重装表。还有一些输入输出队列。
此软件包接受来自高层或数据链路层的分组。若从高层来,则必须将它交付给数据链路层进行传输(除非使用还会地址127.x.y.z)。若来自数据链路层,则或者讲起交付给数据链路层进行转发(在路由器中),或者交付给高层协议(目的地址与本站一致)。
首部添加模块:接受来自高层的数据,把数据封装成为IP数据报,计算校验和,插入对应字段,然后发送到输入队列。
处理模块:核心,接受来自高层或数据链路层的数据报。若目的地址与本地地址相匹配,则发送到重装模块,处理完毕;若本机是路由器,则TTL减一;若TTL小于等于0,则丢弃此分组并发送ICMP差错报文,处理完毕;还未完毕的话,将数据报发送到转发模块,处理完毕。
队列:输入队列指的是来自数据链路层和高层的数据报。输出队列则存放的是要发送到数据链路层和高层的数据。处理模块从输入队列中取出数据报,分片和重装模块则向输出队列中添加数据报。
路由表:转发模块利用路由表来确定下一跳的地址。
转发模块:接受来自处理模块的IP分组。找出下一站的IP地址以及发送该分组时应当使用的接口。然后将分组以及这些信息传递给分片模块。
MTU表:分片模块使用MTU表找出特定接口的MTU值。
分片模块:分片模块查询MTU表,若数据报长度大于MTU,则进行分片,对每一个分片添加首部,并将它们发送个ARP软件包以进行地址解析和交付。
重装表:有5个字段,状态、源IP地址、数据报标识符、超时以及分片。状态字段取值为FREE或IN-USE。数据报标识是IP分组中的标识字段,定义了一个数据报以及属于该数据报的所有分片。超时表示所有分片必须在预定的时间内到达。分片字段是指向分片链表的指针。
重装模块:找出分片是属于哪个数据报的,并将它们进行排序,所有分片都到达时重新组装成一个数据报,超时的话全部丢弃。
参考
《TCP/IP协议族(第4版)》 (Behrouz A.Forouzan) 第四、五、六、七章