ip校验与计算
2017-01-02 14:09
218 查看
IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下:
在发送数据时,为了计算IP数据包的校验和。应该按如下步骤:
(1)把IP数据包的校验和字段置为0;
(2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和;
(3)把得到的结果存入校验和字段中。
在接收数据时,计算数据包的校验和相对简单,按如下步骤:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;
(2)检查计算出的校验和的结果是否等于零(反码应为16个1);
(3)如果等于零,说明被整除,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。
所谓的二进制反码求和,即为先进行二进制求和,然后对和取反。
IP数据报格式
假设IP头为:4500 0046 17d9 0000 4011 ec1d(校验字段) ac1c 0f3b ac1c 0f3d计算:4500 + 0046 +17d9 + 0000 + 4011+ ec1d +ac1c + 0f3b + ac1c + 0f3d
取出的和相加再取反->即为应填充的校验和 当接受到IP数据包时,要检查IP头是否正确,则对IP头进行检验,方法同上: 计算: 44500 + 0046 +17d9 + 0000 + 4011+ ec1d +ac1c + 0f3b + ac1c + 0f3d再与它们的和相加得出的一个数再次相加为FFFF,得到的结果是全一,正确。现假如一数据报为45 00 05 D4 CA E0 40 00 75 06 70 D2 CA 62 39 64 C0 A8 00 02根据IP数据报的格式可以看出它的首部校验字段为70 D2 它是怎么算出来的呢?方法:我们把首部校验字段即70 D2 用0000代替4500+05D4+CAE0+4000+7506+0000+CA62+3964+C0A8+0002=38F2A然后把进出来的一位与后4位再进行十六进制加法,8F2A+0003=8F2D最后用FFFF减去算出来的结果就可以了即FFFF-8F2D=70D2
代码实现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);}
在发送数据时,为了计算IP数据包的校验和。应该按如下步骤:
(1)把IP数据包的校验和字段置为0;
(2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和;
(3)把得到的结果存入校验和字段中。
在接收数据时,计算数据包的校验和相对简单,按如下步骤:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;
(2)检查计算出的校验和的结果是否等于零(反码应为16个1);
(3)如果等于零,说明被整除,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。
所谓的二进制反码求和,即为先进行二进制求和,然后对和取反。
IP数据报格式
假设IP头为:4500 0046 17d9 0000 4011 ec1d(校验字段) ac1c 0f3b ac1c 0f3d计算:4500 + 0046 +17d9 + 0000 + 4011+ ec1d +ac1c + 0f3b + ac1c + 0f3d
取出的和相加再取反->即为应填充的校验和 当接受到IP数据包时,要检查IP头是否正确,则对IP头进行检验,方法同上: 计算: 44500 + 0046 +17d9 + 0000 + 4011+ ec1d +ac1c + 0f3b + ac1c + 0f3d再与它们的和相加得出的一个数再次相加为FFFF,得到的结果是全一,正确。现假如一数据报为45 00 05 D4 CA E0 40 00 75 06 70 D2 CA 62 39 64 C0 A8 00 02根据IP数据报的格式可以看出它的首部校验字段为70 D2 它是怎么算出来的呢?方法:我们把首部校验字段即70 D2 用0000代替4500+05D4+CAE0+4000+7506+0000+CA62+3964+C0A8+0002=38F2A然后把进出来的一位与后4位再进行十六进制加法,8F2A+0003=8F2D最后用FFFF减去算出来的结果就可以了即FFFF-8F2D=70D2
代码实现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);}
相关文章推荐
- Keepalived系列2:IP报文的校验计算
- ip校验和及udp校验和的计算方法
- ip校验和计算方法
- js计算时间差与时间的校验
- 已知主机 ip 和子网掩码,计算这个主机所在网络的网络地址和广播地址的解法
- hdu 2206 IP的计算
- 【HDOJ】2206 IP的计算
- .net 后台数据校验,电话号码,邮箱地址,IP有效性
- PHP ip掩码计算ip范围
- IP首部的校验和字段是怎么计算的?
- TCP校验和详细讲解和计算
- VC获取本机IP、子网掩码、网关、计算广播地址等信息代码(通过读注册表)
- IP计算方法!【杨栋胜】
- 一个18位身份证校验计算函数
- 五、天气、在线计算、域名信息查询、ip归属、手机号归属
- 计算IP首部检验和
- Android 校验IP的正则表达式
- 网络管理之IP计算工具
- HDU 2206 IP的计算(字符串处理)
- 推荐一款哈希计算工具(可用于镜像文件校验)