ICMP 校验和(CHECKSUM)

    最近在研究网络协议,在用raw socket编程时遇到校验和的问题,发现校验和用了如下函数:
 1 USHORT checksum(USHORT *buffer, int size)
 2 {
 3     unsigned long cksum=0;
 4 
 5     while(size > 1)
 6     {
 7         cksum += *buffer++;
 8         size -= sizeof(USHORT);
 9     }
10 
11     if(size)
12     {
13         cksum += *(UCHAR *)buffer;
14     }
15 
16     cksum=(cksum >> 16+ (cksum & 0xffff);
17     cksum+=(cksum >> 16);
18     return(USHORT) (~cksum);
19 }
    马上google,才发现区区的校验和也如此复杂(参考RFC1071)。马上翻RFC1071,这个也太专业了,不过勉强可以看懂,按照自己的理解记录一下,发现我记性越来越差了-_-!。
    ICMP(包括IP等)校验和操作:

      一、计算校验和:按2个字节(16位)对齐进行反码加运算,然后放入校验和字段(16位)。

      二、检验校验和:与计算校验和一样再计算一遍,如果为全1说明正确。

    上面的反码加我是自己猜的不知道叫什么好,原文中的解释是(1's complement sum,符号为+')。这个就不懂了,只好按自己理解的写了。 具体操作是先取反再加,如何有进位,进位要加到最低位上,相当于循环加了。
    一般操作为了提高性能,往往先全部相加,再加上进位,再取反,就如上面的程序里一样。至于为什么要搞那么复杂,我猜是数学的严谨吧。
    下面从数学的角度看这个问题:
     一般的相加肯定要溢出或进位的,那溢出的部分信息就丢掉了。为了保留溢出的信息,需要把进位信息保留下来,也就是移到低位上相加,而这个一般加法是很难实现的,所以需要别的改进后的加法(反码加)。
    想考虑8位时的情况:
     0xF0 + 0xF0 = 0xE0 + 溢出;
    如何保留溢出位,与最低位先加就得到:
     0xF0 + 0xF0 = 0xE1;
    上面运算是错误的,但有什么加法可以时上式成立呢???
    答案就是反码加(计算校验和):
     ~0xF0 + (~0xF0= ~0xE1; ==> (0xF0 +' 0xF0 = ~0xE1 = 0x1E), 0x1E就是校验和。
    检验校验和:
     0xF0 +' 0xF0 +' 0x1E = 0xFF; 校验时同时计算校验字节,结果为0xFF,为正确。
    这个方法而且与CPU的字节序无关,具体看那个RFC1071去。
    这个也太绕了,用程序实现基本上效率很低,所以只能走捷径:) ,贴上校验代码:
 1 bool validatechecksum(unsigned short *buffer, int size)
 2 {
 3    unsigned long cksum=0;
 4    
 5    while(size >1
 6    {
 7       cksum+=*buffer++;
 8       size-=sizeof(unsigned short);
 9    }
10   
11    if(size)
12       cksum+=*(unsigned short*)buffer;
13    
14    cksum=(cksum >> 16)+(cksum&0xffff);
15    cksum+=(cksum >>16);
16    
17    return ((unsigned short)cksum == 0xFFFF);
18 }    

参考:http://blog.csdn.net/World7th/archive/2008/12/31/3669278.aspx

posted on 2010-03-28 15:41 gewala 阅读(6644) 评论(0)  编辑 收藏 引用 所属分类: 网络编程


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

设计模式 网络编程

网络

搜索

最新评论

阅读排行榜

评论排行榜