• java
  • go
  • 数据库
  • linux
  • 中间件
  • 书
  • 源码
  • 夕拾

  • java
  • go
  • 数据库
  • linux
  • 中间件
  • 书
  • 源码
  • 夕拾

ip协议详解

目录

  • 目录
  • ip服务特点
  • ipv4头部信息及释义
    • 抓包报文示例
  • ip分片
  • ip路由
    • ip模块工作流程
    • 路由机制
      • ip路由机制
    • 路由表的更新
  • ip转发
  • 重定向
  • ipv6头部结构
    • ipv6扩展头部

ip服务特点

ip协议是tcp/ip协议族的动力,为上层协议提供无状态,无连接,不可靠服务

ip通信双方不同步传输数据的状态信息,因此所有的ip数据报的发送,传输,接收都是相互独立,没有上下文的关系.

这种服务的缺点是无法处理乱序数据和重复的ip数据报.接收端的ip模块只要接收到了完整的ip数据报(如果ip分片,ip模块无法将其先行重组),就将其数据部分(tcp报文段,udp报文段,或者icmp报文)交给上层协议.

ip虽然在数据报头部提供了一个标识字段用以唯一标识一个IP数据报,但它是被用来处理ip分片和重组的,不是用来指接收顺序.

无状态服务的优点也很明显:简单高效.

无连接(connectionless)指ip通信双方都不长久维持对方信息.这样上层协议每次发送数据的时候,都必须明确指明对方的ip地址.

不可靠指的是ip协议不能保证ip数据报准确地到达接收端.使用ip服务的上层协议需要自己实现数据确认,超时重传等机制

ipv4头部信息及释义

image.png

字段说明
4位版本号 version version,指定ip协议的版本,对IPv4来说值为4,其他ipv4协议的扩展版本(sip协议和pip协议)有不同的版本号,也头部结构也不同
4位头部长度 header-length(4) 标识该ip头部有多少个32bit(4字节),因为4位最大能标识15.所以ip头部最长60字节
8位服务类型(TOS) type of service,包括一个3位优先权字段(现已被忽略),4位tos字段和1位保留字段(必须为0).4位tos字段分别表示:最小延时,最大吞吐量,最高可靠性,最小费用,最多有一个能置为1,应用程序应该根据实际需求来设置它,ssh和telnet这也的登陆程序需要的是最小延时服务,文件传输这种需要最大吞吐量服务)
16位总长度 total length 指整个ip数据报长度,以字节为单位,因此ip数据报最大长度为65535字节.由于MTU限制,长度超过MTU的数据报将被分片传输,所以实际传输的IP数据报(或分片)长度都远远没有到达最大值
16位标识(identification) 唯一标识主机发送的每一个数据报.其初始值由系统随机生成:没法送一个数据报,其值就加1.该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值
3位标志 3位标志字段的第一位保留.第二位(don’t fragment,df)标识”禁止分片,如果ip数据报长度超过了MTU,则会返回一个ICMP差错报文,第三位(MORE fragmet,MF)标识更多分片,除了数据报最后一个分片,其他分片都把它设置为1
13位分片偏移(fragmentation offset) 分片相对原始IP数据报开始处(仅指数据部分)的偏移,实际的偏移值时该值左移3位(乘8)后得到的.由于这个原因,除了ip数据报最后一个分片,其他分片的数据部分长度都必须是8的整数倍(这也才能保证后面的分片有一个合适的偏移值)
8位的生存时间(TIME to Live,ttl) 数据报到达目的地之前允许经过的路由器跳数,ttl值被发送端设置(场景的值是64).没经过一个路由器,都会被路由器减1,当ttl值为0,则会丢弃数据报并返回一个ICMP差错报文,ttl值可以防止数据报陷入路由循环
8位协议 protocol 区分上层协议,linux中 /etc/protocols 中定义了所有上层协对应的protocol值,ICMP是1,tcp是6,udp是17./etc/protocols是RFC 1700的一个子集
16位头部校验 header checksum 发送端填充,接收端对其使用CRC算法以检验IP数据报头部(仅检验头部,在传输过程中是否损坏)
32位源端/目的端ip地址 用来标识数据报的发送端/接收端.
选项字段(option) 可变长的可选信息,最多包含40字节,因为内ip头部最长是60字节(20字节固定).

补充:
可选字段的选项内容:

  1. 记录路由(record route),告诉数据报途径的所有路由器都将自己ip地址填入ip头部的选项部分,可以跟踪数据报的传递路径
  2. 时间戳(timestamp),告诉每个路由器将数据报被转发的时间(或时间与ip地址对应),填入ip头部的选项部分,这样我们就可以跟踪数据报的传递路径.
  3. 松散源路由器选择(loose source routing),指定一个路由器ip地址列表,数据包发送过程,必须经过其中所有的路由器.
  4. 严格源路由器选择(strict source routing),和松散源路由器,数据报只能经过被指定的路由器

