资源描述:
《Linux2.6下ESP包解析流程》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、1.前言在Linux2.6中自带了ipsec的实现,可以不再使用freeswan及其变种了,freeswan通过建立ipsec*的虚拟网卡来将发送和接收ipsec数据包,通过ipsec*网卡看到的数据是明文数据,而2.6中的ipsec实现是不建立ipsec*虚拟网卡的,本文分析一下ESP包进入系统协议栈的处理流程。以下Linux内核代码版本为2.6.19.2。2.流程分析2.1esp协议结构esp协议结构定义,对于每个IPv4上层的协议,如TCP、UDP、ICMP、IGMP、ESP、AH等都需要定义这个结构挂接到IPv4的协议链表中,当接收到IP数据包时,会根据包中定
2、义的IP协议号找到该结构,然后调用其成员handler函数进行处理。/*net/ipv4/esp4.c*/staticstructnet_protocolesp4_protocol={ .handler = xfrm4_rcv, .err_handler = esp4_err, .no_policy = 1,};esp协议的handler函数是xfrm4_rcv()2.2xfrm4_rcv/*net/ipv4/xfrm4_input.c*/intxfrm4_rcv(structsk_buff*skb){ returnxfrm4_rcv_encap(skb,0);}实际
3、就是xfrm4_rcv_encap,封装类型参数设置为0,即没封装数据2.3xfrm4_rcv_encap/*net/ipv4/xfrm4_input.c*/intxfrm4_rcv_encap(structsk_buff*skb,__u16encap_type){ interr; __be32spi,seq; structxfrm_state*xfrm_vec[XFRM_MAX_DEPTH]; structxfrm_state*x; intxfrm_nr=0; intdecaps=0;//获取skb中的spi和序列号信息 if((err=xfrm4_parse_sp
4、i(skb,skb->nh.iph->protocol,&spi,&seq))!=0) gotodrop;//进入循环进行解包操作 do{ structiphdr*iph=skb->nh.iph;//循环解包次数太深的话放弃 if(xfrm_nr==XFRM_MAX_DEPTH) gotodrop;//根据地址,SPI和协议查找SA x=xfrm_state_lookup((xfrm_address_t*)&iph->daddr,spi,iph->protocol,AF_INET); if(x==NULL) gotodrop;//以下根据SA定义的操
5、作对数据解码 spin_lock(&x->lock); if(unlikely(x->km.state!=XFRM_STATE_VALID)) gotodrop_unlock;//检查由SA指定的封装类型是否和函数指定的封装类型相同 if((x->encap?x->encap->encap_type:0)!=encap_type) gotodrop_unlock;//SA重放窗口检查 if(x->props.replay_window&&xfrm_replay_check(x,seq)) gotodrop_unlock;//SA生存期检查 if(
6、xfrm_state_check_expire(x)) gotodrop_unlock;//type可为esp,ah,ipcomp,ipip等,对输入数据解密 if(x->type->input(x,skb)) gotodrop_unlock; /*onlythefirstxfrmgetstheencaptype*/ encap_type=0;//更新重放窗口 if(x->props.replay_window) xfrm_replay_advance(x,seq);//包数,字节数统计 x->curlft.bytes+=skb->len; x
7、->curlft.packets++; spin_unlock(&x->lock); xfrm_vec[xfrm_nr++]=x;//mode可为通道,传输等模式,对输入数据解封装 if(x->mode->input(x,skb)) gotodrop;//如果是IPSEC通道模式,将decaps参数置1,否则表示是传输模式 if(x->props.mode==XFRM_MODE_TUNNEL){ decaps=1; break; }//看内层协议是否还要继续解包,不需要解时返回1,需要解时返回0,错误返回负数//协议类型可以多层