Chinaunix首页 | 论坛 | 博客
  • 博客访问: 670217
  • 博文数量: 66
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2071
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-04 15:22
个人简介

从事IT相关工作近10年,获得《网络规划师》《信息系统项目管理师》《系统分析师》、Cisco等认证,对网络和操作系统有较深理解,对认证计费系统和虚拟化技术有深入研究。

文章分类

全部博文(66)

文章存档

2019年(4)

2018年(1)

2015年(2)

2014年(16)

2013年(43)

分类: 网络与安全

2014-01-13 02:05:16

IPv4版本的头部信息比较复杂,含有校验等信息,但是也导致路由器需要进行计算,增加了延时,IPv6中取消了对应的校验和。



这个图很好的显示了Ipv4的IP包内的组成,可以看出头部总长度是20字节。

然后我们看下Ipv4和Ipv6版本的IP头部的区别:


直接说下重点吧,就是关于IP头部的计算问题:

这是我随手抓的一个包,就以它为例进行计算:

IP的所有字段:
4500 0042 3038 0000 4011 6257 c0a8 0afa af90 [6ce9]  

全部相加: 29314 =>  然后把溢出的第一位移动到最后一位 得到 9316
得到二进制后人后取反:
1001 0011 0001 0110
0110 1100 1110 1001 => 6CE9(正解)

二进制反码求和,即为先进行二进制求和,然后对和取反。


下面是最常用的C语言的校验算法,虽然Linux内核使用更高效的汇编写成的,但是这个C语言版本的在其他位置更常用。


  1. /*求校验和函数*/
  2. USHORT CheckSum(USHORT *buffer, int size)
  3. {
  4.     unsigned long cksum=0;
  5.     while (size > 1)
  6.     {
  7.         cksum += *buffer++;
  8.         size -= sizeof(USHORT);
  9.     }
  10.     if (size)
  11.     {
  12.         cksum += *(UCHAR*)buffer;
  13.     }
  14.     /*对每个16bit进行二进制反码求和*/
  15.     cksum = (cksum >> 16) + (cksum & 0xffff);
  16.     cksum += (cksum >>16);
  17.     return (USHORT)(~cksum);
  18. }


阅读(6005) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~