精华内容
下载资源
问答
  • ip首部校验和

    2021-09-02 15:48:07
    ip首部校验和 只检验数据报的首部,不包括数据部分 方法: 在发送方,先把IP数据报首部划分为许多16位字的序列,并把检验和字段置0,用反码算术运算把所有16位字相加后,将得到的和的反码写入检验和字段。 接收方...

    ip首部校验和

    只检验数据报的首部,不包括数据部分

    方法:

    在发送方,先把IP数据报首部划分为许多16位字的序列,并把检验和字段置0,用反码算术运算把所有16位字相加后,将得到的和的反码写入检验和字段。

    接收方收到数据报后,将首部的所有16位字再使用反码算术运算相加一次。将得到的和取反码,即得出接收方的检验和的计算结果。

    若首部未发生任何变化,则此结果必为0。

    UDP校验和

    与IP校验和类似,但UDP的检验和是把首部和数据部分一起都检验。
    *在计算检验和时,要在UDP用户数据报之前增加12字节的伪首部。

    方法:

    在发送方,首先是把全零放入检验和字段。再把伪首部以及UDP用户数据报看成是由许多16位的字符串接起来的。(若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节)。然后按二进制反码计算出这些16位字的和。将此和的反码写入检验和,发送出去。

    在接收方,把收到的UDP用户数据报连同伪首部一起,按二进制反码求这些16位字的和。当无差错时其结果应为全1.

    TCP校验和

    与UDP类似。

    展开全文
  • IP首部校验和算法

    2016-07-04 14:51:47
    IP数据报首部校验和(长度是16位),用于检验首部的有效性和完整性。IP首部校验和采用 的时反码求和算法。就是把首部看成16位的整数序列。然后反码求和。把 得到的值放入首部校验和位置。反码求和算法如下: 0和0...

    IP数据报首部校验和(长度是16位),用于检验首部的有效性和完整性。IP首部

    校验和采用的是反码求和算法。就是把首部看成16位的整数序列。然后反码

    求和。把得到的值放入首部校验和位置。反码求和算法如下:

    0和0相加是0但要产生一个进位1,0和1相加是1,1和1相加是0.若最高位相加后产生进位,

    则最后得到的结果要加1。

    (0)反 + (0)反 = 1 + 1 = 10
    (1)反 +(0)反 = 0 + 1 = 1
    (1)反 + (1)反 = 0 + 0 = 0
    在发送时,第一次发送前,首部校验和置0。然后用该算法算出校验和填充。接受端收到数
    据后,用校验和算法(包含填充的检验和值)检验所有数据。结果应该为0。
    #include "stdafx.h"
    //16位反码求和算法
    unsigned short checksum(unsigned short *buffer, int size)
    {
    unsigned long cksum = 0;
    while(size>1)
    {
    cksum += *buffer++;
    size -= sizeof(unsigned short);
    }
    if (size)
    {
    cksum += *(unsigned short*)buffer;
    }
    cksum = (cksum>>16) + (cksum&0xffff);
    cksum += (cksum>>16);
    return (unsigned short)(~cksum); //返回16位值
    }
    // 模拟数据
    struct datasum
    {
    char data[50];//数据
    unsigned short checksum;//校验和
           };
    //测试程序
    int _tmain(int argc, _TCHAR* argv[])
    {
    struct datasum msg = {"Hello World!",0};
    msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
    printf("checksum prev is: %d",msg.checksum);
    msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
    printf("checksum after is: %d",msg.checksum);
    getchar();
    return 0;
    }

    展开全文
  • TCP校验和,TCP校验和不仅要校验20位的TCP首部与TCP首部后面的数据,还要在TCP首部前加上两个IP(每个IP四个字节)、十六位的TCP协议(为0x0006)、TCP首部与数据部分的字节数(即TCP首部和数据加起来的长度)组成的...

    首先,关于IP和TCP校验和的概念

    IP首部的校验和相对简单,在不是特殊类型包的情况下,IP首部长度为20字节,IP校验和就是计算这20位的校验和;TCP校验和,TCP校验和不仅要校验20位的TCP首部与TCP首部后面的数据,还要在TCP首部前加上两个IP(每个IP四个字节)、十六位的TCP协议(为0x0006)、TCP首部与数据部分的字节数(即TCP首部和数据加起来的长度)组成的伪头。

    IP校验和的计算:

    发送端,

    计算前,先把IP首部校验和设为0,然后将20字节的IP首部视为10个十六位的数值,从前(底层方向为前)往后每一位相加,相加的结果存入一个32位的变量;如果IP首部是特殊类型包,字节数不为20(可能21、23、27谁知道,都有可能),它剩下一个奇数位(它是一个8位的数值),扩展成一个16位的数(后面填充8位的0),把这个新生的16位数加入到前面的和里面。

    得到这样一个和,再把这个和(32位的数值)的高16位与低16位相加,如果和的结果里,高16仍然不等于0,那么再把高16位与低16位相加,直到高16位为0。

    这样一个数值它是一个16位的数,把它以二进制按位取反(比如一个4位的数值,1010按位取反就是0101),按位取反以后的数,就是发送端的校验和,把这个校验和填入IP首部校验和位置。

    接收端,

    接收端计算校验和,接收端收到的包里,已经填入了发送端填写的校验和,这个不用改。计算的规则和发送端一样,都是视为16位的数值,一一相加,奇数位扩展成16位的数值,加入和里面,再把高16位与低16位反复相加,得到一个16位的和,把这个和按位取反。

    这里如果数据包的IP首部正确,那么计算结果就是0(这就是校验和的意义,发送端填入的校验和,接收端计算的时候将校验和计算在里面,结果如果为0,数据包的IP首部就是正确无误的)

     

    //一个实例,以下实例原代码是从51单片机的程序里面拷过来的,在这里要感谢这位LiZhanglin前辈,他的程序给了我很多帮助。
    
    //u_int8_t、u_int16_t 、u_int32_t分别为无符号的8位数、16位数、32位数
    
    
    u_int16_t  CheckSum(u_int16_t * buff, u_long size, u_long InSum)//buff是指向IP首部的指针,InSum是一个初始值,如果是计算IP首部,它的值就为0
    {
        u_int8_t *buf;//这个指针应该没什么用
        u_int32_t cksum = InSum;//把初始值赋值给用于求和的32位变量
       
        u_int16_t  * EndBuf = (u_int16_t *)buff + size / 2;//将IP首部结束位置赋值给一个16位指针,(如果IP首部长度为奇数,它指向的就是最后一个奇数位;如果IP首部长度为偶数,它指向的就是IP首部第20个字节(假设是20字节)的后一位,即实际上就是TCP头、UDP头、ICMP头的位置)
        while (buff < EndBuf)
        {
            cksum += ntohs(*(buff));//相加,这里要注意的,网络上通信用的都是大端序的存储方式,但是我们很多家用计算机里面都是小端序,我这里就必须通过ntohs将网络通信的格式转成我计算机里的格式,否则相加的和就会不正确
            buff++;
        }
        
        if ((size & 0x0001) != 0)//用一个与运算,IP首部字节数是否是奇数
        {
            cksum += ntohs((*buff)) & 0xff00;//是奇数,就将buff指针指向的数值与运算以后加入到和里面(这里buff指针是一个16位的指针,所以它所指的值,是IP首部的奇数位与后面TCP头或UDP头或ICMP头的头一个字节组合起来的16位数,需要把这个16位数的低8位置为0,变相达到将奇数位扩充为16位数的效果,这里的办法是与运算一个0xff00的十六位数;同样这里也要注意大小端序的问题)
        }
            
        cksum = (cksum >> 16) + (cksum & 0xffff);//高低16位反复相加,网上说,这样两句代码与循环将高低16位数相加的效果是一样的,最后结果都是一个16位的数,这应该是一个数学问题,有兴趣的哥哥姐姐可以去找找原因
        cksum += (cksum >> 16);
        
        return (u_int16_t)(~cksum);//将和按位取反,返回一个16位的数
    }

     

    TCP首部的校验和:

    发送端

    发送端将TCP首部的校验和位置设为0。

    先计算伪首部,伪首部由发送端的IP+接收端的IP+TCP协议序号(0x0006)+TCP首部与数据的字节数组成,它并不是一个存在于数据包里的东西,而是一个我们为了方便计算而假设的一个首部,计算方式也是视为16位的数,一个个相加。

    加完伪首部,加TCP首部和数据部分,同样视为16位的数值,一个个相加,如果最后TCP首部和数据部分字节数为奇数位,将奇数位扩充为低8位为0的16位数,加入和里面。

    和的高低16位反复相加,得到一个16位数值,按位取反,返回。

     

    接收端

    计算方式同上,计算结果为0,说明伪头、TCP头、数据没有问题。

     

    实例(我删改了部分注释,删掉了部分多余代码,也可能它并不多余,大家就着原理理解好了,真的缺了什么,自己补吧):

    u_int16_t TCPCheckSum(struct ip_header * pIPHead, u_int16_t TCPSize)//参数:指向IP首部的指针,TCP首部与数据的字节数
    {
        u_long sum = 0;
        u_int16_t  * p;
        u_int16_t i;
        u_int8_t buf[2000];
        
        
        sum = 0;
    
        //虽然不知道是不是我想多了,万一最后一位奇数位后面超出边界怎么办?所以我的想法是复制到一个数组里再计算
        memset(buf, 0x00, 2000);//初始化为0
        memcpy(buf,(u_int8_t*)&(pIPHead->ip_souce_address), 8);//两个IP共占据8个字节
    
        p = (u_int16_t *)buf;
        for (i = 0; i < sizeof(u_int32_t) / sizeof(u_int16_t) * 2; i++, p++) {
            sum += ntohs(*p);//加上两个IP,注意大小端序问题
        }
            
        //sum += (u_int16_t)pIPHead->ip_protocol;
        sum += 0x0006;//反正TCP的协议是0006,加上协议序号
      
        
        sum += (u_int16_t)TCPSize;//加上TCP首部和数据部分的字节数
        
    
        memset(buf, 0x00, 2000);//初始化为0
        memcpy(buf, (u_int8_t *)((u_int8_t *)pIPHead + 20), TCPSize);//复制TCP首部和数据
      
        return CheckSum((u_int16_t*)buf, TCPSize, sum);//调用前面的函数
    }
    

    另注:以上代码是在VS2017上测试成功的,如果你拿去不能用,就看看哪里需要修改。

     

    展开全文
  • IP首部校验和的计算

    万次阅读 2015-09-12 18:31:08
    IP首部校验和的计算

    IP首部校验和的计算主要是两步:按位异或和取反,具体来说

    对于发送方计算检验和:

    1. 初始计算校验和字段时该字段全部用0填充;

    2. IP头部以16位为一个单位,逐个模2加(相当于异或);

    3. 得到的结果取反,作为校验和放入校验和字段;

    对于接收者来说,验证也很简单:

    1. 对于接收的IP报文头部以16位为单位逐个求和;

    2. 若结果为1,则校验正确,否则出错丢弃;

    原理很简单,接收方的计算对象是A和A的反的异或,结果当然是1了!

    具体的程序实现例子如下:

    <span style="font-size:14px;">SHORT checksum(USHORT* buffer, int size)
    {
        unsigned long cksum = 0;
        while(size>1)
        {
            cksum += *buffer++;
            size -= sizeof(USHORT);
        }
        if(size)
        {
            cksum += *(UCHAR*)buffer;
        }
        cksum = (cksum>>16) + (cksum&0xffff); 
        cksum += (cksum>>16); 
        return (USHORT)(~cksum);
    }</span>
     为了方便大家,这里再借用网上的一个例子吧:
      IP头:
      45 00    00 31
      89 F5    00 00
      6E 06    00 00(校验字段)
      DE B7   45 5D       ->    222.183.69.93   (源IP地址)
      C0 A8   00 DC       ->    192.168.0.220  (目的IP地址)
      计算:  
      4500 + 0031 +89F5 + 0000 + 6e06+0000 + DEB7 + 455D + C0A8 + 00DC =3 22C4 (结果大于4bit,继续迭代计算)
      0003 + 22C4 = 22C7 
      ~22C7 = DD38      ->即为应填充的校验和
      当接受到IP数据包时,要检查IP头是否正确,则对IP头进行检验,方法同上:
      计算:
      4500 + 0031 +89F5 + 0000 + 6E06+DD38 + DEB7 + 455D + C0A8 + 00DC =3 FFFC
      0003 + FFFC = FFFF
      得到的结果是全1,正确。


    展开全文
  • 目录 ip首部校验和的计算方法(c语言实现)1. IP首部校验和的计算方法(C语言实现)2. 校验和计算方法3. 对校验和进行校验 ip首部校验和的计算方法(c语言实现) 1. IP首部校验和的计算方法(C语言实现) 关联博客:...
  • IP首部校验和计算

    2016-10-31 18:06:00
    根据RFC1071文档的计算方法,编写代码实现IP首部校验和的计算 计算步骤: 1.首先将IP首部中校验和字段置0 2.将IP首部每16bit进行相加,如果有进位产生,则将进位加到最低位。 3.将计算的结果取反即可 1 ...
  • IP数据报首部校验和算法

    千次阅读 2018-05-26 13:51:19
    IP数据报首部校验和算法 详细 非代码当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正。文章省略一点,呵呵 IP/ICMP/IGMP/TCP/UDP等协议的校验和...
  • IP数据报首部校验和算法说明

    千次阅读 2017-12-28 16:26:28
    《IP数据报首部校验和算法》 1. IP数据报首部校验主要用于保证IP数据报头的完整性。 2. 该算法为“反码求和校验”,”反码求和校验“是一个专用术语,区别于先求反码再求和。 3. 该算法过程如下文所示例。  => ...
  • ip首部校验和计算

    2016-10-25 15:30:42
    IP首部校验和的计算方法: 1.把校验和字段清零。 2.然后对每16位(2字节)进行二进制反码求和,反码求和的意思是先对每16位求和,再将得到的和转为反码。 接下来详细描述反码求和的步骤:看下面的代码 算法:...
  • IP首部校验和计算原理

    千次阅读 2017-09-19 09:02:15
    以 IP 首部中的校验和为例,计算过程可分为三个步骤:   1.把校验和字段以全零填充; 2.对每 16 位(2 Byte)进行二进制反码求和; ...3.对得到的结果即为首部校验和。   示例: 对
  • 作业:首部校验和计算

    千次阅读 2016-10-10 11:17:31
    IP首部校验和的计算主要是两步:按位异或和取反,具体来说1. IP头部以16位为一个单位,逐个模2加(相当于异或);2. 得到的结果取反,作为校验和放入校验和字段;3. 初始计算校验和字段时该字段全部用0填充; 以上是...
  • IP包的首部校验和的计算与程序设计一,感受与实验基本要求1.1 实验目的1.2 实验要求二,实验内容2.1 IP首部的基本校验方法2.2流程图2.3编程思路2.3.1得到数据并进行标准化2.3.2 信息合并后,把字符串转换成十进制,...
  • 目录 IP数据报首部校验和算法 详细 非代码 IP数据报首部校验和算法 详细 非代码 参考转载至: ​ http://www.cnblogs.com/fhefh/archive/2011/10/18/2216885.html 当用google搜索IP数...
  • 理解UDP协议的首部校验和校验和

    万次阅读 2018-12-26 23:00:15
    然后就可以开始着手校验和的计算了,但在这之前还应注意,上表中有一项 Checksum ,这是发送方根据发送内容计算出来校验和,接受方需要根据收到的内容重新计算一遍校验和,然后再对比两者。所以在接收方计算时应该...
  • IP数据报首部校验和算法 详细 非代码 当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正。文章省略一点,呵呵 IP/ICMP/IGMP/TCP/UDP等...
  • ip数据报首部校验和的计算网络层间的数据传送特点是: 不可靠: 分组可能丢失,乱序等,不做确认; 无连接: 每个分组都独立对待; 尽力投递: 不随意放弃分组; 点到点。因为在传输过程中会受到很多的干扰,ip数据包会...
  • 由于在IP首部和ICMP报文中都存在着校验和的问题,在网上搜索了关于校验和的计算方法,得出如下的转载文章: i 将校验和字段置为0,然后将IP包头按16比特分成多个 校验和Header Checksum:0x618D将其重置为0X...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,220
精华内容 9,688
关键字:

首部校验和