#include "../network_protocol.h"/* 计算以太网帧中的IP包首部检验,以本地节顺序返回 */uint16 ipcksum(byte *eth) { uint16 *hptr; // 用于2字节指针转换 int32 i; // 用于循环计数 uint16 word; // 用于2字节的取舍 uint32 cksum=0; // 用于2字节的累加,辅助计算校验 hptr = (uint16 *) ((struct EthPkt*)eth)->data; // 获取IP头部指针 /* 对首部按2字节进行累加 */ cksum = 0; for (i = 0; i < 10; i++) { // 循环10次,每次累加2字节 word = *hptr++; // 获取2字节的值 cksum += word; // 将2字节的值累加到cksum中 if (cksum & 0xffff0000) { // 如果累加的结果超过2字节,则将高16位与低16位相加 cksum = (cksum & 0xffff) + (cksum >> 16); } } cksum = (cksum & 0xffff) + (cksum >> 16); // 将cksum的高16位与低16位相加 cksum = (cksum & 0xffff) + (cksum >> 16); // 将cksum的高16位与低16位相加 cksum = ~cksum; // 将累加结果按位取反,得到校验和的值 return (uint16)cksum; // 将校验和的值以本地字节序返回}
时间: 2024-01-30 10:01:55 浏览: 145
这段代码的作用是计算以太网帧中的IP包头部校验和,并返回计算结果。具体来说,该函数实现了以下功能:
1. 将IP头部按照2字节进行累加,并将结果存储在cksum变量中;
2. 如果累加的结果超过2字节,则将高16位与低16位相加,直到结果小于2字节;
3. 将累加结果按位取反,得到校验和的值。
值得注意的是,该函数只计算IP头部的校验和,如果要计算整个IP数据报的校验和,需要在IP头部中设置校验和字段为0,然后对整个IP数据报进行累加和计算,并将计算结果填充到校验和字段中。
具体代码注释如下:
```
#include "../network_protocol.h"
/* 计算以太网帧中的IP包首部检验,以本地节顺序返回 */
uint16 ipcksum(byte *eth) {
uint16 *hptr; // 用于2字节指针转换
int32 i; // 用于循环计数
uint16 word; // 用于2字节的取舍
uint32 cksum=0; // 用于2字节的累加,辅助计算校验
hptr = (uint16 *) ((struct EthPkt*)eth)->data; // 获取IP头部指针
/* 对首部按2字节进行累加 */
cksum = 0;
for (i = 0; i < 10; i++) { // 循环10次,每次累加2字节
word = *hptr++; // 获取2字节的值
cksum += word; // 将2字节的值累加到cksum中
if (cksum & 0xffff0000) { // 如果累加的结果超过2字节,则将高16位与低16位相加
cksum = (cksum & 0xffff) + (cksum >> 16);
}
}
cksum = (cksum & 0xffff) + (cksum >> 16); // 将cksum的高16位与低16位相加
cksum = (cksum & 0xffff) + (cksum >> 16); // 将cksum的高16位与低16位相加
cksum = ~cksum; // 将累加结果按位取反,得到校验和的值
return (uint16)cksum; // 将校验和的值以本地字节序返回
}
```
阅读全文