IP报解析及校验和计算

数据包的头信息格式:
    +-------------------------------------------------+
    |  版本 (4位)                                    |4    IPV4
    +-------------------------------------------------+
    |  首部长度(4位)                                |5           20字节
    +-------------------------------------------------+   
    |  服务类型(TOS)8位                            | 0      
    +-------------------------------------------------+
    |  数据包总长度(16位)                            |    28+1024  (28=ip首部长+udp首部长度   1024 每个包是1024字节的数据)
    +-------------------------------------------------+
    |  标识ID号(16位)                                | 0
    +-------------------------------------------------+   
    |  标志位(3位)                                  |    010   不允许分片   40 00  标志位3+片偏移13
    +-------------------------------------------------+
    |  片偏移(13位)                                  |  0
    +-------------------------------------------------+   
    |  生存时间(TTL)(8位)                          | 40  64跳
    +-------------------------------------------------+   
    |  协议类型 (8位)                                |    11  udp
    +-------------------------------------------------+   
    |  首部校验和(16位)                              | 
    +-------------------------------------------------+   
    |  源IP地址(32位)                                | 
    +-------------------------------------------------+   
    |  目的IP地址 (32位)                            |
    +-------------------------------------------------+ 
    *  IP选项(若有) (32位)                        *
    +-------------------------------------------------+   
    *  数据                                          *
    +-------------------------------------------------+ 

 

45 00    04 1C   00 00  40 00  40 11    00 00    192 168 1 1   192 168 1 2

只要修改蓝色字:长度                           校验和        源IP      目的IP

 

校验和计算:

                  45 00

       04 1C

       00 00

       40 00

       40 11

       00 00 +

---------------------------------

       C9 2D                         (1)

 

 

       BC AE

       01 01

       BC AE

       01 02  +

--------------------------------

      17B 5F          (2)

 

(1) +(2) =C92D +17B5F=2448C  -----

高16位 + 低16位 = 2+448C=448E

对448E取反得:BB71  即校验和为BB71

 

 

 接收端的对校验和的检测 计算

校验和计算:

                  45 00

       04 1C

       00 00

       40 00

       40 11

       BB 71+

---------------------------------

      184 9E                       (1)

 

 

       BC AE

       01 01

       BC AE

       01 02  +

--------------------------------

      17B 5F          (2)

 

(1) +(2) =1849E + 17B5F=2FFFD

高8位+低8位=2+FFFD=FFFF

  对FFFF-----取反得:0          即检验校验和正确

 

 

 

 

 

 

 

 

下面的转自:http://wenku.baidu.com/view/eedddef90242a8956bece4f4.html

 

 

 

 

 

 

 

 

 

 

 

 

unsigned short checksum(unsigned short *buf, int nword)
{
  unsigned long sum;
  for(sum = 0; nword > 0; nword--)
    sum += *buf++;
  sum = (sum>>16) + (sum&0xffff);
  sum += (sum>>16);
  return -sum;
}

 

 

让我们假设一个IP头数据,来解cksum的惑

IP头数据:

01000101                 /*ver_hlen*/
00000000                 /*tos*/
00000000 00000010        /*len*/
00000000 00000000        /*id*/
00000000 00000000        /*offset*/
00000100                 /*ttl*/
00010001                 /*type*/
00000000 00000000        /*cksum(0)*/
01111111 00000000 00000000 00000001    /*sip*/
01111111 00000000 00000000 00000001    /*dip*/
(1)16比特分组;

(2)校验和清‘0

(3)求所有16比特之和

 01000101 00000000           /*ver_hlen*/
 00000000 00000010           /*len*/
---------------------
 01000101 00000010
 00000000 00000000          /*id*/
---------------------
 01000101 00000010
 00000000 00000000        /*offset*/
---------------------
 01000101 00000010
 00000100 00010001         /*ttl*//*type*/
---------------------
 01001001 00010011
 00000000 00000000           /*cksum(0)*/
---------------------
 01001001 00010011
 01111111 00000000       /*sip*/
---------------------
 11001000 00010011
 00000000 00000001       /*sip*/
---------------------
 11001000 00010100
 01111111 00000000      /*dip*/
---------------------
101000111 00010100
 00000000 00000001         /*dip*/
---------------------
101000111 00010101        sum

(4)把求得的和模(216-1)

00000000 00000001         (sum>>16)
01000111 00010101         (sum&0xffff)
---------------------
01000111 00010110

(5)在(4)的基础上求二进制反码

10111000 11101001      cksum

说白了就是循环加,然后在取反!



对方机器调用checksum()计算校验和,如果校验和为0表明IP包传输正确
-----------------------------------------------------------
01000101                 /*ver_hlen*/
00000000                 /*tos*/
00000000 00000010        /*len*/
00000000 00000000        /*id*/
00000000 00000000        /*offset*/
00000100                 /*ttl*/
00010001                 /*type*/
10111000 11101001        /*cksum(0)*/
01111111 00000000 00000000 00000001 /*sip*/
01111111 00000000 00000000 00000001 /*dip*/

 01000101 00000000
 00000000 00000010
---------------------
 01000101 00000010
 00000000 00000000
---------------------
 01000101 00000010
 00000000 00000000
---------------------
 01000101 00000010
 00000100 00010001
---------------------
 01001001 00010011
 10111000 11101001
---------------------
100000001 11111100
 01111111 00000000
---------------------
110000000 11111100
 00000000 00000001
---------------------
110000000 11111101
 01111111 00000000
---------------------
111111111 11111101
 00000000 00000001
---------------------
111111111 11111110      sum

00000000 00000001      (sum>>16)
11111111 11111110      (sum&0xffff)
----------------------
11111111 11111111

 
~sum
00000000 00000000

现在我们所用的机器设备大多数是使用二进制补码算法进行计算的

转载于:https://www.cnblogs.com/TFH-FPGA/archive/2013/02/02/2889850.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值