SYNDOS —— TCP/IP Checksum极速算法

  当SYN数据包的发送速度大幅提高后,校验和计算成了自然成了不可忽视的一部分。

  
  传统的Checksum算法网上随便一搜一大堆,甚至不少攻击器也是用此算法。该算法并没有什么缺点,具有普遍性,可计算任意数据任意长度的Checksum。对于SYN包那样很短并且每次都是固定长度的包,这种算法显然有些累赘了。我们不妨仔细分析下Checksum算法的原理:

USHORT ChechkSum(USHORT *buffer, int size)
{
   DWORD chkSum = 0;

   while(size > 1)
   {
      chkSum += *buffer++;
      size -= sizeof(USHORT);
   }

   if(size)
      chkSum += *(UCHAR*)buffer;

   chkSum = (chkSum >> 16) + (chkSum & 0xffff); 
   chkSum += (chkSum >> 16);

   return (USHORT)(~chkSum);
}

  

  下面不考虑长度为奇数的情况。先看循环里面的代码,事实上只是把这些数据当作一个USHORT[],计算这个数组的和而已。即使数据的内容不一样,但只要这个累加的和不变,那后面不管对其做什么运算,函数结果肯定是一样的。简单的说:不同的数据可能有相同的和,必然也有相同的校验和。比如1+2+3=3+2+1=2+2+2,和都是6,所以他们也有相同的校验和。

  

  既然是这样的算法,我们就可以大作优化了。比如一个固定数组:USHORT A[10]。他的和一共有65535*10+1种情况。这个应该很好理解:如果10个数全是0,那和也是0;反之全是最大数65535,那么和是655350;其余情况就在这之间波动。由此可见,N字长的数据校验和其实也只有65535*N+1种情况。在本程序中计算TCP校验和的数据有20字长(40字节),其结果也只有1,310,699种。如果你在思考的话一定也想到了经典的空间换时间算法。没错,正是如此!即使事先把这几个数的校验和全部计算好保存起来,也仅需2.5M的内存空间。不过问题是,以后如何去利用表里的这些缓存数据?

  

  因为这是一张“”与“校验和”的映射表,所以当“和”确定后即可获得“校验和”。因此在预先填充数据包的时候,可变的字段一定要置0,然后计算出这个半成品包的“和”当作“基值”。以后当可变部分填上数据时,比如IP头填上了id字段,那么这个IP头的“和”就是:基值+id,校验和当然就是:表[基值+id]。o(1)的复杂度,够快吧!

  

  当然,如果可变字段超过2个字节就不能这么简简单单的加上就可以了,还要对其做高位合并计算。比如IP头的SrcIP(4个字节)填上了数据,那么:

表[基值 + SUM(SrcIP)]

 

  才是其正确的校验和,具体的SUM运算可以用个宏来定义:

  #define HI(VALUE)  (VALUE >> 16)
  #define LOW(VALUE) (VALUE & 0xFFFF)
  #define SUM(VALUE) (HI(VALUE) + LOW(VALUE))

  

  缓存表的初始化:

USHORT TableChkSum[MAX_TBL_SIZE];

/**************************************************
 * 函数:InitChkSumTable
 * 注释:初始化Checksum映射表
 *       缓存: 字段和(sum) -> 校验和(checksum)
 **************************************************/
VOID InitChkSumTable()
{
	UINT i;
	UINT chkSum;

	for(i=0; i<MAX_TBL_SIZE; i++)
	{
		chkSum = SUM(i);
		chkSum += HI(chkSum);
		TableChkSum[i] = (USHORT)~chkSum;
	}
}

(2009/1/2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值