Linux26下ESP包解析流程

上传人:do****y1 文档编号:183726514 上传时间:2023-01-31 格式:DOCX 页数:7 大小:14.26KB
收藏 版权申诉 举报 下载
Linux26下ESP包解析流程_第1页
第1页 / 共7页
Linux26下ESP包解析流程_第2页
第2页 / 共7页
Linux26下ESP包解析流程_第3页
第3页 / 共7页
资源描述:

《Linux26下ESP包解析流程》由会员分享,可在线阅读,更多相关《Linux26下ESP包解析流程(7页珍藏版)》请在装配图网上搜索。

1、1.前言在Linux2.6中自带了 ipsec的实现,可以不再使用freeswan及其变种了,freeswan通过建 立ipsec*的虚拟网卡来将发送和接收ipsec数据包,通过ipsec*网卡看到的数据是明文数据,而2.6中的ipsec实现是不建立ipsec*虚拟网卡的,本文分析一下ESP包进入系统协议栈的处理流程。以下Linux内核代码版本为2.6.19.2。2. 流程分析2.1 esp协议结构esp协议结构定义,对于每个IPv4上层的协议,如TCP、UDP、ICMP、IGMP、ESP、AH等都需要定义这个结构挂接到IPv4的协议链表中,当接收到IP数据包时,会根据包中定义的IP协议号找到

2、 该结构,然后调用其成员handler函数进行处理。/* net/ipv4/esp4.c */static struct net_protocol esp4_protocol = .handler = xfrm4_rcv,.err_handler = esp4_err,.no_policy = 1,;esp 协议的 handler 函数是 xfrm4_rcv()2.2 xfrm4_rcv/* net/ipv4/xfrm4_input.c */int xfrm4_rcv(struct sk_buff *skb)return xfrm4_rcv_encap(skb, 0);实际就是xfrm4_rc

