IP首部校验和算法

IP首部校验和用于确保数据完整性的反码求和算法,不包括数据部分。计算分为填充、反码加法和取反三个步骤。在接收时,通过相同方式验证,若无误结果应为全1。
摘要由CSDN通过智能技术生成

一、校验和概念

  报头校验和(Header Checksum)是针对IP报头的纠错字段。校验和不计算被封装的数据,UDP、TCP和ICMP都有各自的校验和。报头校验和字段包含一个16位二进制补码和,这是由数据包发送者计算得到的。接受者将连同原始校验和重新进行16位二进制补码和的计算。如果数据包传输中没有发生错误,那么结果应该16位全部为1。

二、校验和算法

   IP校验和主要是用来保证数据(IP报头)的完整性的,就是反码求和校验。需要注意的是反码求和又叫1的补码,而2的补码就是我们通常说的补码求和了。校验算法具体如下。

1、发送方

  i)将校验和字段置为0,然后将IP报头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;

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、付费专栏及课程。

余额充值