1.4.1 IP协议
IP协议是TCP/IP协议族中最为核心的协议。它把上层数据报封装成IP数据报后进行传输。如果IP数据报太大,还要对数据报进行分片后再传输,到了目的地址处再进行组装还原,以适应不同物理网络对一次所能传输数据大小的要求。
1.IP协议的特点
(1)不可靠
不可靠的意思是它不能保证IP数据报能成功地到达目的地。IP协议仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端。任何要求的可靠性必须由上层协议来提供(如TCP协议)。
(2)无连接
无连接的意思是IP协议并不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。这也说明,IP数据报可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报(先是A,然后是B),每个数据报都是独立地进行路由选择,可能选择不同的路线,因此B可能在A之前先到达。
(3)无状态
无状态的意思是通信双方不同步传输数据的状态信息,无法处理乱序和重复的IP数据报;IP数据报提供了标识字段用来唯一标识IP数据报,用来处理IP分片和重组,不指示接收顺序。
2.IPv4数据报的报头格式
IPv4数据报的报头格式如图1-8所示,主要说明IPv4的报头结构,IPv6的报头结构与之不同。图1-8中的“数据”以上部分就是IP报头的内容。因为有了选项部分,所以IP报头长度是不定的。如果选项部分没有,则IP报头的长度为(4+4+8+16+16+3+13+8+8+16+32+32)bit=160bit=20字节,这也是IP报头的最小长度。
图1-8
· 版本(Version):占用4 bit,标识目前采用的IP协议的版本号,一般取值为0100(IPv4)和0110(IPv6)。
· 首部长度(Header Length):即IP报头长度,这个字段的作用是为了描述IP报头的长度。该字段占用4 bit,由于在IP报头中有变长的可选部分,为了能多表示一些长度,因此采用4字节(32 bit)为本字段数值的单位,比如,4 bit最大能表示为1111,即15,单位是4字节,因此最多能表示的长度为15×4=60字节。
· 服务类型(Type of Service,TOS):占用8 bit,可用PPPDTRC0这8个字符来表示,其中,PPP定义了数据报的优先级,取值越大表示数据越重要,取值如表1-1所示。
表1-1 数据报的取值及其含义
D:时延,0表示普通,1表示延迟尽量小
T:吞吐量,0表示普通,1表示流量尽量大
R:可靠性,0表示普通,1表示可靠性尽量大
C:传输成本,0表示普通,1表示成本尽量小
0:这是最后一位,被保留,恒定为0
· 总长度:占用16 bit,该字段表示以字节为单位的IP数据报的总长度(包括IP报头部分和IP数据部分)。如果该字段全为1,就是最大长度了,即216‒1= 65535字节≈ 63.9990234375KB,有些书上写最大是64KB,其实是达不到的,最大长度只能是65535字节,而不是65536字节。
· 标识:在协议栈中保持着一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。注意这个“标识符”并不是序号,IP是无连接服务,数据报不存在按序接收的问题。当IP数据报由于长度超过网络的MTU(Maximum Transmission Unit,最大传输单元)而必须分片(把一个大的网络数据报拆分成一个个小的数据报)时,这个标识字段的值就被复制到所有的小分片的标识字段中。相同的标识字段的值使得分片后的各数据报片最后能正确地重装成为原来的大数据报。该字段占用16 bit。
· 标志(Flags):该字段占用3 bit,该字段最高位不使用,第二位称DF(Don't Fragment)位,DF位设为1时表明路由器不对该上层数据报分片。如果一个上层数据报无法在不分段的情况下进行转发,则路由器会丢弃该上层数据报并返回一个错误信息。最低位称MF(More Fragments)位,为1时说明这个IP数据报是分片的,并且后续还有数据报;为0时说明这个IP数据报是分片的,但已经是最后一个分片了。
· 片偏移:该字段的含义是某个分片在原IP数据报中的相对位置。第一个分片的偏移量为0。片偏移以8个字节为偏移单位。这样,每个分片的长度一定是8字节(64位)的整数倍。该字段占13 bit。
· 生存时间(TTL,Time to Live,也称存活时间):表示数据报到达目标地址之前的路由跳数。TTL是由发送端主机设置的一个计数器,每经过一个路由节点就减1,减到为0时,路由就丢弃该数据报,向源端发送ICMP差错报文。这个字段的主要作用是防止数据报不断在IP互联网络上循环转发。该字段占8 bit。
· 协议:该字段用来标识数据部分所使用的协议,比如取值1表示ICMP、取值2表示IGMP、取值6表示TCP、取值17表示UDP、取值88表示IGRP、取值89表示OSPF。该字段占8 bit。
· 首部校验和(Header Checksum):该字段用于对IP头部的正确性检测,但不包含数据部分。由于每个路由器会改变TTL的值,所以路由器会为每个通过的数据报重新计算首部校验和。该字段占16 bit。
· 起源和目标地址:用于标识这个IP数据报的起源和目标IP地址。值得注意的是,除非使用NAT(网络地址转换),否则整个传输的过程中,这两个地址不会改变。这两个地段都占用32 bit。
· 选项(可选):这是一个可变长的字段。该字段属于可选项,主要是给一些特殊的情况使用,最大长度是40字节。
· 填充(Padding):由于IP报头长度这个字段的单位为32bit,所以IP报头的长度必须为32bit的整数倍。因此,在可选项后面,IP协议会填充若干个0,以达到32bit的整数倍。
在Linux源码中,IP报头的定义如下:
struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix <asm/byteorder.h>" #endif __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ };
这个定义可以在源码目录的include/uapi/linux/ip.h查到。
3.IP数据报分片
IP协议在传输数据报时,将数据报分为若干分片(小数据报)后进行传输,并在目的系统中进行重组,这一过程称为分片(Fragmentation)。
要理解IP分片,首先要理解MTU,物理网络一次传送的数据是有最大长度的,因此网络层的下层(数据链路层)的传输单元(数据帧)也有一个最大长度,这个最大长度值就是MTU,每一种物理网络都会规定链路层数据帧的最大长度,比如以太网的MTU为1500字节。
IP协议在传输数据报时,若IP数据报加上数据帧头部后长度大于MTU,则将数据报切分成若干分片后再进行传输,并在目标系统中进行重组。IP分片既可能在源端主机进行,也可能发生在中间的路由器处,因为不同网络的MTU是不一样的,而传输的整个过程可能会经过不同的物理网络。如果传输路径上的某个网络的MTU比源端网络的MTU要小,路由器就可能对IP数据报再次进行分片。分片数据的重组只会发生在目的端的IP层。
4.IP地址的定义
IP协议中有个概念叫IP地址。所谓IP地址,就是Internet中主机的标识,Internet中的主机要与别的主机通信必须具有一个IP地址。就像房子要有个门牌号,这样邮递员才能根据信封上的地址送到目的地。
IP地址现在有两个版本,分别是32位的IPv4和128位的IPv6,后者是为了解决前者不够用的问题而产生的。每个IP数据报都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据报选择路由。
这里以IPv4为例,IP地址由四个数字组成,数字之间用小圆点隔开,每个数字的取值范围在0~255之间(包括0和255)。通常有两种表示形式:
(1)十进制表示,比如192.168.0.1。
(2)二进制表示,比如11000000.10101000.00000000.00000001。
两种方式可以相互转换,每8位二进制数对应一位十进制数,如图1-9所示。
图1-9
实际应用中多用十进制表示,比如172.16.100.2。
5.IP地址的两级分类编址
互联网有很多网络构成,每个网络上都有很多主机,这样便构成了一个有层次的结构。IP地址在设计的时候就考虑到地址分配的层次特点,把每个IP地址分割成网络号(NetID)和主机号(HostID)两个部分,网络号表示主机属于互联网中的哪一个网络,而主机号则表示其属于该网络中的哪一台主机,两者之间是主从关系。同一网络中绝对不能有主机号完全相同的两台计算机,否则会报出IP地址冲突。IP地址分为两部分后,IP数据报从网际上的一个网络到达另一个网络时,选择路径时可以基于网络而不是主机。在大型的网际中,这一优势特别明显,因为路由表中只存储网络信息而不是主机信息,这样可以大大简化路由表,方便路由器的IP寻址。
根据网络地址和主机地址在IP地址中所占的位数可将IP地址分为A、B、C、D、E五类,每一类网络可以从IP地址的第一个数字看出,如图1-10所示。
图1-10
这5类IP地址中,A类地址,第一位为0,第二至八位为网络地址,第九至三十二位为主机地址,这类地址适用于为数不多的主机数大于65536(216)的大型网络,A类网络地址的数量最多不超过126(27‒2)个,每个A类网络最多可以容纳16777214(224‒2)台主机。
B类地址前两位分别为1和0,第三至第十六位为网络地址,第十七至三十二位为主机地址,此类地址用于主机数介于256~65536(28~216)之间的中型网络,B类网络数量最多16382(214‒2)个。
C类地址前三位分别为1、1、0,四到二十四位为网络地址,其余为主机地址,用于每个网络只能容纳254(28‒2)台主机的大量小型网,C类网络数量上限为2097150(221‒2)个。
D类地址前四位为1、1、1、0,其余为多目地址。
E类地址前五位为1、1、1、1、0,其余位数留待后用。
A类IP的第一个字节范围是0到126,B类IP的第一个字节范围是128到191,C类IP的第一个字节范围是192到223,例如192.X.X.X肯定是C类IP地址,根据IP地址的第一个字节的范围就能够推导出该IP属于A类、B类或C类。
IP地址以A、B、C三类为主,又以B、C两类地址更为常见。除此之外还有一些特殊用途的IP地址:广播地址(主机地址全为1,用于广播,这里的广播是指同时向网上所有主机发送报文,不是指我们日常听的那种广播)、有限广播地址(所有地址全为1,用于本网广播)、本网地址(网络地址全为0,后面的主机号表示本网地址)、回送测试地址(127.X.X.X型,用于网络软件测试及本地机进程间通信)、主机位全0地址(这种地址的网络地址就是本网地址)及保留地址(网络号全为1和32位全为0两种)。由此可见,网络位全1或全0和主机位全1或全0都是不能随意分配的。这也就是前面的A、B、C类网络的网络数及主机数要减2的原因。
总之,主机号全为0或全为1时分别作为本网络地址和广播地址使用,这种IP地址不能分配给用户使用。D类网络用于广播,它可以将信息同时传送到网上的所有设备,而不是点对点的信息传送,这种网络可以用来召开电视电话会议。E类网络常用于试验。网络管理员在配置网络时不应该采用D类和E类网络。特殊的IP地址如表1-2所示。
表1-2 特殊的IP地址
当前,A类地址已经全部分配完,B类也不多了,为了有效并连续地利用剩下的C类地址,互联网采用CIDR(Classless Inter Domain Routing,无类别域间路由)方式把许多C类地址合起来作B类地址分配,全球被分为四个地区,每个地区分配一段连续的C类地址:欧洲(194.0.0.0~195.255.255.255)、北美(198.0.0.0~199.255.255.255)、中南美(200.0.0.0~201.255.255.255)、亚太地区(202.0.0.0~203.255.255.255)、保留备用(204.0.0.0~223.255.255.255)。这样每一地区都有约3200万个网址供使用。
6.网络掩码
在IP地址的两级编址中,IP地址由网络号和主机号两部分组成,如果我们把主机号部分全部置零,此时得到的地址就是网络地址,网络地址可以用于确定主机所在的网络,为此路由器只需计算出IP地址中的网络地址,然后与路由表中存储的网络地址相比较就知道这个分组应该从哪个接口发送出去。当分组达到目的网络后,再根据主机号抵达目的主机。
要计算出IP地址中的网络地址,需要借助于网络掩码,或称默认掩码。它是一个32位的数,前面n位全部为1,后边32~n位连续为0。A、B、C三类地址的网络掩码分别为255.0.0.0、255.255.0.0和255.255.255.0。我们通过IP地址和网络掩码进行与运算,得到的结果就是该IP地址的网络地址。网络地址相同的两台主机,就是处于同一个网络中,它们可以直接通信,而不必借助于路由器了。
举个例子,现在有两台主机A和B,A的IP地址为192.168.0.1,网络掩码为255.255.255.0;B的IP地址为192.168.0.254,网络掩码为255.255.255.0。我们先对A运行,把它的IP地址和子网掩码每位相与:
IP: 11010000.10101000.00000000.00000001 子网掩码: 11111111.11111111.11111111.00000000 AND运算 网络号: 11000000.10101000.00000000.00000000 转换为十进制:192.168.0.0
再把B的IP地址和子网掩码每位相与:
IP: 11010000.10101000.00000000.11111110 子网掩码: 11111111.11111111.11111111.00000000 AND运算 网络号: 11000000.10101000.00000000.00000000 转换为十进制:192.168.0.0
可以看到,A和B的两台主机的网络号是相同的,因此可以认为它们处于同一网络。
由于IP地址越来越不够用,为了不浪费,人们对每类网络进一步划分出子网,为此IP地址的编址又有了三级编址的方法,即子网内的某个主机IP地址={<网络号>,<子网号>,<主机号>},该方法中有了子网掩码的概念。后来又提出了超网、无分类编址和IPv6。限于篇幅,这里不再赘述。