了解TCP校验和函数 [英] Understanding the TCP checksum function

查看:150
本文介绍了了解TCP校验和函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信TCP校验和函数执行以下操作:

I believe that the TCP checksum function does the following:


  1. 将伪标头和TCP段标头和数据分成2字节

  2. 如果长度不是2个字节,请将最后一个块的末尾添加一个0字节的填充字节,以使其成为2个字节。


听起来很简单。因此,我写了我自己的泛型校验和函数:

Sounds simple enough. Hence I wrote my own generic checksum function:

#include <inttypes.h>
#include <arpa/inet.h>

uint16_t checksum(uint16_t * data, int size) {
    uint16_t sum = 0;

    int i = 0, length = size / 2;

    while (i < length) sum += data[i++];

    if (size % 2) sum += data[i] & 0xFF00;

    return htons(~sum);
}

但是其他人写了校验和似乎更复杂的函数。例如:

However other people have written checksum functions which seem to be more complicated. For example:

uint16_t checksum(uint16_t * addr, int len) {
    int nleft = len;
    int sum = 0;

    uint16_t * w = addr;
    uint16_t answer = 0;

    while (nleft > 1) {
        sum += *w++;
        nleft -= sizeof(uint16_t);
    }

    if (nleft == 1) {
        *(uint8_t *) (&answer) = *(uint8_t *) w;
        sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    answer = ~sum;
    return (answer);
}

我对此代码有几个问题:

I have a few questions regarding this code:


  1. 语句 *(uint8_t *)(& answer)= *(uint8_t *)w; 实际上是什么?

  2. 为什么我们将总和视为:

  1. What does the statement *(uint8_t *) (&answer) = *(uint8_t *) w; actually do?
  2. Why do we take the sum as:

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);


  • 计算TCP校验和的方法是否改变?

  • Did the way to calculate the TCP checksum change?

    我真的不明白为什么我们做 sum =(sum>> 16)+(sum& 0xFFFF )。考虑 sum 0xABCD

    I really don't see why we do sum = (sum >> 16) + (sum & 0xFFFF). Consider sum is 0xABCD:

    0xABCD >> 16    == 0x0000
    
    0xABCD & 0xFFFF == 0xABCD
    
    0x0000 + 0xABCD == 0xABCD
    

    一个冗余步骤。对于下一语句 sum + =(sum>> 16)也是如此。

    It seems like a redundant step. Same goes for the next statement sum += (sum >> 16).

    推荐答案

    校验和函数仅适用于大端处理器。

    The checksum function appears to be for big-endian processors only.

    第一个while循环针对速度进行了优化。

    The first while loop is optimized for speed.

    & answer 特技将最后一个字节(如果有奇数个字节)类似于你的代码对 data [i]& data的操作,字节 answer 0xff00 。它的工作方式是这

    The &answer trick loads the last byte (if there were an odd number of bytes) into the high byte of answer, leaving the low byte zero, similar to what your code does with data[i] & 0xff00. The way it works is this

    1) take the address of answer      (&answer)
    2) convert that to a byte pointer  (uint8_t *)  
    2a) on a big endian processor the first byte of a 16-bit quantity is the high byte
    3) overwrite the high byte with the last byte of the data
    

    校验和应该计算与载入的加载。这里假设这个代码正在运行在 int 是32位的机器上。因此,(sum& 0xffff)是16位校验和,(sum>> 16)是需要加回的进位位(如果有的话)。因此,行

    The checksum is supposed to be computed with the carries added back in. It's assumed here that this code is running on a machine where an int is 32-bits. Therefore, (sum & 0xffff) is the 16-bit checksum, and (sum >> 16) are the carry bits (if any) that need to be added back in. Hence, the line

    sum = (sum >> 16) + (sum & 0xffff);
    

    调整总和以包括进位。然而,该行代码本身可以产生另一进位位。因此,下一行 sum + =(sum>> 16)将携带(如果有)返回到校验和。

    adjusts the sum to include the carries. However, that line of code could itself generate another carry bit. So the next line sum += (sum >> 16) adds that carry (if any) back into the checksum.

    最后,采取答案的补充。注意,不使用 htons ,因为整个函数隐含地假定它在大端处理器上运行。

    Finally, take the ones-complement of the answer. Note that htons is not used since the whole function implicitly assumes that it is running on a big endian processor.

    这篇关于了解TCP校验和函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