使用3,4的大概仅有trace route程序,此外作为记录路由ip选项的替代品,traceroute程序使用UDP报文和ICMP报文实现了更可靠的记录路由功能

MTU(Max Transmit Unit,帧最大传输单元),以太网帧的MTU是1500字节

抓包报文示例

1
2
3
4
5
IP 127.0.0.1.37804 > 127.0.0.1.23: Flags [S], seq 1037143771, win 65495, options [mss 65495,sackOK,TS val 1696486497 ecr 0,nop,wscale 7], length 0
0x0000: 4510 003c 349e 4000 4006 080c 7f00 0001
0x0010: 7f00 0001 93ac 0017 3dd1 8edb 0000 0000
0x0020: a002 ffd7 fe30 0000 0204 ffd7 0402 080a
0x0030: 651e 5461 0000 0000 0103 0307

本次为本机操作,使用telnet登陆,端口号为23,二客户端使用临时端口号37804与服务器进行通信.
flags,seq,win,options描述的都是tcp头部信息.length指出该数据报所携带的应用程序数据的长度.
本次抓包开启了tcpdump的-x选项,使之输出2进制码,此数据包共包含60字节,前20字节是ip头部,后40字节为tcp头部

16进制 10进制 头部信息
0x4 4 ip版本号
0x5 5 头部长度,为5个32bit–20字节
0x10 10 TOS选项最小延时服务
0x003c 60 数据报总长度
0x349e 数据报标识
0x4 禁止分片
0x000 0 分片偏移
0x40 64 ttl
0x06 6 协议字段为6,上层协议为tcp
0x080c 头部校验
0x7f000001 32位源端ip
0x7f000001 32位目的端ip

ip分片

ip数据报的长度超过帧的MTU时,它将被分片传输.分片可能发生在传送段,也可能在中转路由器上,而且可能被多次分片,只有在最终的目标机器上,这些分片会被内核中的ip模块重组.

ip头部信息中的数据报标识,标志和偏移量为ip分片和重组提供了足够的信息.一个ip数据报的每个分片都具有自己的IP头部,他们具有相同的标识值,但具有不同的片偏移.并且除了最后一个分片外,其他分片都将设置MF标志.此外,每个肺片的IP头部的总长度字段将被设置为该分片的长度.

以太网帧的MTU是1500字节(可以通过ifocnfig或者netstat命令查看),因此它携带的ip数据报中数据部分最多是1480字节.

ip路由

IP协议一个核心任务就是数据报的路由,即决定发送举报到目标机器的路径.

ip模块工作流程

image.png

从右向左分析

  1. ip模块收到数据链路层的数据后,先对数据报的头部做CRC校验,确认无误之后分析头部的具体信息.
  2. 如果该IP数据报的头部设置了原站选路选项(松散源或者严格源路由选择),则ip模块调用数据报转发子模块来处理该数据报.
  3. 如果该数据报头部信息中的目标地址是本机的某个ip地址,或者广播地址,即该数据报是发送给本机的,则ip模块就根据数据包中的协议字段来决定将它派发给上层应用.
  4. 如果ip模块发现不是发送给本机的,则也调用数据报转发子模块来处理该数据报
  5. 数据报转发子模块首先检测系统是否允许转发,如果不允许,则将该数据报丢弃,如果允许,则将对数据报执行一些操作,然后将他交给ip数据报输出子模块.
  6. ip数据报应该发送至哪个下一跳路由由(或者目标机器),以及经过哪个网卡来发送,就是ip路由过程,即图中”计算吓一跳路由”子模块.IP模块实现数据报路由的核心数据结构是路由表.这个表按照数据报的目标ip地址分类,同一类型的ip数据报将被发往相同的下一跳路由器(或者目标机器)
  7. ip输出队列存放的是所有等待发送的ip数据报,其中除了需要转发的ip数据包外,还包括封装了本机上层数据(ICMP报文,TCP报文,UDP数据报)
  • 可通过route命令调整路由表.

路由机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# wsl2 下的路由表

Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default DESKTOP-0IUK3TJ 0.0.0.0 UG 0 0 0 eth0
172.30.208.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0

# 云上的路由表
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 0 0 0 eth0
link-local 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-7f2a81f4d920
172.21.0.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0

字段 含义
Destination 目标网路或者主机
Gateway 网关地址,*标识目标和本机在同一个网络,不需要路由
Genmask 网络掩码
Flags 路由标志项
Metric 路由距离,到达指定网络所需的中专数
Ref 路由被引用的次数,linux未使用
Use 该路由项被使用的次数
Iface 该路由项对应的输出网卡接口

补充:
路由标志项,常规有5种,更多见route命令的man手册

  • U:该路由项是活动的
  • H:该路由项是一台主机
  • G:该路由项的目标是网关
  • D:该路由项是重定向生成的
  • M:该路由项被重定向修改过

