Linux网络IP协议

1.IP协议

主机是配有IP地址,也要进行路由的设备。路由器是既有IP地址,又能进行路由的设备。主机和路由器右统称为节点。

1.1协议报头格式

IP协议的报头部分和TCP报头的大小是相同的(在都无选项的情况下),IP协议报头分为12部分(忽略选项),分别为:4位版本、4位首部长度、8位服务类型、16位总长度、16位标识、3位标志、13位片偏移量、8位生存时间、8位协议、16位首部检验和、32位源IP地址、32位目的地址。一共20字节,如果有选项的话就要另算。

首先4位版本号对应的是IP协议的版本,主流的有IPv4和IPv6,这两个版本互不兼容。4位首部长度跟TCP的4位首部长度一样,取值范围都是20到60字节。8位服务类型在现代网络中实际使用的是DSCP(区分服务码点)和ECN(显式拥塞通知),早期定义中的3位优先权字段已弃用,4位TOS字段(分别表示最小延时、最大吞吐量、最高可靠性、最小成本)也已不再使用,当时这四者互相冲突,只能选择一种。

16位总长度代表报文的总长度,最大值为65535字节。拿总长度减去报头长度就可以得到正文长度,从而解决数据粘包问题。16位标识用于分片时标识分包的数据报属于哪一个组,相同标识的数据报属于分片前的同一个数据报。那么数据报为什么要分片呢?其实是因为链路层规定了最大传输单元(MTU),常见以太网的MTU为1500字节,当IP报文超过这个大小时就需要分片了。3位标志位中,第一位是保留位,第二位为1表示禁止分包,第三位表示更多分片,也就是说如果最后一位为0表示是最后一个分片,其他分片该位为1。13位片偏移量表示该数据报在分片前的源数据报中的偏移量,因为偏移量只有13位,无法直接表示16位总长度范围内的所有位置,所以实际偏移量除以8后再存入该字段。也就是说,13位偏移量其实是实际偏移量除以8的结果,对端拿到偏移量后乘以8得到真正的偏移量。因此,除最后一个分片外,其他每个分片的数据部分长度都必须是8的整数倍。

8位生存时间是报文到达目的地允许经过的最大路由器跳数,初始值通常为64。每经过一个路由器减1,如果减到0仍未到达目的地,报文就会被丢弃,这主要是为了防止路由循环导致报文在网络中永远存在。8位协议标识上层协议,用于分用时确定该交给传输层的哪个协议(如TCP或UDP)。16位首部校验和采用Internet校验和(反码求和)进行校验,用于检测头部是否在传输过程中损坏。32位源IP地址和32位目的地址就是字面意思。

1.2网段划分

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到233.255.255.255,D类从244.0.0.0到239.255.255.255,E类从240.0.0.0到247.255.255.255。

但是因为使用互联网的人数越来越多,这种划分方案的局限性很快显现出来。大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址。因为A类、B类这种一个子网理论上能允许很多主机,但实际一个子网里的主机数有限,远远达不到理论值,导致大量IP地址被浪费。为了解决以上问题,提出了新的划分方案,称为CIDR(无类别域间路由)。CIDR引入网络掩码来区分网络号和主机号。子网掩码是32位的整数,由**连续的1(网络部分)和连续的0(主机部分)**组成。将IP地址跟子网掩码按位与,得到的结果就是网络号。

在一个子网中,在子网掩码限定的主机位范围内,将主机地址全部设为0就成了网络号,代表这个局域网。将主机地址全部设为1就代表广播地址,用于向局域网内的所有主机发送信息。127.*的IP地址是用于本地环回的,通常是127.0.0.1。

