网络层是OSI参考模型中的第三层,介于传输层和数据链路层之间,其主要作用是实现两个不同网络系统之间的数据透明传送,具体包括路由选择,拥塞控制和网际互连等。网络层负责在不同的网络之间(基于数据包的IP地址)尽力转发数据包,不负责丢包重传和接收顺序。
而IP协议就是网络层中的一个重要协议。
IP指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。设计IP的目的是提高网络的可扩展性:一是解决互联网问题,实现大规模、异构网络的互联互通;二是分割顶层网络应用和底层网络技术之间的耦合关系,以利于两者的独立发展。根据端到端的设计原则,IP只为主机提供一种无连接、不可靠的、尽力而为的数据包传输服务。
IP协议主要包含三方面内容:IP编址方案、分组封装格式以及分组转发规则。
IP协议报文由报头和数据组成。由于IP位于网络层,而网络层是OSI参考模型的第三层,因此数据自顶向下做封装时,IP报文的数据部分必然包含上两层的报头和有效载荷。现对IP报头进行介绍。
- 四位版本号:指定IP数据报中使用的IP协议版本,占4位,IPv4对应值为4(0100)。
- 4位首部长度:这与TCP的四位首部长度含义相同。四位范围为[0000,1111]即 [0,15](单位是字节)。四位首部长度=四位范围*4字节,因此四位首部长度范围为[0,60]。因为标准报头不包含选项内容,即标准报头大小为20字节,因此四位首部长度范围为[20,60]。
- 8位服务类型(TOS):: 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0)。4位 TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本。这四者相互冲突, 只能选择一个。对于ssh/telnet这样的应用程序, 最小延时比较重要; 而对于ftp这样的程序, 最大吞吐量比较重要。
- 16位总长度(total length): IP数据报整体占多少个字节。IP是固定长度报文,因此IP协议是面向数据报的。
- 16位标识(id): 唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个 id都是相同的。
- 3位标志字段: 第一位保留不用。第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文。第三位表示"更多分片", 如果分片了的话, 最后一个分片置为1, 其他是0,类似于一个结束标记。
不同网络上的链路可以传输的最大报文大小是不同的,这就是我们通常说的MTU(最大传输单元)。尺寸较大的数据报在MTU值较小的网络链路传输需要将数据报分段依次传输,对应的接收方就需要把这些接收到的拆分的分段组合起来,还原成原来的数据报。
- 13位分片偏移(framegament offset): 是分片相对于原始IP报文开始处的偏移,其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此, 除了最后一个报文之外, 其他报 文的长度必须是8的整数倍(否则报文就不连续了)。
- 8位生存时间(Time To Live, TTL): 数据报到达目的地的最大报文跳数。一般是64,每次经过一个路由, TTL -= 1, 一直减到0还没到达, 那么就丢弃了。设定生存时间是为了防止数据报在网络中无限制地循环转发。
- 8位协议: 表示上层协议的类型。通过该字段告诉接收方应该将报文交付给上层哪个协议。
- 16位头部校验和: 用来检验IP数据报的包头部分(不含“数据”部分),在传输到接收端后是否发生了变化,占16位。因为数据报每经过一个路由器,路由器都要重新计算一下首部校验和。
- 32位源地址和32位目标地址: 表示发送端和接收端的IP地址,各占32位。
- 选项:用来支持各种选项,提供扩展余地,可用来支持排错、测量以及安全等措施。
转发器
(repeater)。网桥
或者桥接器(bridge)。路由器
(router)。网关
(gateway)。用网关连接两个不兼容的系统需要在高层进行协议转换。本文主要介绍的是网络层,那么介绍的使用设备是路由器。
须知:
IP地址分为两个部分,网络号和主机号。
- 网络号:保证相互连接的两个网段具有不同的标识。(网段:一段范围内的IP,网络号相同的IP处于同一个网段。)
- 主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号。
- 子网:IP 地址是以网络号和主机号来表示网络上的主机的, 只有在一个网络号下的计算机之间才能“直接”互通, 不同网络号的计算机要通过网关(Gateway)才能互通。但这样的划分在大多数情况下显得并不十分灵活。为此IP网络还允许划分成更小的网络, 称为子网(Subnet)。
- 不同的子网其实就是把网络号相同的主机放到一起。
- 如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复。在不同的子网主机号可以相同。
通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同。
而IP地址这么多,在子网中管理IP地址就成了非常复杂的事情。因此孕育出了DHCP技术。
DHCP 动态主机配置协议
:首先,这是一个应用层协议,可以自动给子网内新增的主机节点分配IP地址
。一般的路由器都带有DHCP功能, 因此路由器也可以看做是一个DHCP服务器。在过去曾提出一个划分IP地址的方案,将所有的IP地址划分为五类。
- A类从0.0.0.0到127.255.255.255
- B类从128.0.0.0到191.255.255.255
- C类从192.0.0.0到223.255.255.255
- D类从224.0.0.0到239.255.255.255
- E类从240.0.0.0到247.255.255.255
随着互联网的发展,这种划分方案的局限性逐渐被扩大。大多数组织会申请B类网络地址。导致B类网络地址很快被分配完,而A类缺浪费了大量地址。B类的一个子网能够容纳6w多个主机号,在生活中使用较为合理。而A类的一个子网可以容纳1千6百多万主机,在实际的网络架设中, 不会存在一个子网内有这么多主机的情况,因此大量的IP地址都被浪费掉了。
针对这种情况就有人提出了新的划分方案,称为CIDR(Classless Interdomain Routing)即子网掩码。
举个例子
- IP地址中的主机号全为0,就成了网络号,代表这个局域网。
- 将IP地址中的主机号的二进制全部设为1,就成为了广播地址。用于给同一个链路中相互连接的所有主机发送数据包。
- *的IP地址用于本地环回测试。它代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。所以通常在安装物理网卡前就可以ping通这个本地回环地址。 一般都会用来检查本地网络协议、基本数据接口等是否正常的。通常使用127.0.0.1。
IP地址(IPv4)是一个4字节32位的正整数,那么一共只有2的32次方个IP地址, 大概是43亿左右。而TCP/IP 协议规定, 每个主机都需要有一个IP地址。
实际上由于一些特殊的IP地址的存在,我们的可使用IP数量远远不及43亿。并且IP地址并非是按照主机划分,而是一张网卡需要配置一个或多个IP地址。
CIDR在一定程度上提高了IP地址的使用率,减少了浪费,但实际上IP地址的绝对上限并没有增加,仍然是不够用的。此时有人提出了三种方式来解决:
RFC1918
规定了用于组建局域网的私有IP地址。
- 10.*,前8位是网络号,共16,777,216个地址。
- 172.16*到172.31 *,前12位是网络号,共1,048,576个地址。
- 192.168.*,前16位是网络号,共65,536个地址。在这个范围中的IP地址都成为私有IP, 其余的则称为全局IP(或公网IP)。
总结一下:
通常我们使用的是内网IP即源IP是内网IP,而目的IP是公网IP。我们向公网IP发送请求。此时服务器面对的是一个内网IP,而内网IP是可以重复的,因此服务器就不知道将响应发给谁。
因此实际上我们发送的报文会通过路由器。路由器会将报文的源IP(内网IP)转换为wan口IP,然后继续向服务器发送,经过多个路由器的wan口IP转换后,服务器拿到的就是公网IP了。其中LAN口IP转化换为WAN口IP的技术就是NAP技术。
一个IP报文被发出,经过一个个路由器时,IP地址会不断发生改变。是由于进入或出去路由器的网络时IP地址会与子网掩码进行计算。其中IP报文越靠近目的IP,其路径上的路由器的子网掩码位数越来越多,IP地址能操作的主机号位数越来越少,即IP报文的定位越靠近IP主机,直到IP主机收到IP报文。
从名字来听可以认为路由具有在复杂的网络结构中, 找出一条通往终点的路线。
而路由的过程,就是“一跳一跳”(Hop by Hop)“问路”的过程。
IP数据包的传输过程
- 当IP数据包, 到达路由器时, 路由器会先查看目的IP。
- 路由器根据路由表中的目的地址栏目,决定是直接将数据包发送给目的IP,还是发送给下一个路由器。
- 如果目的IP存在于路由表中,路由器会将报文直接发送给目标主机或转发给下一个路由器。
- 当目的IP与路由表中的地址都不匹配时,路由器会将数据包转发给默认目的IP。
- 重复这个过程, 一直到达目标主机(或者TTL为0时被丢弃);
路由表可以通过route查看
以下面路由表为例
例如路由器收到的IP报文的目的IP是192.168.10.33。该目的IP与第一行的子网掩码运算后得到192.168.10.0。与第一行的目的地址相符合,因此就通过eth0接口将报文发送给目的地址的网关。
若路由器收到的IP报文的目的地址是192.168.45.33。该目的IP与子网掩码运算后得到192.168.45.0,其网络号都没有命中路由表中的目的地址,路由器就会将该IP报文转发给默认网关(default)192.168.10.1。
实际上查找目的IP是先查找他所归属的子网,报文经过路由器转发后进入子网,IP报文的网络号部分也由公网IP转换为子网IP,然后路由器根据转换后的IP将报文发送给目的主机。
再次分析IP报头结构
16位标识:标识IP报文的唯一性。如果一个IP报文在数据链路层被分片了,那么每一片的这个字段都是一样的。
3位标志:第一位被弃用。第二位为0说明该报文允许被分片,第二位为1说明该报文禁止被分片,若该报文长度超过MTU(在数据链路层具有MAC帧协议,MAC帧协议规定自己的有效载荷大小不能超过一定字节—MTU大小,这里假定MTU大小为1500字节),那么该报文就要被丢弃。如果分片了,标志位第三位为0,标识IP报文的结尾,其余分片为1。
13位片偏移:分片相对于原始IP报文起始的偏移量,标识该分片位于IP报文的位置,实际上分片偏移量=该13位偏移*8。因此除了最后一个分片,其余分片的该字段都为8的整数倍。
当前分片报文的起始地址+自身报文长度=下一个分片报文的起始地址。即可以根据分片报文的13位偏移量得知分片报文在原始报文的顺序。且根据13位偏移量就能够对分片报文按序组装。
分片的三位标志位第三位为1说明该报文为分片报文。若分片的三位标志位第三位为0且13位偏移量>0说明该报文即是分片报文又是末尾报文。
可以根据报文的16位标识得知哪些报文是同一个报文的分片。
将分片报文组装好后,在网络层IP协议会对报文的报头进行16位首部校验和验证。且报文去到控制传输层TCP协议也会对报文的报头进行校验和验证。
但IP报文分片与组装,不是主流情况。分片报文丢失一份,源IP就需要重传一整份IP报文,大大增加了丢包率。
IP地址
硬件地址