#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; /* 对首部按2字节进行累加 */ cksum = 0; …
时间: 2024-01-19 22:02:54 浏览: 108
lm3s6965_demo.rar_DEMO_LM3S6965_inc/hw_types.h
这段代码的功能是计算以太网帧中IP包头部的校验和。其中,eth是指向以太网帧的指针,通过将eth强制转换为EthPkt结构体指针,可以获取到IP包的指针。具体来说,该函数实现了以下功能:
1. 将IP头部按照2字节进行累加,并将结果存储在cksum变量中;
2. 如果累加的结果超过2字节,则将高16位与低16位相加,直到结果小于2字节;
3. 将累加结果按位取反,得到校验和的值。
可以参考下面的代码注释:
```
#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; // 将校验和的值以本地字节序返回
}
```
需要注意的是,这里只计算了IP头部的校验和,如果要计算整个IP数据报的校验和,则需要在IP头部中设置校验和字段为0,然后对整个IP数据报进行累加和计算,并将计算结果填充到校验和字段中。
阅读全文