先看一下协议头的全景图,每一个竖线代表一个比特
Version: 4比特
标记当前报文使用的协议格式,本文件描述的是第4版本。
IHL:4比特
表示请求头32比特字长度(单位是32比特),它的计算是从第一个字节开始。一个正确的包头最小长度的5。
Type of Service:8比特
标记发出服务希望的传输质量的参数。这些参数用来指引网络进行包传输时实际参数的选择。某些网络提供优先级支持,对优先数据包给予更高德重视(一般是在高负载的时候,已处理高于特定优先级的数据包)。最终的选择是在低延时,高可用,高吞吐之间的权衡。
使用延时,吞吐,可用三个指示器的时候,在某种程度上会增加服务消耗。使用一个指示器性能好的网络,往往不适合另一个指示器。除非特别不常见的场景,一般最多同时使用两个指示器。
服务类型用来说明数据包在网络中传输时如何被处理。“服务映射”一节会说明不同网络中服务类型和真实服务类型之间的映射关系。
网络优先级的设计目标仅是在一个网络内使用。具体怎么使用,如何起控制作用由具体的网络决定。网络还需要控制访问和使用这些优先级指示器。
Total Length: 16比特
是数据包的总长度,包含包头长度,以字节(8比特)为单位。这个字段限制了数据包的最大长度是65535字节长度。对于大多数主机和网络,65535字节数据包是不实用的。所有主机都需要能够接收最大576字节的数据包(不论是完整数据包,还是数据包分片)。
选择576这个数字是为了能够传输除头数据之外的合理大小的数据块。比如,这个大小能容纳512字节数据块,外加64字节包头的数据包。最大包头是60字节,常见的包头是20字节,考虑高层协议头的对齐。
Identification: 16比特
重新组装分片的标识符。
Flags: 3比特
控制标记。0比特-保留位,必须是0;1比特-是否分片,0允许分片,1不允许分片;2比特-是否最后一个分片,0最后一个分片,1还有更多分片。
Fragment Offset: 13比特
标记分片在整个数据包的哪个位置。偏移量单位是8个字节(64比特)。第一个分片的偏移量是0。
Time to Alive: 8比特
标记数据包在网络中的最大存活时间。如果这个字段值是0,数据包必须即刻被销毁。字段值在包头处理过程中会被修改。字段值单位是秒,但是每一跳处理数据包时最少减一。处理时间小于1秒,也要减一。这个字段只能最为最大存活时间上限。目的是为了丢弃无法被传输的包(防止一直在网络中循环传递),限制数据包的生存期。
Protocol: 8比特
标记数据体中封装的另一层网络协议类型。“Assigmed Numbers”章节给出了多种协议的类型值。
Header Checksum: 16比特
包头数据的检验值。由于包头部分字段传输中会发生变化,检验值在每一跳包头处理时也需要重新计算和检验。
校验码算法:该字段的值是包头中所有16比特位的补码和。计算时需要把该字段赋值为0。
以上是一种简单的检验算法,从经验看是够用的。但这是临时的,需要看以后的使用经验,也很有可能在以后被CRC算法替代。
Source Address: 32比特
原地址。
Destination Address: 32比特
目标地址。
Options: 可选的
选项字段在数据包中可以出现,也可以不出现。所有的主机和网关的IP模块必须支持选项字段。选项字段在包传输时是可选的,但是是否实现不是可选的。
某些环境下,所有数据包必须包含安全选项。
选项字段的长度是变化的,可以是零个,也可以是多个。选项有两种格式类型:
Case 1:仅一个8比特的选项类型
Case 2:一个8比特选项类型,一个8比特选项长度,和真正的选项数据。
选项长度包含选项类型和选项长度占用的字节。
选项类型分为3个域:
1比特:拷贝标记
2比特:选项类别
5比特:选项数值
拷贝标记指名该选项在分片过程中,要拷贝到所有分片。
0:不拷贝
1:拷贝
选项类别包括:
0:控制
1:保留将来使用
2:调试和测量
3:保留将来使用
选项的细节这里省略不议了,一般较少使用。
协议的实现必须足够强壮。不同个体实现的协议应当能交互操作。虽然本文档的目的是为了明确协议,但是仍然不能排除理解上的差异。一般,发送行为实现上要尽可能保守,接收行为实现上要尽可能放宽限制。也就是说,必须尽可能小心的发送格式化良好的数据包,接收任何能解析的数据包(比如,不拒绝意义仍然明确的技术错误)。
基础网络服务是面向数据包的,网关提供数据分片,目的主机的IP模块进行数据包重组。当然,数据包在网关之间分片和重组也是允许的,因为这对IP协议以及高层协议都是透明的。这种透明的分片叫做网络依赖分片,本文不做深入讨论。
网络地址区分原地址和目的地址,同时提供一个协议字段。不论是否有必要使用多路传输,这都需要提供。这一段有点懵
寻址
为了提供分配地址的灵活性,支持大量的小到中型网络。网络地址被逻辑上分为几类:少量网络号每个网络号包含大量主机,中量网络号每个网络号包含中量主机,大量网络号每个网络号少量主机,还有剩下的值就给扩展分类使用。
地址格式:
真实网络地址值见“Assigned Number”章节。
本地网络分配的本地地址必须允许一个主机扮演多个不同的网络主机拥有多个网络地址
。也就是说,必须实现一个网络地址和接口的映射关系,一个接口封装多个网络地址的处理。允许主机有多个物理接口,处理多个接口的数据包就像处理一个接口的数据包一样。不同网络地址之间的映射关系见“Address Mapping”章节。
分片和重组
网络标识字段(ID)协同源地址、目的地址、协议类型识别包的分片完成重组。
如果分片不是最后一个分片,更多分片字节被设置为1。分片偏移量字段指名分片的位置,位置是相对于原始未分片包的起始位置。分片以8字节为单位(64比特)。不分片的包分片相关字段都为0值(MF=0,Fragment offset=0)。如果一个包需要被分片,分片必须以8字节为最小单位。
这种策略最大允许2**13=8192个8字节长度,也就是65535个字节长度。这个数据包的总长度字段是一致的,只是总长度字段包含了包头长度,分片长度不包含。
发生分片的时候,有些选项会拷贝给所有分片,有些分片只会保留在第一个分片。
所有的IP模块必须能够不分片的传输68个字节。因为包头最大有60字节,最小分片是8字节。
每一个网络终端必须能够接收576字节的数据包。
可能会被分片影响的字段包括:
(1)选项字段
(2)更多分片标记
(3)分片偏移量
(4)包头长度
(5)总长度
(6)包头检验和
如果设置了不分片字段,那么这个网络包是不允许分片的,尽管数据包可能会被丢弃。可以用在目标主机没有足够资源处理分片重组的情况。
用例子描述分片和重组过程更加便于理解。以下用示例来描述这个过程。
(例子暂不翻译了)
序号
增加序号字段是因为需要唯一的识别某个网络包的分片。协议模块在重组分片时把具有相同源地址、目标地址、协议类型、序号的分片识别成同一个包的分片。数据包发送者必须选择具有唯一性的序号,在网络包的生存期内不能重复。
看起来像是,协议发送模块维护了一个序号表,在数据包在因特网上的最大生命期内,与它通讯的每个目的地都有一条记录。
然而,因为序号字段可以容纳65536个数值,所以有些主机可以简单的实现不区分目的地的序号。
对于某些高级的网络协议来说,也可以适当的选择使用序号字段。比如说,TCP协议可能重传TCP分片,如果重传时使用相同的序号,那么接收的成功率就会提高,因为,两次发送的TCP分片的每一个IP分片都可以参与TCP分片的重组。
服务类型
服务类型字段用于网络服务质量选择。服务类型由四种抽象参数定义:优先级、延时、吞吐、可靠性。四个抽象参数对应的真实服务参数由网络包途经的网络定义。
优先级:数据包重要性的独立度量。
延时:要求数据包被及时传递。
吞吐:要求高德数据传输率。
可靠性:要求在传输上做更多保障。
比如阿帕网有一个优先字节,并且可以选择“标准”消息(type 0)和“不受控”消息(type 3)。“不受控”消息倾向于较低的可靠性保证和低延时。假设,有一个数据包要经过阿帕网传输,设置服务类行为如下值:
在本例中,将这些参数映射到ARPANET的可用参数将是:设置ARPANET优先级位,因为Internet优先级在其范围的上半部分;选择“标准”消息,因为指出了吞吐量和可靠性要求,而没有延迟。更多详情将在服务映射章节给出。
生命期
数据包的生命期是网络包允许在因特网上传输的最大时间,由发送方设置。如果数据包在因特网上的生存时间大于了生存期,数据包必须被销毁。
在每一个端点处理数据包时必须减少生存期的值,以反应处理数据包消耗的时间。甚至在没有本地耗时信息的情况下,生命期值也要减1。生命期用秒来衡量,1代表1秒。因此,生命期的最大值是255秒,即4.25分钟。因为每一个模块处理数据包的时候尽管可能小于1秒,生命期都必须至少减小1,所以,生命期只能作为数据包可能存在的最大生存时间。生命期的目的是为了丢弃无法传递的数据包,限制数据包最大生存时间。
有些面向可靠连接的高层协议假设旧的重复数据包在一段时间之后就永远不会到达。生命期是保证这些协议上述假设成真的一种手段。
选项
这对数据包来说是可选的,对于实现网络协议来说是必备的。也就是说数据包携带选项与否由发送方决定,但是每一个网络模块必须能够解析所有选项。选项字段可能会同时包含多个选项值。选项可能不能满足32字节的边界,必须用0填充剩余字节。前半部分是最后一个选项值,后半部分是填充字节。
每个网络模块必须能够处理所有的选项值。如果要传输机密、受限或分隔的数据,则需要使用“安全”选项。
校验和
如果网络头有变化,需要重新计算校验和。比如,生命期值减小、增加选项或者发生分片。网络头校验和的作用是保护网络头,防止发生传输错误。
某些应用允许少量字节错误,倒是不允许网络延时。如果网络协议强制了数据正确性,那么就不能支持这些应用了。
错误
IP协议错误可以通过ICMP返回。
用户接口功能描述是尽可能构想的,因为每个操作系统都有不同的基础设施。因此,必须提醒读写的是不同的协议实现可能有不同的用户接口。倒是,所有的IP实现中必须包含一个最小功能集,保证所有的IP模块能支持所有的协议族。接下来说明所有IP实现必须的功能接口。
IP协议接口一边连接的是本地网络,一边连接的是高层协议或者用户程序。接下来把高层协议或者用户程序称为用户,因为他们使用网络模块。IP协议是数据包协议,所以需要提供最小内存和传输时状态保持。调用IP模块的用户需要提供IP工作必须的所有信息。
上层接口示例:
以下是用户调用网络模块满足要求的两个示例(=>表示返回值)。
当用户发送数据包的时候,调用SEND方法,提供所有SEND需要的参数。当IP模块接收到调用之后,会检验参数,准备并发送消息。如果参数没有问题,数据包被本地网络成功接收了,SEND返回成功。如果参数有问题,或者本地网络没有成功接收,SEND返回不成功。当不成功时,需要返回问题原因的合理报告,但是报告的详情由实现模块自行决定。
当数据包从本地网络到达IP模块的时候,可能存在挂起的RECV调用,也可能不存在。第一种情况下,挂起的RECV调用把数据传递给用户才结束。第二种情况下,通知用户地址有达到的数据包。如果用户地址不存在,会返回给发送方ICMP错误报文,同时丢弃数据包。
通知用户可以通过模拟中断或者相似的机制,具体由操作系统环境适当性选择。
用户RECV调用可以是接收到挂起的数据包即返回,也可以是一直等到数据接收完成再返回。
调用SEND的时候指定源地址,以防主机有多个地址存在(多个物理连接或者逻辑地址)。IP模块必须检查源地址是不是自己逻辑地址之一。
IP模块的实现可以允许或要求调用时指名对某类数据包感兴趣,或者对其独占使用。
这一节从功能上说明了用户/IP模块间的接口。所用符号和高级语言里函数间调用的符号相似。这种用法没有排除中断类型(Trap Type)的服务调用(SVCs, UUOs, EMTs),或者其他形式的进程间通信。指明不排除异步类型调用?