IP 包头的 checksum 是如何计算的?

IP 包头的 checksum 是如何计算的?

 

struct HdrIp {
   byte: ihl_ver;      // IP header (RFC 791) - Internet Layer
                       // Combined field:
                      //   ihl:4 - IP header length divided by 4
                      //   version:4 - IP version
   byte: tos;         // IP type-of-service field
   word: tot_len;     // total length
   word: id;          // unique ID
   word: frag_off;    // Fragment Offset + fragmentation flags (3 bits)
   byte: ttl;         // time to live
   byte: protocol;     // protocol type
   word: checksum;    // IP header checksum
   InAddr : saddr;    // source IP
   InAddr : daddr;   // destination IP
};

这是一个IP包头格的说明. 里面有一个 checksum

RFC791 里是这样说的:

    The checksum algorithm is:
      The checksum field is the 16 bit one's complement of the one's
      complement sum of all 16 bit words in the header.  For purposes of
      computing the checksum, the value of the checksum field is zero.


说实话我没太看明白它的意思.大约是说这个 checksum 只是头格式的 checksum 不包括数据部份. 计算方式是把每个 字段补足16bit 来相加,计算前把 checksum 域计为 0.

但我抓了几个包来试,发现都得不到那个 checksum 呢? 是我没看明白,还是方法不正确? 哪个大侠给我说一下 这个 checksum 是如何计算出来的???

这是我抓的这几个包的包头.

第一个:

45                  // ihl_ver
00                  // tos
00 28               // tot_len
16 B9               // id
40 00               // frag_off
80                  // time to live
06                  // IP Protocel
61 8F               // checksum  这个是 checksum
C0 A8 00 D1         // saddr
C0 A8 00 66         // daddr  

这是第二个:

45                    // ihl_ver
00                    // tos
00 28                 // tot_len
5B CC                 // id
40 00                 // frag off
80                    // time to live   
06                    // tcp ,udp
1C 7C                 // checksum
C0 A8 00 66           // saddr
C0 A8 00 D1           // daddr

第三个
45                  // ihl_ver
00                  // tos
00 30               // tot-len   // 48 byte , 总长度 - mac 头
16 BA               // id
40 00               // frag off   
80                  // time to live
06                  // tcp udp
61 86               // check sum
C0 A8 00 D1         // saddr
C0 A8 00 66         // daddr

总之我一连计算了几个. 用不同的计算方法都得不到这个 checksum. 这个 checksum 是如何计算的?

 

 



### Checksum 计算方法概述 Checksum 是一种用于验证数据完整性的机制,广泛应用于通信协议、文件传输以及网络层的数据包校验。以下是几种常见的 checksum 计算方法及其具体实现。 #### 方法一:基于位操作的 XBR Message Checksum XBR Message Checksum计算方式较为特殊,主要通过位移和逻辑与运算完成。其核心公式如下: \[ \text{XBR Message Checksum} = ((\text{Checksum} >> 4) + \text{Checksum}) & 0x0F \] 此过程分为以下几个部分: 1. 将原始 `Checksum` 右移 4 位。 2. 将右移后的结果加上原值。 3. 对最终结果保留低 8 位,并与 `0x0F` 进行按位与运算。 例如,假设初始 `Checksum` 值为 `0110 0101 1110 (十六进制表示为 0x65E)`,则计算流程如下: - \( (\text{Checksum} >> 4) = 0000 0110 0101 \) - 加法结果:\( 0000 0110 0101 + 0110 0101 1110 = 0110 1100 0101 \) - 舍弃高位后得到:\( 0101 1110 \) - 按位与运算:\( 0101 1110 & 0x0F = 0000 1110 \) 因此,最终结果为 `0xE`[^1]。 --- #### 方法二:累加型 Checksum 实现 另一种常见的方式是对输入数据进行逐字节累加并返回最终结果。以下是一个 C 风格的函数实现: ```c uint8_t receive_CheckSum(uint8_t *data, uint8_t len) { uint8_t i, crc = 0; for (i = 0; i < len; i++) { crc += *(data++); } return (crc + 1); } ``` 该算法的核心在于遍历整个数据缓冲区并对每个字节执行累加操作。最后一步 `(crc + 1)` 表明这是一个简单的修正步骤,可能为了兼容特定的应用场景[^2]。 --- #### 方法三:IP 数据报头部校验和 在网络编程领域,尤其是 IP 协议栈中,checksum 主要用于检测数据包头的完整性。其标准定义如下: 1. 将 IP 头部分割成多个 16 位字段。 2. 对这些字段逐一求和(忽略溢出的部分)。 3. 如果存在溢出,则将溢出部分重新加入到总和中。 4. 最终结果取反码作为校验和。 Java 中的一种典型实现可以参考以下代码片段: ```java public static short calculateIpHeaderChecksum(byte[] header) { int sum = 0; // 将每两个字节视为一个短整数 for (int i = 0; i < header.length - 1; i += 2) { int w = ((header[i] & 0xFF) << 8) | (header[i + 1] & 0xFF); sum += w; // 处理溢出情况 while ((sum & 0xFFFF0000) != 0) { sum = (sum & 0xFFFF) + (sum >>> 16); } } // 返回补码形式的校验和 return (short) (~sum); } ``` 需要注意的是,在实际应用中可能会遇到奇数长度的情况,此时最后一个字节应被填充为零后再参与计算[^3]。 --- ### 总结 以上介绍了三种不同的 checksum 计算方法,分别适用于不同场景下的需求。无论是基础的位操作还是复杂的网络协议支持,都体现了 checksum 在现代计算机科学中的重要地位。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值