IP包的校验和

IP头结构

 

IPv4首部一般是20字节长。在以太网帧中,IPv4包首部紧跟着以太网帧首部,同时以太网帧首部中的协议类型值设置为0800 16 。 IPv4提供不同,大部分是很少用的选项,使得IPv4包首部最长可扩展到60字节(总是4个字节4个字节的扩展)
0481216192431
版本首部长度服务类型长度
认证标志段偏移量
TTL协议校验和
源IP地址
目的IP地址
选项 ...

 

IP包头字段说明

版本:4位,指定IP协议的版本号。

包头长度(IHL):4位,IP协议包头的长度,指明IPv4协议包头长度的字节数包含多少个32位。由于IPv4的包头可能包含可变数量的可选 项,所以这个字段可以用来确定IPv4数据报中数据部分的偏移位置。IPv4包头的最小长度是20个字节,因此IHL这个字段的最小值用十进制表示就是5 (5x4 = 20字节)。就是说,它表示的是包头的总字节数是4字节的倍数。

服务类型:定义IP协议包的处理方法,它包含如下子字段

        过程字段:3位,设置了数据包的重要性,取值越大数据越重要,取值范围为:0(正常)~ 7(网络控制)

        延迟字段:1位,取值:0(正常)、1(期特低的延迟)

        流量字段:1位,取值:0(正常)、1(期特高的流量)

        可靠性字段:1位,取值:0(正常)、1(期特高的可靠性)

        成本字段:1位,取值:0(正常)、1(期特最小成本)

        未使用:1位

长度:IP包的总长

认证:

标志:是一个3位的控制字段,包含:

        保留位:1位

        不分段位:1位,取值:0(允许数据报分段)、1(数据报不能分段)

        更多段位:1位,取值:0(数据包后面没有包,该包为最后的包)、1(数据包后面有更多的包)


段偏移量:当数据分组时,它和更多段位(MF, More fragments)进行连接,帮助目的主机将分段的包组合。

TTL:表示数据包在网络上生存多久,每通过一个路由器该值减一,为0时将被路由器丢弃。

协议:8位,这个字段定义了IP数据报的数据部分使用的协议类型。常用的协议及其十进制数值包括ICMP(1)、TCP(6)、UDP(17)。

校验和:16位,是IPv4数据报包头的校验和。

源IP地址:

目的IP地址:

 

ip 包的校验和

 

当发送 IP 包时,需要计算 IP 报头的校验和:

1    把校验和字段置为 0

2    IP 头部中的每 16bit 进行二进制求和;

3    如果和的高 16bit 不为 0 ,则将和的高 16bit 和低 16bit 反复相加,直到和的高 16bit 0 ,从而获得一个 16bit 的值;

4    将该 16bit 的值取反,存入校验和字段。

当接收 IP 包时,需要对报头进行确认,检查 IP 头是否有误,算法同上 2 3 步,然后判断取反的结果是否为 0 ,是则正确,否则有错。

  

算法:

SHORT checksum(USHORT* buffer, int size)

{

unsigned long cksum = 0;

while(size>1)

{

     cksum += *buffer++;

     size -= sizeof(USHORT);

}

if(size)

{

     cksum += *(UCHAR*)buffer;

}

cksum = (cksum>>16) + (cksum&0xffff);   // 将高 16bit 与低 16bit 相加

cksum += (cksum>>16);              // 将进位到高位的 16bit 与低 16bit 再相加

  

return (USHORT)(~cksum);

}

  

实例:

IP 头:   

               45 00     00 31

               89 F5     00 00

               6E 06     00 00 (校验字段)

               DE B7    45 5D        ->     222.183.69.93

               C0 A8    00 DC      ->     192.168.0.220

计算:     

     4500 + 0031 +89F5 + 0000 + 6e06+ 0000 + DEB7 + 455D + C0A8 + 00DC =3 22C4

     0003 + 22C4 = 22C7

      ~22C7 = DD38       -> 即为应填充的校验和

当接受到 IP 数据包时,要检查 IP 头是否正确,则对 IP 头进行检验,方法同上:

计算:

     4500 + 0031 +89F5 + 0000 + 6E06+ DD38 + DEB7 + 455D + C0A8 + 00DC =3 FFFC

     0003 + FFFC = FFFF

      ~FFFF = 00000      -> 正确

TCP 首部检验和与 IP 首部校验和的计算方法相同,在程序中使用同一个函数来计算。

需要注意的是,由于 TCP 首部中不包含源地址与目标地址等信息,为了保证 TCP 校验的有效性,在进行 TCP 校验和的计算时,需要增加一个 TCP 伪首部的校验和,定义如下:

struct

{

unsigned long saddr; // 源地址

unsigned long daddr; // 目的地址

char mbz;// 置空

char ptcl; // 协议类型

unsigned short tcpl; //TCP 长度

}psd_header;

然后我们将这两个字段复制到同一个缓冲区 SendBuf 中并计算 TCP 校验和:

memcpy(SendBuf,&psd_header,sizeof(psd_header));

memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));

tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值