赞
踩
校验和只是为防止报文在信道传输出现误码导致报文错误,并不保证报文被他人恶意篡改。
转发报文相关的校验和包括3层校验和4层校验,2中的校验和的计算公式的入参不同:3层校验仅仅校验3层头;4层校验需要校验伪头部+4层头+4层负载。
所有校验和的计算方法是统一的,即所有2字节数据相加,结果的进位再次与2字节数据相加,对最终结果取反。还有一种是4字节相加,然后再2字节折叠,进位再与2字节相加,最终取反。
根据以上计算方式有推论:
csum(ip头)+csum(ip负载)=csum(ip头+ip负载)
unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
iph:ip头指针
ihl:ip头长度,4字节长度的数目。
采用4字节进位累加,最终再2字节折叠进位累加。
该函数发包计算和收包校验都可以。发包计算虚将ip->check字段清0;收包校验不用将check清0,直接对整个ip头计算结果如果为FFFF则认为校验成功。
二、TCP、UDP校验和计算
伪头部=saddr + daddr + len(tcp头+tcp负载) + protocol(L4)
L4校验和=csum(伪头部+tcp头+tcp负载),计算之前需将头里校验和字段清0.
增加伪头部的校验进一步增加校验内容,为保证L3和L4的一致(防君子不防小人)
csum_tcpudp_magic()的sum参数就是tcp头+tcp负载的校验和
如:
三、其他校验和函数
1、csum_partial()
从buff开始的len长度的内存计算校验和,并且额外加sum计算。简单说将len对4补齐计算32bit校验和,但没有取反。
2、csum_fold()
将32bit数字折叠成16bit校验和,并取反。以4字节计算校验和方式的接口最终都会调用该接口获取最终结果。
一般校验和计算都是统一对数据进行++操作后如skb_csum()、csum_partial()函数等等,最终调用csum_fold()函数对结算结果进程折叠并取反,得出最终的校验和结果。
四、skb中校验和相关字段
ip_summed表明L3和L4的计算结果,区分接收和发送。
1、接收过程
skb->csum可能包含L4一部分校验和;
skb->ip_summed字段代表:设备驱动告诉L4, 软件当前校验和的状态,各取值含义如下:
(1) CHECKSUM_NONE:
skb->csum中的校验和无效,可能是硬件没有提供校验和,可能是硬件不支持,也可能是硬件校验出错但是并未丢弃数据包,此时将ip_summed设为CHECKSUM_NONE,让L4软件重新校验;
(2) CHECKSUM_COMPLETE:
硬件已经校验了L4报头和其payload部分,并且校验和保存在了skb->csum中,L4软件只需要再计算伪报头然后检查校验结果即可。硬件计算稍复杂的伪头部比较好性能,因为伪头部需要提取ip头的信息。
(3) CHECKSUM_UNNECESSARY:
硬件已经进行了完整的校验,无需软件再进行检查,L4收到数据包后如果检查ip_summed是这种情况,就可以跳过校验过程;
2、发送过程
skb->ip_summed字段包含了L4软件告诉设备驱动程序当前校验和的状态,各取值含义如下:
(1) CHECKSUM_NONE:L4软件已经进行了校验,硬件无需做任何事情;
(2) CHECKSUM_PARTIAL:L4软件计算了伪报头,并且将值保存在了tcp/udp首部的check字段中,硬件需要计算其余部分的校验和。硬件适合做简单的++操作,伪头部稍复杂交给cpu。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。