gpt4 book ai didi

c - 即使我在计算之前已经将校验和设置为 0,TCP 校验和计算也会返回 0

转载 作者:可可西里 更新时间:2023-11-01 02:34:14 26 4
gpt4 key购买 nike

我正在编写一个简单的程序来发送/接收 TCP 数据包。我在计算 TCP 数据包的校验和时遇到了困难。

对于校验和函数,我重新使用了如下代码:

static int
in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;

/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}

/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);

我收到一个数据包并存储在 char buffer[2048] 中。为了获得 IP header ,我这样做:

struct iphdr* ip;
ip = (struct iphdr*) buffer;

下面是我如何获取 tcp header :

tcp=(struct tcphdr*) (buffer+(4*ip->ihl));

这是我的伪 TCP 结构

struct tcp_pseudohdr{
uint32_t tcp_ip_src, tcp_ip_dst;
uint8_t tcp_reserved;
uint8_t tcp_ip_protocol;
uint16_t tcp_length;
struct tcphdr tcp_hdr;
}
struct tcp_pseudohdr pseudo_tcp;
memset(&pseudo_tcp,0,sizeof(struct tcp_pseudohdr));

然后我填充 TCP 伪结构并计算 tcp 校验和如下:

pseudo_tcp.tcp_ip_src = ip->saddr;
pseudo_tcp.tcp_ip_dst = ip->daddr;
pseudo_tcp.tcp_ip_protocol = ip->protocol;
pseudo_tcp.tcp_reserved = 0;
pseudo_tco.tcp_length = htons(ntohs(ip->tot_length)-(4*ip->ihl));
memcpy(&pseudo_tcp,tcp,ntohs(ip->tot_length)-(4*ip->ihl));

在此之后,我能够正确准备好 pseudo_tcp.tcp_hdr.source、pseudo_tcp.tcp_hdr.check 等中的信息。

然后我最终计算校验和如下:

tcp->check=0;
tcp->check=in_cksum((unsigned short*)&pseudo_tcp, ntohs(ip->tot_length)-(4*ip->ihl)+12);

这个函数 ntohs(tcp->check) = 0 的输出。我觉得我真的很接近,但可能会遗漏一些东西。通常,当我在计算之前没有设置校验和= 0时,cksum函数返回0。但是,在这种情况下,我做了但不确定发生了什么。

我注意到的一件事是 struct tcphdr 的大小 = 20,但是当我 memcpy 时,这个 ntohs(ip->tot_length)-(4*ip->ihl) = 40 因为它包含选项。不知道是这导致了问题还是存在其他问题。

如有任何帮助,我们将不胜感激。提前致谢!

最佳答案

设置 tcp->check = 0 不会执行任何操作,因为您正在校验 pseudo_tcp,它是 tcp 的副本。在将 tcp 复制到 pseudo_tcp 之前设置 tcp->check = 0,或者将 pseudo_tcp 中的校验和设置为 0。

关于c - 即使我在计算之前已经将校验和设置为 0,TCP 校验和计算也会返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26860245/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com