ip路由机制

  1. 查找路由表的种和数据报的目标ip地址完全匹配的主机IP地址.如果找到,就使用该路由项,没有则2步骤
  2. 查找路由表种和数据报的目标IP地址具有相同网络ID的网络IP地址,如果没找到,就步骤3
  3. 选择默认路由项,通常意味着数据报的下一跳路由是网关.

路由表的更新

通过route或者其他工具过呢更新,通常是静态路由更新方式,对于大型路由器,他们通常通过BGP(Border Gateway protocol,边际网关协议),RIP(Routing Information Protocol,路由信息协议),OSPF等协议来发现协议,并更新自己的路由表,这种更新是动态的,自动的.

ip转发

不是发送给本机的IP数据报将由数据报转发子模块来处理.路由器都能执行数据报的转发操作,而主机一般只发送和接收数据报,赭色hi因为主机上/proc/sys/net/ipv4/ip_forward呢和参数默认被设置为0.我们可以通过修改它来使用主机的数据报转发功能.

1
echo 1 > /proc/sys/net/ipv4/ip_forward

对于允许ip数据报转发的系统,数据报转发子模块将对期望转发的数据报执行如下操作:

  1. 检查数据报的TTL,如果为0,则丢弃数据报
  2. 检查数据包头部的严格源路径选择项,如果被设置,则检测数据报的目标IP地址是否是本机的某个ip地址.如果不是,则发送一个ICMP源站选路失败报文给发送端
  3. 如果有必要,则给源端发送一个ICMP重定向报文,告诉它下一个更合理的下一跳路由器.
  4. 将TTL值减1
  5. 处理IP头部选项
  6. 如果有必要,执行分片操作.

重定向

重定向报文格式:
image.png

ICMP报文头部3个固定字段:8位类型,8位代码和16位校验和.
ICMP重定向报文的类型值是5,代码字段有4个可选值,用来区分不同的重定向类型.本书中只讨论主机重定向,代码值位1.

ICMP重定向报文的数据部分含义很明确,它给接收方提供了如下两个信息:

  1. 引起重定向的ip数据报的源端ip地址(图中的原始IP数据报)
  2. 应该使用的路由器ip地址.

接收主机根据这两个信息就可以断定引起重定向的IP数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)
/proc/sys/net/ipv4/send_redirects内核参数指定是否允许发送ICMP重定向报文.
/proc/sys/net/ipv4/conf/all/accept_redirects内核参数指定是否允许接收ICMP重定向报文.一般来说,主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文.

ipv6头部结构

image.png

说明
4位版本号 指定ip协议,对ipv6来说,值为6
8位通信类型(traffice class) 指示数据流通信类型或者优先级,类似IPv4中TOS
20位流标签(flow label) IPv6新增加字段,用于某些对链接的服务质量有特殊要求的通信,如音频或者视频等实时数据传输
16位净荷长度(payload length) IPv6扩展头部和应用程序长度之和,不包括固定头部长度
8位下一个包头(netx header) 紧跟IPv6固定头部后的包头类型,如扩展头,或某个上层协议头(tcp,udp,icmp).类似IPv4投不中的协议字段,且相同的取值有相同意义
8位跳数限制(hop limit) 类似ipv4 TTL

IPv6用128位(16字节)标识ip地址,共可以表示2^128个地址.
32位标识的IPv4地址一般用点分10进制标识,而IPv6,用16进制字符串标识.使用:分割成8组,每组包含2字节.由于表示过于麻烦,通常用零压缩法来简写(省略连续的0,全0的组),...0000:0000:0000...可以简化为...::...,不过零压缩法只能用一次.

ipv6扩展头部

扩展头部 含义
Hop-by-Hop 逐跳选项头部,包含每个路由器都必须检查和处理的特殊参数选项
Destingation options 目的选项头部,指定由最终目的节点处理的选项
Routing 路由头部,指定数据报要经过哪些中转路由器,功能类似IPv4的松散源路由选择项和记录路由选项
Fragment 分片头部,处理分片和重组的细节
Authentication 认证头部,提供数据源认证,数据完整性检查和反重播保护
Encapsulating Security Payload 加密头部,提供加密服务
No next header 没有后续扩展头部

IPv6并不是Ipv4协议的简单扩展,而是完全独立的协议.用以太网帧封装的IPv6和IPv4数据报具有不同的类型之.IPv4的以太网帧封装类型是0x800,而IPv6的以太网帧封装类型是0x8dd

三十六计
tcp-ip协议族
  1. 1. 目录
  2. 2. ip服务特点
  3. 3. ipv4头部信息及释义
    1. 3.1. 抓包报文示例
  4. 4. ip分片
  5. 5. ip路由
    1. 5.1. ip模块工作流程
    2. 5.2. 路由机制
      1. 5.2.1. ip路由机制
    3. 5.3. 路由表的更新
  6. 6. ip转发
  7. 7. 重定向
  8. 8. ipv6头部结构
    1. 8.1. ipv6扩展头部
© 2023 haoxp
Hexo theme