gpt4 book ai didi

c - C语言中的TCP校验和

转载 作者:行者123 更新时间:2023-11-30 16:42:39 27 4
gpt4 key购买 nike

我一直在尝试用 C 计算 TCP header 的校验和。就我的目的而言,TCP header 有 20 个字节长,并且没有额外的数据或选项。另外,据我所知,TCP校验和的计算方式是报头中16位字的补码和的反码。因此,我编写了一个函数来计算TCP校验和,考虑到我上面说的条件。但是,当我在计算校验和后检查发送的数据包时,我得到:

1 0.000000   10.0.2.15 -> 127.0.0.1    TCP 74 24131->8000 [SYN] Seq=0 Win=13273 [TCP CHECKSUM INCORRECT] Len=20

我使用 tshark 检查了数据包。不过,我也用Wireshark检查了数据包,它也说了同样的事情。除了括号中的内容外,它说“可能是由 TCP 校验和卸载引起的?”我不太明白。

这是我用来计算校验和的代码:

unsigned short tcp_checksum(struct tcphdr* tcph,struct iphdr* iph)  {

/* Calculate TCP checksum */

struct pseudo_hdr* pseudo_hdr;
u_char* buffer;
u_char* segment;
u_char* pseudo_segment;
unsigned int count = 32;
unsigned long sum = 0;
unsigned short mask = 0xffff;
unsigned long long* hdr;

pseudo_hdr = malloc(sizeof(struct pseudo_hdr)); // allocate memory
buffer = malloc(32); // allocate for 32 bytes of information

if (pseudo_hdr == NULL || buffer == NULL) { // if memory wasn't allocated properly

err();
if (pseudo_hdr != NULL) free(pseudo_hdr);
if (buffer != NULL) free(buffer);
return 0;

}


pseudo_hdr->saddr = (unsigned long)iph->saddr; // we add the cast because the fields if of type u_int_32
pseudo_hdr->daddr = (unsigned long)iph->daddr; // same reason for adding the cast as above
bzero(&pseudo_hdr->reserved,sizeof(pseudo_hdr->reserved)); // zero header
pseudo_hdr->proto = IPPROTO_TCP; // this will always be 6
pseudo_hdr->len = htons(tcph->doff*4); // length of tcp header

/* Place both headers into a buffer */

segment = (u_char*)tcph;
pseudo_segment = (u_char*)pseudo_hdr;

/* Concactenate */

memcpy((char*)buffer,(char*)pseudo_segment,sizeof(struct pseudo_hdr)); // first the pseudo header
memcpy((char*)buffer+12,(char*)segment,sizeof(struct tcphdr)); // then the TCP segment

/* Calculate checksum just like IP checksum (RFC C implementation) */

hdr = (unsigned long long*)buffer;

while (count > 1) {

sum += *(unsigned short*)hdr++;
count -= 2;
}

// Add left over bytes, if any

if (count > 0) sum += * (u_char*) hdr;

// Fold 32-bit sum to 16 bits

while (sum>>16) sum = (sum & mask) + (sum >> 16);

sum = ~sum; // bitwise NOT operation

/* Discard headers and buffer */

free(buffer);
free(pseudo_hdr);

return sum;

}

struct iphdrstruct tcphdr定义于 <netinet/ip.h><netinet/tcp.h> 。这是我对 struct pseudo_hdr 的定义:

struct pseudo_hdr {

unsigned long saddr; // 4 bytes
unsigned long daddr; // 4 bytes
unsigned char reserved; // 1 byte
unsigned char proto; // 1 byte
unsigned short len; // 2 bytes

};

/* Total = 4+4+1+1+2 = 12 bytes */

正如我所说,出于我的目的,该函数计算 20 字节长的 TCP header 的校验和。

感谢您的帮助或建议。

最佳答案

@RonMaupin 关于查看 RFC 的建议以及其他人为进一步了解 TCP(以及一般的 C!)而做出的贡献帮助我解决了问题。谢谢!

关于c - C语言中的TCP校验和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45741827/

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