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
现在我们所用的机器设备大多数是使用二进制补码算法进行计算的
¥29.8
¥9.9
¥59.8