3、v_encap,封装类型参数设置为0,即没封装数据2.3 xfrm4_rcv_encap/* net/ipv4/xfrm4_input.c */int xfrm4_rcv_encap(struct sk_buff *skb, u16 encap_type)int err;be32 spi, seq;struct xfrm_state *xfrm_vecXFRM_MAX_DEPTH;struct xfrm_state *x;int xfrm_nr = 0;int decaps = 0;/获取skb中的spi和序列号信息if (err = xfrm4_parse_spi(skb, skb-nh.i

4、ph-protocol, &spi, &seq) != 0) goto drop;/进入循环进行解包操作do struct iphdr *iph = skb-nh.iph;/循环解包次数太深的话放弃if (xfrm_nr = XFRM_MAX_DEPTH)goto drop;/根据地址,SPI和协议查找SAx = xfrm_state_lookup(xfrm_address_t *)&iph-daddr, spi, iph-protocol, AF_INET);if (x = NULL)goto drop;/以下根据SA定义的操作对数据解码spin_lock(&x-lock);if (unli

5、kely(x-km.state != XFRM_STATE_VALID)goto drop_unlock;/检查由SA指定的封装类型是否和函数指定的封装类型相同if (x-encap ? x-encap-encap_type : 0) != encap_type) goto drop_unlock;/ SA重放窗口检查if (x-props.replay_window & xfrm_replay_check(x, seq)goto drop_unlock;/ SA生存期检查if (xfrm_state_check_expire(x)goto drop_unlock;/ type可为esp,ah

6、,ipcomp, ipip等,对输入数据解密if (x-type-input(x, skb)goto drop_unlock;/* only the first xfrm gets the encap type */encap_type = 0;/更新重放窗口if (x-props.replay_window) xfrm_replay_advance(x, seq);/包数,字节数统计x-curlft.bytes += skb-len;x-curlft.packets+;spin_unlock(&x-lock);xfrm_vecxfrm_nr+ = x;/ mode可为通道,传输等模式,对输入

7、数据解封装if (x-mode-input(x, skb)goto drop;/如果是IPSEC通道模式,将decaps参数置1,否则表示是传输模式if (x-props.mode = XFRM_MODE_TUNNEL) decaps = 1;break;/看内层协议是否还要继续解包,不需要解时返回1,需要解时返回0,错误返回负数/协议类型可以多层封装的,比如用AH封装ESP,就得先解完AH再解ESPif (err = xfrm_parse_spi(skb, skb-nh.iph-protocol, &spi, &seq) sp | atomic_read(&skb-sp-refcnt) !=

8、 1) struct sec_path *sp;sp = secpath_dup(skb-sp);if (!sp)goto drop;if (skb-sp)secpath_put(skb-sp);skb-sp = sp;if (xfrm_nr + skb-sp-len XFRM_MAX_DEPTH) goto drop;/将刚才循环解包用到的SA拷贝到安全路径/因此检查一个数据包是否是普通明文包还是解密后的明文包就看skb-sp参数是否为空memcpy(skb-sp-xvec + skb-sp-len, xfrm_vec,xfrm_nr * sizeof(xfrm_vec0);skb-sp-l

9、en += xfrm_nr;nf_reset(skb);if (decaps) /通道模式if (!(skb-dev-flags&IFF_LOOPBACK) dst_release(skb-dst);skb-dst = NULL;/重新进入网卡接收函数netif_rx(skb);return 0; else /传输模式#ifdef CONFIG_NETFILTER/如果定义NETFILTER,进入PRE_ROUTING链处理,然后进入路由选择处理/其实现在已经处于INPUT点,但解码后需要将该包作为一个新包看待/可能需要进行目的NAT操作,这时候可能目的地址就会改变不是到自身/的了,因此需要将

10、其相当于是放回PRE_PROUTING点去操作,重新找路由/这也说明可以制定针对解码后明文包的NAT规则,在还是加密包的时候不匹配/但解码后能匹配上_skb_push(skb, skb-data - skb-nh.raw);skb-nh.iph-tot_len = htons(skb-len);ip_send_check(skb-nh.iph);NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb-dev, NULL,xfrm4_rcv_encap_finish);return 0;#else/内核不支持NETFILTER,该包肯定就是到自身的了/返回IP协

11、议的负值,表示重新进行IP层协议的处理/用解码后的内层协议来处理数据return -skb-nh.iph-protocol;#endifdrop_unlock:spin_unlock(&x-lock);xfrm_state_put(x);drop:while (-xfrm_nr = 0)xfrm_state_put(xfrm_vecxfrm_nr);kfree_skb(skb);return 0;最后说一下返回负协议值的处理,IP上层协议的handler是在ip_local_deliver_finish()函数 中调用的:/* net/ipv4/ip_input.c */static inli

12、ne int ip_local_deliver_finish(struct sk_buff *skb)int ihl = skb-nh.iph-ihl*4;_skb_pull(skb, ihl);/* Point into the IP datagram, just past the header. */skb-h.raw = skb-data;rcu_read_lock();/* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE=MAX_INET_PROTOS */int protocol = skb-nh.iph-protocol;int h

13、ash;struct sock *raw_sk;struct net_protocol *ipprot;resubmit:/协议hash值,IPv4最大支持255种协议hash = protocol & (MAX_INET_PROTOS - 1);raw_sk = sk_head(&raw_v4_htablehash);/* If there maybe a raw socket we must check - if not we* dont care less*/if (raw_sk & !raw_v4_input(skb, skb-nh.iph, hash)raw_sk = NULL;/直

14、接在协议数组中获取协议指针if (ipprot = rcu_dereference(inet_protoshash) != NULL) int ret;if (!ipprot-no_policy) if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb) kfree_skb(skb);goto out;nf_reset(skb);/调用协议handlerret = ipprot-handler(skb);if (ret 0) /如果返回值为负,取反后重新跳回resubmit点进行选协议处理protocol = -ret;goto resubmit;I

15、P_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); else if (!raw_sk) if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb) IP_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);icmp_send(skb, ICMP_DEST_UNREACH,ICMP_PROT_UNREACH, 0); elseIP_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);kfree_skb(skb);out:rcu_read_unlock();return 0;3

16、.结论虽然在2.6的native ipsec中没支持虚拟网卡,但在通道模式下也用到了 netif_rx函数将解 码后的数据包重新接收处理的过程,并没有改变skb包的dev网卡参数,因此如果在该网卡上抓包, 就会同时抓到最初的加密包和解码后的明文包;而用freeswan的实现,在普通网卡上抓包抓到的是加 密包,由于freeswan在解码后将skb包的dev参数改为了 ipsec*,因此是通过在ipsec*网卡上能抓到解密包。对于传输模式,由于没有调用netif_rx函数,因此在实际网卡抓包只能抓到加密包,解密包只能 在netfilter架构中看到了。另外,在此情况下NAT规则仍然是有效的,制定NAT规则时根据解密后的地址端口等信息 来处理就可以了。识别一个明文包是否是解密过的就看skb的sp参数即可,该指针为空表示是普通明文包,非空表示是解密后的明文包。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!