数据包的头信息格式:
+-------------------------------------------------+
| 版本 (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
现在我们所用的机器设备大多数是使用二进制补码算法进行计算的