TCP校验和详细讲解和计算

TCP校验字段占两个字节如0x62,0x0d,实际上是这样计算来的:

对方IP+我方IP+报文长度+信息长度+0x06(协议类型)+
TCP各字段长度以及数据各字段和(注意此时将对应的校验和字段--TCP的第17,18位,实际对应数组下标的16,17位--都设为0x00.同时
每两个字节组合为一个数值如0x01,0x02组合为0x0102,数据abc对应为0x61,0x62,0x63,则组合成0x6162,0x6300)

上述算出来的校验和(设为resule)假如超过0xffff的话,将超过的部分添加到result的低位去再用0xffff减去该值,如:0x54321最终应成为:0xffff-(0x4321+0x05)

其次根据抓包工具抓住的TCP报文我们看到下列图片中已经有一个包含了双方IP,TCP报文以及信息的报文,根据图片中给出的信息,依照上述原理手动计算一个TCP校验和:






本地Ip:0xc0,0xa8,0x9f,0x01;
对方IP:0xc0,0xa8,0x9f,0x82
TCP字段:0x04, 0xc6, 0x87, 0x01, 0x4b, 0xd7, 0x89, 0x9f, 0x4e, 0x3b, 0x90, 0xae, 0x50, 0x18, 0xff, 0xff, 0xeb, 0x69, 0x00, 0x00
从上述实际报文可见该TCP的校验和为eb69
将对应的校验和字段设为0x00后TCP报文实际为:
0x04, 0xc6, 0x87, 0x01, 0x4b, 0xd7, 0x89, 0x9f, 0x4e, 0x3b, 0x90, 0xae, 0x50, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
数据字段abc,对应0x61,0x62,0x63;
TCP报文长度为20,信息长度为3,23化为16进制即0x17
所以result=(0xc0a8+0x9f01)+(0xc0a8+0x9f82)+(0x04c6+0x8701+0x4bd7+0x899f+0x4e3b+0x90ae+0x5018+0xffff+0x0000+0x0000)+(0x17+0x06)+(0x6162+0x6300)
得出result=0x7148f,将超出0xffff的位加到低位上去,reuslt=0xffff-(0x148f + 0x0007)=0xeb69正好和抓包工具显示的校验和字段是一样的.

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用C语言计算TCP校验和的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <netinet/tcp.h> unsigned short csum(unsigned short *buf, int nwords) { unsigned long sum; for (sum = 0; nwords > 0; nwords--) { sum += *buf++; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (unsigned short)(~sum); } int main() { char buf[1024]; struct tcphdr *tcp_header; unsigned short *ptr; int tcp_len; memset(buf, 0, sizeof(buf)); /* 构造TCP报文 */ tcp_header = (struct tcphdr*)(buf + sizeof(struct iphdr)); tcp_header->source = htons(12345); /* 源端口号 */ tcp_header->dest = htons(80); /* 目的端口号 */ tcp_header->seq = htonl(1); tcp_header->ack_seq = 0; tcp_header->doff = 5; /* TCP头长度 */ tcp_header->syn = 1; /* SYN标志位 */ tcp_header->window = htons(65535); tcp_header->check = 0; tcp_len = sizeof(struct tcphdr); ptr = (unsigned short*)buf; ptr[5] = htons(tcp_len >> 1); /* 计算TCP校验和 */ tcp_header->check = csum((unsigned short*)tcp_header, tcp_len >> 1); return 0; } ``` 在这个示例中,我们首先构造了一个TCP报文,并将它存储在一个缓冲区中。然后,我们调用`csum()`函数计算校验和,并将结果存储在TCP报文的校验和字段中。 我们使用了`struct tcphdr`结构体来构造TCP报文,该结构体定义在`netinet/tcp.h`头文件中。`htons()`和`htonl()`函数用于将主机字节序转换为网络字节序,`memset()`函数用于初始化缓冲区,`sizeof()`用于获取结构体大小。`ptr`指针用于访问缓冲区中的16位字。最后,我们将TCP头长度除以2,以便将16位字的数量作为参数传递给`csum()`函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值