【问题标题】:TCP checksum incorrect for packets with payload带有有效负载的数据包的 TCP 校验和不正确
【发布时间】:2015-06-26 04:53:28
【问题描述】:

我正在用 C 语言开发一个 Ubuntu 机器。
校验和计算代码如下:

unsigned short csum(unsigned short *buf, int nwords)
{
  unsigned long sum;
  for(sum=0; nwords>0; nwords=nwords-2){
    sum += *buf;
    //printf("%04x\n", *buf);
    buf++;
  }
  if(nwords>0)
    sum += *buf++;
  while(sum >> 16)
    sum = (sum >> 16) + (sum &0xffff);
  /* sum += (sum >> 16);*/
  return (unsigned short)(~sum);
}

不过,这对于 IP 和 ICMP 段运行良好,所以我非常怀疑这是问题所在。
为了找出问题所在,我目前正在捕获随机数据包,构建 tcp 标头部分的伪标头 + 深拷贝,然后打印出原始校验和和计算出的校验和。

  struct tcphdr *tcph = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + iphdrlen);
  int tcphdrlen = size - sizeof(struct ethhdr) - iphdrlen;
  int pseudo_len = sizeof(iph->saddr) + sizeof(iph->daddr) + 1 + sizeof(iph->protocol) + 2 + tcphdrlen;
  test = (u_char *) malloc(pseudo_len);
  memset(test, 0, pseudo_len);
  memcpy(test, &(iph->saddr), sizeof(iph->saddr));
  int pos = sizeof(iph->saddr);
  memcpy(test + pos, &(iph->daddr), sizeof(iph->daddr));
  pos += sizeof(iph->daddr);
  memset(test + pos, 0, 1);
  pos += 1;
  memcpy(test + pos, &(iph->protocol), sizeof(iph->protocol));
  int tcphdrlenhtons = htons(tcphdrlen);
  pos += sizeof(iph->protocol);
  memcpy(test + pos, &tcphdrlenhtons, 2);
  pos += 2;
  memcpy(test + pos, tcph, tcphdrlen);

  struct tcphdr *t_tcph = (struct tcphdr *)(test + pos);
  memset(&(t_tcph->check), 0, sizeof(t_tcph->check));

  printf("correct tcp checksum: %d\n", ntohs(tcph->check));
  printf("my tcp checksum: %d\n", ntohs((unsigned short) csum((unsigned short *)test, pseudo_len)));

在测试中,我发现计算出的校验和是正确的,但前提是数据包没有负载。
如果有人能告诉我我可能做错了什么,我将不胜感激。

【问题讨论】:

  • 您可能在有效载荷校验和之前捕获数据包。将“TCP 校验和卸载”打入您最喜欢的搜索引擎。 (也可能是“TCP 分段卸载”。)
  • @David Schwartz 你是对的。谢谢。

标签: c tcp checksum


【解决方案1】:

这与其说是一个真正的答案,不如说是一个建议。您的测试代码有点难以理解。像test 这样的变量不会让其他人轻松阅读和理解代码。

尝试为伪标头创建一个实际的结构,并为 IPv4 地址之类的东西进行常规分配,而不是 memcpy。它们只有 4 个字节长,这将使您的代码更易于阅读。

这一行:

memset(test + pos, 0, 1);

有点困扰我,因为您设置为 0 的内容并不明显。我还想知道您是否将正确的字节数设置为 0。

我试图弄清楚您是否可能有字节序问题,但这很困难,因为我无法遵循您的测试代码。

【讨论】:

    【解决方案2】:

    正如 David Schwartz 所指出的,程序在计算校验和之前就捕获了数据包,从而使捕获的数据包的校验和不正确。该程序实际上给出了正确的校验和。

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 2020-10-01
      • 2011-04-28
      • 1970-01-01
      • 2011-05-17
      • 2018-08-17
      • 1970-01-01
      • 2019-01-30
      • 2015-08-26
      相关资源
      最近更新 更多