华为网络基础 | TCP校验和算法实例抓包验证

  • 内容
  • 相关

前几篇已经讲解了TCP保证可靠性中的,序列号(按序到达)确认应答机制,为了讲解TCP校验和又把IP包的校验和讲了,今天这篇博文就该讲讲TCP的校验和了,后续也通过实例抓包进行实际验证。

关于TCP头部结构及字段说明,在之前的华为网络基础 | TCP头部封装篇章已将将结果了,这儿不再过多赘述,具体的知识点请点击超链接查看学习。

这次的重点将是TCP校验和(Checksum)的原理和抓包实际验证

一、TCP校验和概述

TCP校验和(Checksum)是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。

TCP校验和覆盖TCP首部和TCP数据,而IP首部中的校验和只覆盖IP的首部,不覆盖IP数据报中的任何数据。TCP校验和、IP校验和的计算方法是基本一致的,除了计算的范围不同

TCP的校验和是必需的,而UDP的校验和是可选的。TCPUDP计算校验和时,都要加上一个12字节的伪首部。

二、伪首部的概念

伪首部的数据都是从IP数据报头获取的。其目的是让TCP检查数据是否已经正确到达目的地,只是单纯为了做校验用的,如下图所示。

伪首部结构体如下:

struct
{
unsigned long saddr;      //源地址
unsigned long daddr;     //目的地址
char mbz;                        //强制置空
char ptcl;                         //协议类型
unsigned short tcpl;        //TCP长度
}psd_header;

伪首部共有12字节(前96Bits),包含如下信息:源IP地址、目的IP地址、保留字节(0)、传输层协议号(TCP6)TCP报文长度(报头+数据)

伪首部是为了增加TCP校验和的检错能力,如检查TCP报文是否收错了(目的IP地址)、传输层协议是否选对了(传输层协议号)等。

三、TCP校验和定义

先来看看RFC793TCP校验和的定义:

The checksum field is the 16 bit one’s complement of the one’s complement sum of all 16-bit words in the header and text. If a segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a 16-bit word for checksum purposes. The pad is not transmitted as part of the segment. While computing the checksum, the checksum field itself is replaced with zeros.

好吧,还是翻译成汉语……

1、把伪首部、TCP报头、TCP数据分为16位的字段,如果总长度为奇数个字节,则在最后增添一个位都为0的字节(切记切记!!)。把TCP报头中的校验和字段置为0(否则就陷入鸡生蛋还是蛋生鸡的问题);

2、用反码相加法累加所有的16位字(进位也要累加);

3、对计算结果取反,作为TCP的校验和。

四、算法

下面为C实现较为原始的checksum算法,代码中对于算法做了比较详细的注释:

unsigned short checksum(unsigned short * addr, int count)
{
long sum = 0;
/*计算所有数据的16bit对之和*/
   while( count > 1  )  {
       /*  This is the inner loop */
       sum += *(unsigned short*)addr++;
       count -= 2
   }  
/*如果数据长度为奇数,在该字节之后补一个字节(0),然后将其转换为16bit整数,加到上面计算的校验和中。*/
   if( count > 0 ) {
       char left_over[2] = {0};
       left_over[0] = *addr;
       sum += * (unsigned short*) left_over;
   }
/*将32bit数据压缩成16bit数据,即将进位加大校验和  的低字节上,直到没有进位为止。*/
   while (sum>>16)
       sum = (sum & 0xffff) + (sum >> 16);  
 /*返回校验和的反码*/
  return ~sum;
}

哎呀!!算法又见算法,不好理解!好吧,下面还是通过实际抓包进行验证。还是那句话,认真看、做笔记!!

五、实例验证

从下图的WireShark抓包分析可以得出伪头部和TCP报文的一些信息

管理员设置 回复 可见隐藏内容

辛辛苦苦大半天,最终终于把校验和算出来了,AF7884c6 !!!!!!!!

纳尼,纳尼,纳尼,纳尼,纳尼,纳尼,纳尼,纳尼!!!!开始怀疑人生,我们是按照计算过程一步步做的,中间没有数据计算错误的,之前计算IP包的校验和却是可以的,现在计算TCP校验和居然是错的!!

小伙别慌,且等下篇博文分解!!!

 您阅读这篇文章共花了:

上一篇:华为网络基础 | IP包校验和算法实例抓包验证

下一篇:Windows server | 2008R2多个远程连接设置

本文标签:    

版权声明:本文依据CC-BY-NC-SA 3.0协议发布,若无特殊注明,本文皆为《fishyoung》原创,转载请保留文章出处。

本文链接:华为网络基础 | TCP校验和算法实例抓包验证 - http://www.fishyoung.com/post-150.html