IP首部校验和的算法

    IP/ICMP/IGMP/TCP/UDP/等协议的校验和算法是相同的,采用的都是将数据流视为16位整数流进行重复的叠加计算。

    计算校验和的步骤:

(1)把校验和字段置为0。

(2)对IP头部的每16bit进行二进制求和。

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

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

例如:

IP报头

45  00       00  31

89  F5      00  00

6E  06      00   00      //校验字段

DE B7      45   5D     //源IP地址

C0 A8       00   DC    //目的IP地址


根据如上的IP报头,可以求得校验和为:

4500+0031+89F5+0000+6E06+0000+DEB7+455D+C0A8+00DC = 322C4

由于计算的和为322C4的高16位不为0,所以将和的高16位和低16位进行反复的相加,直到和的高16位位0为止。

0003+22C4 = 22C7然后将结果进行取反操作~22C7 = DD38则DD38为最终的校验和。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IP数据报的校验和算法是一种很重要的数据包完整性校验手段,该算法IP数据的发送和接收过程中都得到广泛应用。 该算法的实现步骤如下: 1. 首先将整个IP数据包的首部按照16bit一组进行分组,不足16bit且不是末尾则在末尾添0 2. 将这些16bit的数字从第一个到最后一个相,得到一个数值 3. 以32为单将这个数值进行反码运算,得到的结果即为校验和 参考样例代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFERSIZE 32 /* * 计算IP数据包首部校验和 * @param buf 待计算数据包首部 "struct ipheader" 的指针 * @param len 数据包首部长度 (单:bytes) * return 计算得到的校验和 */ unsigned short checksum(unsigned short *buf, int len){ unsigned long sum = 0; while(len > 1){ sum += *buf++; len -= 2; } if(len){ sum += *(unsigned char*)buf; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (unsigned short)(~sum); } struct ipheader{ unsigned char ver_ihl; /* 版本 (4 bits) + 首部长度 (4 bits) */ unsigned char tos; /* 服务类型(Type of Service) */ unsigned short total_len; /* 总长(Total Length) */ unsigned short ident; /* 标识(Identification) */ unsigned short frag_and_flags; /* 标志(Flags) (3 bits) + 片偏移(Fragment offset) (13 bits) */ unsigned char ttl; /* 存活时间(Time to live) */ unsigned char protocol; /* 协议(Protocol) */ unsigned short checksum; /* 首部校验和(Header checksum) */ unsigned int sourceIP; /* 源IP地址(Source IP address) */ unsigned int destIP; /* 目的IP地址(Destination IP address) */ }; int main(){ unsigned char buffer[BUFFERSIZE]; memset(buffer,0,BUFFERSIZE); struct ipheader *ip = (struct ipheader*) buffer; ip->ver_ihl = 0x45; ip->tos = 0; ip->total_len = htons(sizeof(struct ipheader)); ip->ident = htons(54321); ip->frag_and_flags = 0; ip->ttl = 128; ip->protocol = 6; ip->checksum = 0; ip->sourceIP = inet_addr("192.168.1.101"); ip->destIP = inet_addr("192.168.1.1"); unsigned short check_sum = checksum((unsigned short*)ip,sizeof(struct ipheader)); printf("check sum=%d\n",check_sum); ip->checksum = check_sum; return 0; } 该程序首先定义了一个结构体ipheader,该结构体包含了一个完整的IP首部,然后通过调用checksum函数计算该IP数据包首部校验和。最后将计算得到的校验和存入IP首部中的checksum字段。运行该程序后即可得到IP数据包首部校验和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值