我们都知道IPv4是一个32位4字节的整数,一共有大约43亿个IP地址。但由于要扣除网络号、广播地址、组播地址、私有地址、环回地址等,实际可分配给主机的地址远少于43亿。而且像路由器这种网络设备的每个接口也需要占用IP地址,这进一步减少了可分配给主机的数量。CIDR虽然提高了IP地址的利用率,但IP地址的总数上限没有提升,依然不够用。这时候有三种解决方案:

  1. 动态分配IP地址:通过DHCP等技术,在设备接入网络时临时租用一个IP地址,断开后该IP可被其他设备使用。这样同一个MAC地址的设备,每次接入互联网时获取的IP地址不一定是相同的。

  2. NAT技术:允许多个设备共享一个公网IP地址访问互联网。

  3. IPv6:IPv6与IPv4彼此不兼容,IPv6使用16字节(128位)来标识IP地址,地址总数约为 21282128 个(约 3.4×10383.4×1038 个),可以给地球上的每一粒沙子分配一个IP,从根本上解决了地址短缺问题。

1.3私有IP和公网IP

RFC1918规定了用于组建局域网的私有IP地址为:10.*,前8位是网络号(10.0.0.0/8);172.16.0.0到172.31.255.255,前12位是网络号(172.16.0.0/12);192.168.*,前16位是网络号(192.168.0.0/16)。除去这些地址范围的其他地址都称为公网IP(或公网IP地址)。我们日常使用的家庭、企业网络通常都使用私有IP地址(内网),通过路由器NAT转换后才能访问公网上的服务器。

那么内网又是怎么通信的呢?首先,路由器有两个及以上的网卡,因此拥有两个及以上的IP地址。一般来说,路由器的IP地址分为子网IP和WAN口IP:子网IP用于在子网内通信,而WAN口IP可能是上一级子网的内网IP,也可能是公网IP。在一个子网内的主机想向公网的一台主机发送信息,会经过以下流程:主机查找自己的路由表,找不到目标IP对应的条目,则将数据发送给默认路由(也就是本子网的路由器)。子网路由器收到数据后,执行NAT转换,将源的私有IP地址和端口替换为路由器WAN口IP地址和新分配的端口,并记录映射关系。然后路由器查找自己的路由表,如果仍找不到目标IP,就继续发送给它的默认路由(WAN口所在子网的网关)。重复上述步骤,直到数据到达WAN口IP为公网IP的路由器。之后数据在公网内通过路由协议逐跳转发,最终到达目标主机所在局域网的入口路由器。目标局域网的路由器根据目标IP(可能是公网IP或经过端口映射后的内网IP)将数据转发给目标主机。

在一个局域网内,不同WAN口IP的路由器所连接的子网IP是可以相同的(例如多户家庭都使用192.168.1.0/24)。这是因为私有IP地址只用于子网内部通信,不会影响上层网络或公网。前提是这些子网之间没有直接路由需求,否则需要额外配置。通过这种方式,结合NAT技术,极大地缓解了IPv4地址不足的问题。

1.4理解公网

数据报是怎么在公网传输的呢?数据在公网和内网上的路由原理没有本质区别,都是查找路由表决定下一跳。查找路由表时,路由器会拿目的IP与路由表条目中的网络掩码按位与,得到网络号,再与该条目的目标网络进行对比,决定下一跳的位置。不同的路由表条目可以有不同的网络掩码,也就是说公网中的网络前缀长度并不是固定的。实际的路由选择使用的是最长前缀匹配原则,即路由器会在所有匹配的条目中选择掩码最长(网络号最精确)的那一条作为转发依据。为了减少路由表条目数量,公网中大量使用路由聚合,例如一个大的ISP可能对外通告一个8位掩码的大前缀(如1.0.0.0/8),而内部再将这个地址块细分为10位或16位掩码的更小前缀分配给下级网络。这种层次化的地址分配和聚合机制保证了公网路由的可扩展性,但路由器在实际查表时仍然是统一按照最长前缀匹配来进行。

相关推荐
A小辣椒2 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao3 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush44 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5204 天前
Linux 11 动态监控指令top
linux
网络研究院4 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展