【Linux 网络】IP校验和计算相关

校验和只是为防止报文在信道传输出现误码导致报文错误,并不保证报文被他人恶意篡改。

转发报文相关的校验和包括3层校验和4层校验,2中的校验和的计算公式的入参不同:3层校验仅仅校验3层头;4层校验需要校验伪头部+4层头+4层负载。

所有校验和的计算方法是统一的,即所有2字节数据相加,结果的进位再次与2字节数据相加,对最终结果取反。还有一种是4字节相加,然后再2字节折叠,进位再与2字节相加,最终取反。

根据以上计算方式有推论:

csum(ip头)+csum(ip负载)=csum(ip头+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。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值