校验和覆盖的内容

IP校验和:IP首部。

ICMP校验和:ICMP首部+ICMP数据;

UDP、TCP校验和:首部+数据+12个字节伪首部(源IP地址、目的IP地址、协议、TCP/UDP包长)。

计算步骤

[1]把校验和字段设置为0。

[2]把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和。

[3]把得到的结果存入校验和字段中。

另外UDP、TCP数据报的长度可以为奇数字节,因为计算时是16位为单位,所以此时计算校验和时需要在最后增加一个填充字节0(只是计算校验和用,不发送出去)。

接收端校验校验和计算

把需要校验的内容(包括校验和字段)看成以16位为单位的数字,依次进行二进制反码求和,如果结果是0表示正确,否则表示错误

二进制反码求和

[1]二进制反码求和,就是先把这两个数取反,然后求和,如果最高位有进位,则向低位进1。

[2]先取反后相加与先相加后取反,得到的结果是一样的。因此实现代码都是先相加,最后再取反。

代码

// chksum  没有做字节序转换
uint16_t my_chksum(uint16_t *data, int len) {
    int result = 0;
    while(len > 1){
        result += *data;
        data++;
        len -= 2;
    }
    if ( len ){
        result += *((uint8_t *)data);
    }
    while(result >> 16) result = (result&0xffff) + (result>>16);
    return ~result;
}
文档更新时间: 2021-01-28 19:56   作者:周国强