IP协议介绍

IP头

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

版本号(Version):长度4比特。标识目前采用的IP协议的版本号。一般的值为0100(IPv4),0110(IPv6)
IP包头长度(Header Length):长度4比特。这个字段的作用是为了描述IP包头的长度,因为在IP包头中有变长的可选部分。该部分占4个bit位,单位为32bit(4个字节),即本区域值= IP头部长度(单位为bit)/(8X4),因此,一个IP包头的长度最长为“1111”,即15X4=60个字节。IP包头最小长度为20字节。
服务类型(Type of Service):长度8比特。8位 按位被如下定义 PPP DTRC0
PPP:定义包的优先级,取值越大数据越重要
000 普通 (Routine)
001 优先的 (Priority)
010 立即的发送 (Immediate)
011 闪电式的 (Flash)
100 比闪电还闪电式的 (Flash Override)
101 CRI/TIC/ECP(找不到这个词的翻译)
110 网间控制 (Internetwork Control)
111 网络控制 (Network Control)

D 时延: 0:普通 1:延迟尽量小
T 吞吐量: 0:普通 1:流量尽量大
R 可靠性: 0:普通 1:可靠性尽量大
M 传输成本: 0:普通 1:成本尽量小
0 最后一位被保留,恒定为0
IP包总长(Total Length):长度16比特。 以字节为单位计算的IP包的长度 (包括头部和数据),所以IP包最大长度65535字节。
标识符(Identifier):长度16比特。该字段和Flags和Fragment Offest字段联合使用,对较大的上层数据包进行分段(fragment)操作。路由器将一个包拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。
标记(Flags):长度3比特。该字段第一位不使用。第二位是DF(Don’t Fragment)位,DF位设为1时表明路由器不能对该上层数据包分段。如果一个上层数据包无法在不分段的情况下进行转发,则路由器会丢弃该上层数据包并返回一个错误信息。第三位是MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的IP包的包头中将MF位设为1。
片偏移(Fragment Offset):长度13比特。表示该IP包在该组分片包中位置,接收端靠此来组装还原IP包。
生存时间(TTL):长度8比特。当IP包进行传送时,先会对该字段赋予某个特定的值。当IP包经过每一个沿途的路由器的时候,每个沿途的路由器会将IP包的TTL值减少1。如果TTL减少为0,则该IP包会被丢弃。这个字段可以防止由于路由环路而导致IP包在网络中不停被转发。
协议(Protocol):长度8比特。标识了上层所使用的协议。
头部校验(Header Checksum):长度16位。用来做IP头部的正确性检测,但不包含数据部分。 因为每个路由器要改变TTL的值,所以路由器会为每个通过的数据包重新计算这个值。
起源和目标地址(Source and Destination Addresses):这两个地段都是32比特。标识了这个IP包的起源和目标地址。要注意除非使用NAT,否则整个传输的过程中,这两个地址不会改变。

至此,IP包头基本的20字节已介绍完毕,此后部分属于可选项,不是必须的部分。
可选项(Options):这是一个可变长的字段。该字段属于可选项,主要用于测试,由起源设备根据需要改写。可选项目包含以下内容:
松散源路由(Loose source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,但是允许在相继的两个IP地址之间跳过多个路由器。
严格源路由(Strict source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,如果下一跳不在IP地址表中则表示发生错误。
路由记录(Record route):当IP包离开每个路由器的时候记录路由器的出站接口的IP地址。
时间戳(Timestamps):当IP包离开每个路由器的时候记录时间。
填充(Padding):因为IP包头长度(Header Length)部分的单位为32bit,所以IP包头的长度必须为32bit的整数倍。因此,在可选项后面,IP协议会填充若干个0,以达到32bit的整数倍。

typedef struct _iphdr //定义IP首部
{
  unsigned char h_lenver; //4位首部长度+4位IP版本号
  unsigned char tos; //8位服务类型TOS
  unsigned short total_len; //16位总长度(字节)
  unsigned short ident; //16位标识
  unsigned short frag_and_flags; //3位标志位
  unsigned char ttl; //8位生存时间 TTL
  unsigned char proto; //8位协议 (TCP, UDP 或其他)
  unsigned short checksum; //16位IP首部校验和
  unsigned int sourceIP; //32位源IP地址
  unsigned int destIP; //32位目的IP地址
}IP_HEADER;

分片

分片和重组装的过程对传输层是透明的,其原因是当IP数据报进行分片之后,只有当它到达下一站时,才可进行重新组装,且它是由目的端的IP层来完成的。
IP首部包含了分片和重组所需的信息:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |R|D|M|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ldentification:(16位):发送端发送的IP数据包标识字段都是一个单一值,该值在分片时被复制到每个片中。(具有同一个ID的IP分片将会重新组装)
R:保留未用
DF:“不分片”位,如果将这一比特置1,IP层将不对数据进行分片(DF和MF合起来为3位)
MF:“更多的片”,除了最后一片外,其它每个组成数据报的片都要把该比特置1.
Fragment Offset(13位):该片偏移原始数据包开始处的位置。偏移的字节数是该值乘以8.

当数据报被分片后,每个片的总长度值要改为该片的长度值.
一个未分片的数据报的分片信息字段全为0,即多个分片标志位为0.
某些分片风暴攻击的原理:故意发送部分IP分片而不是全部,则会导致目标主机总是等待分片消耗并占用系统资源.

分片步骤:
(1) 检查DF标志位,查明是否允许分片,如果DF=1,则将该数据报丢弃,并将一个ICMP错误返回给源端。
(2) 基于MTU值,把数据字段分成两个部分或者多个部分。除了最后的数据部分外,所有新建数据选项的长度必须为8的倍数。
(3) 每个数据部分被放入一个IP数据报,这些数据报的报文头略微修改了原来的报文头。除了最后的数据报分片外,所有分片都设置了多个分片(MF)标志位。
每个分片中的片偏移量字段设为这个数据部分在原来数据报中的偏移量。
(4) 设置新数据报的报文头字段及总长度字段。
(5) 重新计算报文头部校验和字段。

重组

重组的前提是接收到所有的分片。内核判断一个队列是否接收到了所有分片需要满足三个条件:
a)INET_FRAG_FIRST_IN  - 在接收到OFFSET为0值的数据包时设置此标志;
b)INET_FRAG_LAST_IN   - 接收到IP报头中More Fragmentation(IP_MF)标志等于0的分片时,设置此标志位;
c)inet_frag_queue中meat等于len - meat在每次成功插入一个分片后增加此分片的长度值,len值由最后一个分片的OFFSET值加上其长度获得。
重组的时候先是为每一个分组开辟内存空间,然后根据片偏移量依次将接收到的数据分片存放在相应的偏移位置,当接收完一个完整的数据报的时候首尾之间的内存肯定会被填满。
重组定时器:
在接收到第一个数据包分片,创建分片队列后,内核随即启动超时计时器,超时时间从网络命名空间结构中获取(timeout), 默认情况下超时时间为30秒钟(IP_FRAG_TIME)。
超时定时器在到期之后,使用ip_expire函数释放分片队列(ipq_put)。如果本机就是这些分片报文的目的主机,回复ICMP的分片重组超时消息(type=ICMP_TIME_EXCEEDED(11), code=ICMP_EXC_FRAGTIME(1))。

分片机制有一定的缺陷:分片越多,分片丢失的机率就越大,对于一个数据报,一旦一个分片丢失,那么整个数据报就要重传;每一个数据报都要复制报头(只复制ip包头),这在一定程度上增加了带宽消耗。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值