目录
ip服务特点
ip协议是tcp/ip协议族的动力,为上层协议提供无状态,无连接,不可靠服务
ip通信双方不同步传输数据的状态信息,因此所有的ip数据报的发送,传输,接收都是相互独立,没有上下文的关系.
这种服务的缺点是无法处理乱序数据和重复的ip数据报.接收端的ip模块只要接收到了完整的ip数据报(如果ip分片,ip模块无法将其先行重组),就将其数据部分(tcp报文段,udp报文段,或者icmp报文)交给上层协议.
ip虽然在数据报头部提供了一个标识字段用以唯一标识一个IP数据报,但它是被用来处理ip分片和重组的,不是用来指接收顺序.
无状态服务的优点也很明显:简单高效.
无连接(connectionless)指ip通信双方都不长久维持对方信息.这样上层协议每次发送数据的时候,都必须明确指明对方的ip地址.
不可靠指的是ip协议不能保证ip数据报准确地到达接收端.使用ip服务的上层协议需要自己实现数据确认,超时重传等机制
ipv4头部信息及释义
字段说明 | |
---|---|
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字节固定). |
补充:
可选字段的选项内容:
- 记录路由(record route),告诉数据报途径的所有路由器都将自己ip地址填入ip头部的选项部分,可以跟踪数据报的传递路径
- 时间戳(timestamp),告诉每个路由器将数据报被转发的时间(或时间与ip地址对应),填入ip头部的选项部分,这样我们就可以跟踪数据报的传递路径.
- 松散源路由器选择(loose source routing),指定一个路由器ip地址列表,数据包发送过程,必须经过其中所有的路由器.
- 严格源路由器选择(strict source routing),和松散源路由器,数据报只能经过被指定的路由器
使用3,4的大概仅有trace route程序,此外作为记录路由ip选项的替代品,traceroute程序使用UDP报文和ICMP报文实现了更可靠的记录路由功能
MTU(Max Transmit Unit,帧最大传输单元),以太网帧的MTU是1500字节
抓包报文示例
1 | 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 |
本次为本机操作,使用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模块工作流程
从右向左分析
- ip模块收到数据链路层的数据后,先对数据报的头部做CRC校验,确认无误之后分析头部的具体信息.
- 如果该IP数据报的头部设置了原站选路选项(松散源或者严格源路由选择),则ip模块调用数据报转发子模块来处理该数据报.
- 如果该数据报头部信息中的目标地址是本机的某个ip地址,或者广播地址,即该数据报是发送给本机的,则ip模块就根据数据包中的协议字段来决定将它派发给上层应用.
- 如果ip模块发现不是发送给本机的,则也调用数据报转发子模块来处理该数据报
- 数据报转发子模块首先检测系统是否允许转发,如果不允许,则将该数据报丢弃,如果允许,则将对数据报执行一些操作,然后将他交给ip数据报输出子模块.
- ip数据报应该发送至哪个下一跳路由由(或者目标机器),以及经过哪个网卡来发送,就是ip路由过程,即图中”计算吓一跳路由”子模块.IP模块实现数据报路由的核心数据结构是路由表.这个表按照数据报的目标ip地址分类,同一类型的ip数据报将被发往相同的下一跳路由器(或者目标机器)
- ip输出队列存放的是所有等待发送的ip数据报,其中除了需要转发的ip数据包外,还包括封装了本机上层数据(ICMP报文,TCP报文,UDP数据报)
- 可通过route命令调整路由表.
路由机制
1 | # wsl2 下的路由表 |
字段 | 含义 |
---|---|
Destination | 目标网路或者主机 |
Gateway | 网关地址,*标识目标和本机在同一个网络,不需要路由 |
Genmask | 网络掩码 |
Flags | 路由标志项 |
Metric | 路由距离,到达指定网络所需的中专数 |
Ref | 路由被引用的次数,linux未使用 |
Use | 该路由项被使用的次数 |
Iface | 该路由项对应的输出网卡接口 |
补充:
路由标志项,常规有5种,更多见route命令的man手册
- U:该路由项是活动的
- H:该路由项是一台主机
- G:该路由项的目标是网关
- D:该路由项是重定向生成的
- M:该路由项被重定向修改过
ip路由机制
- 查找路由表的种和数据报的目标ip地址完全匹配的主机IP地址.如果找到,就使用该路由项,没有则2步骤
- 查找路由表种和数据报的目标IP地址具有相同网络ID的网络IP地址,如果没找到,就步骤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数据报转发的系统,数据报转发子模块将对期望转发的数据报执行如下操作:
- 检查数据报的TTL,如果为0,则丢弃数据报
- 检查数据包头部的严格源路径选择项,如果被设置,则检测数据报的目标IP地址是否是本机的某个ip地址.如果不是,则发送一个ICMP源站选路失败报文给发送端
- 如果有必要,则给源端发送一个ICMP重定向报文,告诉它下一个更合理的下一跳路由器.
- 将TTL值减1
- 处理IP头部选项
- 如果有必要,执行分片操作.
重定向
重定向报文格式:
ICMP报文头部3个固定字段:8位类型,8位代码和16位校验和.
ICMP重定向报文的类型值是5,代码字段有4个可选值,用来区分不同的重定向类型.本书中只讨论主机重定向,代码值位1.
ICMP重定向报文的数据部分含义很明确,它给接收方提供了如下两个信息:
- 引起重定向的ip数据报的源端ip地址(图中的原始IP数据报)
- 应该使用的路由器ip地址.
接收主机根据这两个信息就可以断定引起重定向的IP数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)/proc/sys/net/ipv4/send_redirects
内核参数指定是否允许发送ICMP重定向报文./proc/sys/net/ipv4/conf/all/accept_redirects
内核参数指定是否允许接收ICMP重定向报文.一般来说,主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文.
ipv6头部结构
说明 | |
---|---|
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