了解TCP校验功能 [英] Understanding the TCP checksum function

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

问题描述

我相信,TCP校验功能执行以下操作:

I believe that the TCP checksum function does the following:

  1. 分手的伪首和TCP分段报头和数据为2字节的块。
  2. 添加0的一个字节填充到最后一个块结束时,如果它不是2个字节,使其2个字节。
  3. 取之和的1的补数来获得TCP校验。

听起来很简单。因此,我写我自己的泛型校验功能:

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);
}

我有一个关于这个code几个问题:

I have a few questions regarding this code:

  1. 什么语句 *(uint8_t有*)(安培;回答)= *(uint8_t有*)瓦;?实际上做
  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?

    我真的不明白为什么我们做和=(总和&GT;&GT; 16)+(总和与放大器; 0xFFFF的)。考虑为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
    

    这似乎是一个多余的步骤。这同样适用于下一条语句之和+ =(总和&GT;&GT; 16)。

    推荐答案

    出现校验功能是只大端处理器。

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

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

    The first while loop is optimized for speed.

    &放大器;答案招加载的最后一个字节(如果有字节数为奇数)到答案的高字节,留下低字节为零,类似于您code确实与数据[1] - 放什么;为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
    

    校验应该与携带添加回计算。它这里假设这个code是一台机器,一个 INT 是上运行32位位。因此,(总和&安培; 0xFFFF的)是16位校验和(总和&GT;&GT; 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);
    

    调整总和包括携带。不过,该行的code本身可能产生的另一个进位。因此,下一行之和+ =(总和&GT;&GT; 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天全站免登陆