![详细设计说明书示例_第1页](http://file4.renrendoc.com/view/bce02862c6150b5bd75073d3c73b804a/bce02862c6150b5bd75073d3c73b804a1.gif)
![详细设计说明书示例_第2页](http://file4.renrendoc.com/view/bce02862c6150b5bd75073d3c73b804a/bce02862c6150b5bd75073d3c73b804a2.gif)
![详细设计说明书示例_第3页](http://file4.renrendoc.com/view/bce02862c6150b5bd75073d3c73b804a/bce02862c6150b5bd75073d3c73b804a3.gif)
![详细设计说明书示例_第4页](http://file4.renrendoc.com/view/bce02862c6150b5bd75073d3c73b804a/bce02862c6150b5bd75073d3c73b804a4.gif)
![详细设计说明书示例_第5页](http://file4.renrendoc.com/view/bce02862c6150b5bd75073d3c73b804a/bce02862c6150b5bd75073d3c73b804a5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
详尽设计说明书示例详尽设计说明书示例67/67详尽设计说明书示例1.前言编写目的本说明书供给了freeswan各个模块零件的说明,以供编码人员详细实现及此后的保护工作。2.整体设计设计原那么在确立目标系统的过程中,主要依照了以下几个原那么:目标系统根本上完好地实现IPSec协议族,完好支持VPN的要求;目标系统的效力器端必定要成立在拥有自主版权的内核操作系统之上;目标系统的客户端使用方便、界面友善、配置和管理简单灵巧。软件结构该软件由以下几个模块构成:KLIPS模块――
实现对进入或出门
IP
包的安全办理,如:加密、认证等〔运转在内核空间〕Pluto模块――PF_KEY模块――
实现IKE协议,达成安全结盟的磋商〔运转在用户空间〕实现pfkey2协议,达成上述两个模块间对于SA的通讯3.程序描绘源代码文件构成本程序由两大模块构成,一局部是klips,它运转在操作系统内核空间,主要负责安全结盟和密钥的管理工作,以及对数据报的加密、解密的办理工作;一局部是pluto,它是一个运转在用户空间的守卫进度,主要负责安全结盟的磋商工作。下边分别是它们的文件构成:源文件目录|―――freeswan|――klips|――libdes|――pluto|――utilsKLIPS〔内核IPsec〕详尽设计--―――klipsipsec的核心实现模块|――net|――ipsec|――登记模块,并初始化|――ipsec_tunnel.数据包的办理并发送模块|――数据包接收并办理模块|――管理SA的模块|――sha1实现模块,由改编|――实现模块|――|――路由表的radix数的实现模块|――对上个文件的改编|――实现PF_KEY2协议的模块|――对上个文件的改编|――|――utils|――用户操作eroute表的模块|――用户操作SA库的模块|――同上|――用户操作虚接口的模块|――登记及初始化模块纲要说明功能向内核系统登记几个proc文件,以便于向内核空间中查问安全结盟和eoute表,以及虚接口的状况;初始化SA数据库〔tdb链〕;初始化SPDB数据库〔eroute表〕;初始化pf_key〔PF_KEY套接口〕;模块所波及的文件:intipsec_init(void):intipsec_tdbinit(void):intipsec_radijinit(void):intpfkey_init(void)变量说明proc文件结构将以下结构登记到内核系统中,那么内核就能够经过proc文件系统向应用程序供给一个安全的界面来存取如SA、eroute表等资料。structproc_dir_entryipsec_eroute;structproc_dir_entryipsec_spi;structproc_dir_entryipsec_spigrp;structproc_dir_entryipsec_tncfg;structproc_dir_entryipsec_spinew;structproc_dir_entryipsec_klipsdebug;notifier_block结构structnotifier_block结构是在include/linux/里面的:structnotifier_block{int(*notifier_call)(structnotifier_block*self,unsignedlong,void*);structnotifier_block*next;intpriority;};而register_netdevice_notifier函数在net/core/里面,是这样的:intregister_netdevice_notifier(structnotifier_block*nb){returnnotifier_chain_register(&netdev_chain,nb);}而notifier_chain_register函数在include/linux/里面,是这样的:extern__inline__intnotifier_chain_register(structnotifier_blocklist,structnotifier_block*n){while(*list){if(n->priority>(*list)->priority)break;list=&((*list)->next);}n->next=*list;*list=n;return0;}明显就是依据每个block的优先级把这个block摆列在一个block的链表里面,在notifier_chain_register函数里面我们能够发现这个链表是netdev_chain。实质上这个链表的作用就是在每个interface打开,封闭状态改变或许外界调用相应的ioctl的时候通知这个链表上边的所有有关的设施,而每一个协议都调用register_netdevice_notifier注册了一个netdev_notifier的结构体,这样就能够在interface改变的时候获取通知了(经过调用每个notifier_call函数)。inet_protocol结构structinet_protocolah_protocol={ipsec_rcv,/*AHhandler,定义此协议办理函数*/NULL,/*TUNNELerrorcontrol,错误办理函数*/0,/*next*/IPPROTO_AH,/*protocolID*/0,/*copy*/NULL,/*data*/"AH"/*name*/};ipsec_rcv函数是用来接收数据的callback函数,第二个是错误办理函数,其余的copy是用来协议共享的,这个此后再说,data自然就是这个结构体的私有数据了。structinet_protocolesp_protocol同上;inet_add_protocol函数在net/ipv4/里实现:voidinet_add_protocol(structinet_protocol*prot){unsignedcharhash;structinet_protocol*p2;hash=prot->protocol&(MAX_INET_PROTOS-1);prot->next=inet_protos[hash];inet_protos[hash]=prot;prot->copy=0;p2=(structinet_protocol*)prot->next;while(p2!=NULL){if(p2->protocol==prot->protocol){prot->copy=1;break;}p2=(structinet_protocol*)p2->next;}}这个函数是生成了一个
hash
表,而后每个
hash
表项都是一个链表头,而后经过这个
hash表加链表的方式接见每个协议结构体。函数说明登记及初始化模块包含以下一些函数:init_modules(),ipsec_init(),cleanup_module(),ipsec_cleanup(),ipsec_eroute_get_info(),ipsec_spi_get_info(),ipsec_spigrp_get_info(),ipsec_tncfg_get_info(),ipsec_version_get_info(),ipsec_spi_get_new()intinit_module(void)目的:
装载
ipsec时进行登记及初始化工作。参数:
无返回值:算法描绘:
0调用
――初始化成功,非ipsec_init()。
0值――初始化未成功intcleanup_module(void)目的:卸载ipsec进行去除工作。参数:无返回值:0――初始化成功,非0值――初始化未成功算法描绘:调用ipsec_cleanup()。intipsec_int(void)目的:
装载
ipsec时进行登记及初始化工作。。参数:
无返回值:
0――初始化成功,非
0值――初始化未成功算法描绘:1.将定义好的几个proc_dir_entry结构注册到系统中,如:proc_register(proc_net,&ipsec_eroute);/*PROC_FS_21*/或proc_register_dynamic(&proc_net,&ipsec_eroute);或proc_net_create(“ipsec_erouteproc_register为系统调用,在fs/proc/
〞,0,ipsec_eroute_;get_info)中实现,主要就是在proc_net
对应的目录下边生成每个协议的子目录。用户能够经过接见
/proc/net
目录下边的相应目录获取有关的资料。2.调用ipsec_tdbinit()函数初始化SA数据库,此函数在文件中实现;3.调用ipsec_radijinit()函数初始化SPD数据库,此函数在文件中实现;4.调用pfkey_init()函数初始化PFKEY,此函数在文件中实现;5.调用register_netdevice_notifier(&ipsec_dev_notifier)函数向系统中注册已定义的ipsec_dev_notifier结构,register_netdevice_ntifier()为系统调用;6.调用inet_add_protocol(&esp_protocol)和inet_add_protocol(&ah_protocol)函数向系统中注册ESP协讲和AH协议,inet_add_protocol()为系统调用;7.调用
ipsec_tunnel_init_devices()
函数,登记并初始化
ipsec虚接口,此函数定义在文件中。intipsec_cleanup(void)目的:
卸载
ipsec进行去除工作。参数:
无返回值:
0――去除成功,非
0值――去除未成功算法描绘:1.调用
ipsec_tunnel_cleanup_device(void)
函数,去除向系统登记的
ipsec虚接口,此函数在中实现;2.调用inet_del_protocol(&ah_protocol)和inet_del_protocol(&esp_protocol)去除去在系统中注册的ESP协讲和AH协议;3.调用系统调用unregister_netdevice_notifier(&ipsec_dev_notifier)去除去系统中注册的ipsec_dev_notifier;4.调用ipsec_tdbcleanup(0)去除系统中的SA数据库,此函数在中文件实现;5.调用ipsec_radijcleanup()去除系统中的SPD数据库,此函数在文件中实现;6.调用pfkey_cleanup()做pfkey去除工作;7.调用系统调用proc_net_unregister()去除freeswan在系统中登记的各个proc文件。虚接口模块纲要说明功能为了在不改变现有的操作系统的网络协议栈的状况下,更好地将IPsec嵌入,本程序采用了虚接口的观点。实现中,将创办4个ipsec虚接口,能够将虚接口绑定在物理接口上。对于从tcp/udp协议层传下来的数据,将第一查问eroute表,依据eroute表项决定将数据包发往哪一个接口,物理接口与虚接口将被视为一致的。此时,假如数据包发往虚接口,那么调用函数进行办理。〔该程序近似于网卡驱动程序的编写〕构成文件变量说明device结构虚接口定义为structdevice结构,如:staticstructdevicedev_ipsec0={"ipsec0\0",/*name*/0,/*recvmemoryend*/0,/*recvmemorystart*/0,/*memoryend*/0,/*memorystart*/0x0,/*baseI/Oaddress*/0,/*IRQ*/0,0,0,/*flags*/NULL,/*nextdevice*/ipsec_tunnel_probe/*setup*/};ipsecpriv结构structipsecpriv{structsk_buff_headsendq;structdevice*dev;structwait_queue*wait_queue;charlocked;int(*hard_start_xmit)(structsk_buff*skb,structdevice*dev);int(*hard_header)(structsk_buff*skb,structdevice*dev,unsignedshorttype,void*daddr,void*saddr,unsignedlen);#ifdefNET_21int(*rebuild_header)(structsk_buff*skb);#else/*NET_21*/int(*rebuild_header)(void*buff,structdevice*dev,unsignedlongraddr,structsk_buff*skb);#endif/*NET_21*/int(*set_mac_address)(structdevice*dev,void*addr);#ifndefNET_21void(*header_cache_bind)(structhh_cachehhp,structdevice*dev,unsignedshorthtype,__u32daddr);#endif/*!NET_21*/void(*header_cache_update)(structhh_cache*hh,structdevice*dev,unsignedchar*structenet_statistics*(*get_stats)(structdevice*dev);
haddr);structenet_statisticsmystats;intmtu;/*WhatisthedesiredMTU*/};函数说明intipsec_tunnel_init_devices(void)目的:
登记
ipsec虚接口。参数:
无返回值:
0――登记成功,非
0值――登记未成功算法描绘:调用系统调用
register_netdev(&dev_ipsec0~3)
,向系统登记
4个ipsec虚接口。intipsec_tunnel_init(structdevice*dev)目的:
初始化
ipsec虚接口,达成
device
中变量的初始化和系统资源的申请。参数:返回值:
0――
去除成功,非
0值――去除未成功算法描绘:1.填补
device结构中的几个函数,如:a)dev->open=ipsec_tunnel_open;b)dev->stop=ipsec_tunnel_stop;c)dev->hard_start_xmit=ipsec_tunnel_start_xmit;d)dev->get_stats=ipsec_tunnel_get_stats;2.给dev配空间,dev->priv=kmalloc(sizeof(structipsecpriv),GFP_KERNEL);3.初始化dev结构:skb_queue_head_init(&dev->buffs[i]);4.填补
dev
结构的其余值,如:
dev->set_mac_address=NULL等等。intipsec_tunnel_attach(structdevice*tndev,structipsecpriv*prv,structdevice*dev)目的:将某个虚接口绑定到指定的物理接口上。参数:返回值:0――绑定成功,非0值――绑定未成功算法描绘:intipsec_open(structdevice*dev)目的:参数:
要
open
的
device返回值:
0――
open
成功,非
0值――open
未成功算法描绘:此方法在网络设施驱动程序里是网络设施被激活的时候被调用〔即设施状态由down->up〕。驱动程序作为一个模块被装入:假如虚接口还没有绑定到物理接口,返回错误信息;否那么调用MOD_INC_USE_COUNT宏,以防备模块卸载是设施处于打开状态。intipsec_tunnel_start_xmit(structsk_buff*skb,structdevice*dev)目的:
假定此函数由
dev_queue_xmit()
函数调用,主要负责发送从
tcp/udp
协议层传来的数据包参数:返回值:
由dev_queue_xmit()函数填补好的skb,及要发往的网络接口0――open成功,非0值――open未成功算法描绘:1.skb,dev有效吗有效持续,无效返回;prv=dev->priv获取ipsec接口私有数据;假定prv为空,返回;获取系列参数:物理接口参数physdev,physmtu,stats;2.假如需要,拷贝skb:IfdefNET_21,thenskb_cloned(skb);3.获取Ip头iph,判断该包是不是IPV4,假定不是那么抛弃;4.计算硬件头长度〔hard_header_len〕;5.将ip包的ttl减小,并计算校验和。6.填补查找键键值,依据键值查找eroute表,获取eroute,假定找到,拿出SA,即outgonging_said;7.判断此IP包是不是IKE磋商包〔UDPport500〕,假定是,那么跳出;8.进入封装办理大循环〔几乎全部办理都由outgoing_said决定,一个said对应一个或多个tdb〔通道描绘块〕,依据每个tdb对其进行办理〕:checkforDROPormissingeroutecheckforREJECTeroutecheckforPASSeroutecheckforHOLDeroutecheckforTRAPeroute,signalPF_KEY,swaptoHOLDerouteacquirelockforwalkingtdbchaincalculateheadroomrequiredforchaincheckifSAisinlarval,dropcheckifSAisdead,dropcheckifreplayoverflowed,expireSAcheckiflifetimecountershaveoverflowed,expireSAswitchonprotocoltype,tocalculateheadroomsize.ifESPswitchonprotocoltypetocalculatetailroomsize.alculatemtudiff,sendICMPfragmentneeded.Mark``note2''ackMSSifdesiredcopyupper(layer2)headertosafetyifitwaspresentcheckifdatafitsinexistingskb,elseexpand.applygroupedtransformsapplydisasterof#ifdefs.switchbyprotocoltype,calculateheadroomforthisstageifESP,thenswitchbyciphergetheadroomifESP,thenswitchbyhashtogettailroomdoublecheck(notinNDEBUG)ifthereisenoughheadroompushthedataaheaddoublecheck(notinNDEBUG)ifthereisenoughtailroomextendthedatabehindseeifpackethasbecometoolong(biggerthan64K)finallymovetheplaintextasappropriateswitchonprotocoltypecase:ESPswitchonciphertype,prepareIVprepareself-describingpaddingswitchonciphertype,doencryptionIV.switchonciphertype,updateIVswitchonhashtype,doauthentication11)case:AHprepreplayinfo,headroomswitchonhashtype,doauthentication12)case:IPIP,applyencap13)case:IPCOMPcallskb_compressdosomedebugging14)recalculateheaderchecksumlookuperoutebynewouterheader,ifwefoundsomethingandthesrc/dsthavechanged9.endICMPifpackethasbecometoobig10.re-applylinklayerheaderiftherewasone.11.attempttore-routethepacket12.droppacketifnewrouteleadstousagain.13.doconnectiontracking14.donetfilterlocaloutoutputcall15.callip_sendorIP_SENDdependingonkernelversion⑴.获得一些初始值,如dst,src,iphlen,pyldsz,⑵.接下来是一系列合法性和安全性检查,对不合理局部有两种办理方法:1〕不进行安全办理,直接从物理接口上发送并返回;2〕抛弃数据包,返回。⑶.有eroute吗没有,那么从physdev发送数据包并返回,有那么持续;⑷.假定指定地道模式,却找不到spi,不做办理,按1)发送,返回;⑸.依据said获得tdbp链,和sa_len,假定tdbp链为空,报错返回;⑹.进入tdb办理循环,求出ipsec办理所需的headroom和tailroom;对tdbp链中每一个tdb进行以下办理:①大批的合法性判断,包含tdb状态能否对,SA能否过时,PFKEYv2办理等;②依据tdbp->计算headroom和tailroom。方法是,依据不一样而算法不一样:.tdbp->tdb_encalg〔加密算法〕ESP_DES:headroom+=sizeof(structesp);ESP_3DES:headroom+=sizeof(structesp);ESP_NULL:headroom+=offsetof(structesp,esp_iv);default:抛弃包。.tdbp->tdb_autoalg〔认证算法〕AH_MD5:tailroom+=AHHMAC_HASHLEN;AH_SHA:tailroom+=AHHMAC_HASHLEN;AH_NONE:NOP〔不办理〕;default:不对,抛弃包。Ⅲ.计算:〔数据包假如16〔〕字节的倍数,否则加空补齐。tailroom+=((8-((pyldsz+2*sizeof(unsignedchar))%8))%8)+2;IPPROTO_IPIP:headroom+=sizeof(structiphdr);default:最后,对链表中每一个
tdb
求出的
headroom
、
tailroom
乞降得出
max_headroom
、max_tailroom,pyldsz也相应改变〔加上headroom,tailroom〕。〔Ln1016〕⑺.求出tot_headroom,tot_tailroom,mtu_diff;假定mtu_diff>0,说明
prv->mtu
计算不适合,从头计算;⑻.
调整
mss;⑼.
hard_header_stripped
办理;〔Ln1077〕⑽.⑾.
!。原skb空间够用吗不够就从头分派一个skb并进行进入tdb链循环,进行真实的ipsec安全办理。
extend_copy;①定义变量并赋初值;②依据③办理
tdbp->确立headroom,tailroom;与(6)的办理近似。skb,挪动数据指针(skb_push,skb_put函数);ip头前移;⑤依据不一样的协议种类进行不一样的办理:switch(tdbp->IPPROTO_ESP:填写espp〔spi,rpl,...〕;求出iv[0],iv[1](初始化向量);求出idat,ilen(内部数据地区)要加密的数据地点及长度;求出pad,padlen.〔为了认证〕;〔pad前面两个字节分别寄存
pad
长度和前
iph->protocol.由tdbp->tdb_encalg决定调用加密算法:des_cbc_encrypt(idat,idat,ilen,(caddr_t)tdbp->tdb_key_e,(caddr_t)iv,1);ESP_3DES:des_ede3_cbc_encrypt(idat,idat,ilen,(caddr_t)(&((structdes_eks*)(tdbp->tdb_key_e))[0]),(caddr_t)(&((structdes_eks*)(tdbp->tdb_key_e))[1]),(caddr_t)(&((structdes_eks*)(tdbp->tdb_key_e))[2]),(caddr_t)iv,1);由tdbp->tdb_encalg决定怎样进行认证:AH_MD5:AH_SHA:IPPROTO_AH:填写ahp;...由tdbp->tdb_encalg决定怎样进行认证:AH_MD5:AH_SHA:IPPROTO_IPIP:结构IP头;⑥计算
IP头校验,调整
skb内部参数,
tdb
循环办理;⑿.
拿出源、目的地点,再次求
er;⒀.
还要持续循环吗⒁.
while(/*((orgdst!=newdst)||(orgsrc!=newsrc))*/(orgedst!=
&&&&er);⒂.
硬件头办理;⒃.
求物理接口,寻路由;⒄.
发送。ip_send(skb)intipsec_tunnel_detach(structdevice*dev,structipsecpriv*prv)目的:将某个绑定了的虚接口排除绑定。参数:返回值:算法描绘:
0将
――成功,非0值――未成功prv的各个值清空intipsec_tunnel_clear(void)目的:去除所有的绑定虚接口。参数:
无返回值:算法描绘:
0将
――成功,非0值――未成功prv的各个值清空intipsec_tunnel_cleanup_devices(void)目的:去除4个注册的ipsec虚接口。参数:无返回值:0――去除成功,非0值――去除未成功算法描绘:1.调用系统调用unregister_netdev(&dev_ipsec0~3)去除虚构接口;2.调用系统调用kfree_s(dev_ipsec0~,sizeof(structipsecpriv))开释为虚接口分派的空间。接收办理模块纲要说明功能主要负责办理接收到的ipsec数据包。构成文件文件流程如图3-1所示。传输层办理正常包办理包办理重组出门包查找SA库加认证加密进入策略办理检查SA状态、生计期依据SA进行办理IPSec办理解密认证分片重组办理当地包重组进入包IP路由链路层接收包
转发到本网关内的包
依据SA进行办理IPSec办理IP路由检查SA状态、重播窗口、生计期查找SA库绕过应用抛弃IP分片办理策略办理链路层发送包正常包办理包办理策略库查找虚接口驱动物理接口驱动物理接口驱动虚接口驱动链路层图3.1传统IPSec网关接收和转发包表示图函数说明intipsec_rcv(structsk_buff*skb,unsighedshortxlen)目的:接收并办理ipsec数据包。参数:skb-接收到的数据包,xlen-返回值:0――登记成功,非0值――登记未成功算法描绘:1.SKB正确性判断〔有无数据,头长度等〕;2.假如包被克隆过,对包进行一个留头办理,为后边做准备;3.是AH或ESP格式吗〔只支持这两种格式〕不是那么抛弃包;4.进入解报循环;⑴是ESP包但长度不是4字节的倍数,抛弃。〔因ESP包会有补齐考证,见组报〕;⑵计算ESP或AH头,求出said〔spi,proto,等〕;⑶假定为AH头,计算头长度和下一个头;⑷为tdb链加锁;⑸拿出tdbp〔TDB头〕,假定为空,抛弃包;tdb的状态对吗larval,dead以及超时〔有多种状况〕均将抛弃包;⑺依据认证标记tdbp->tdb_authalg对数据包进行考证;⑻对ESP包进行解密;⑼计算新的IP数据包头;⑽解锁;〔中间抛弃包时也先解锁〕⑾假如新的数据包仍是IPSec包,循环办理;5.对tdb链进行办理;6.把解开的包送入IP接收行列。netifrx(skb)。安全结盟的管理模块纲要说明功能实现了对SA数据库的初始化,增添、删除或更新SA。构成文件,变量说明tdb结构structtdb{
/*tunneldescriptorblock*/structtdb*tdb_hnext;/*nextinhashchain*/structtdb*tdb_onext;/*nextinoutput*/structtdb*tdb_inext;/*nextininput(prev!)*/structifnet*tdb_rcvif;/*relatedrcvencapinterface*/structsa_idtdb_said;/*SAID*/__u32tdb_seq;/*seqnumofmsgthatsetthisSA*/__u32
tdb_pid;
/*PIDofprocessthatsetthisSA*/#if1structxformswcaddr_t
*tdb_xform;/*transformationtouse(hostorder)*/tdb_xdata;/*transformationdata(opaque)*/#endif__u8__u8
tdb_authalg;tdb_encalg;
/*authalgorithmforthisSA*//*encalgorithmforthisSA*/__u32tdb_alg_errs;/*numberofalgorithmerrors*/__u32tdb_auth_errs;/*numberofauthenticationerrors*/__u32tdb_encsize_errs;/*numberofencryptionsizeerrors*/__u32tdb_encpad_errs;/*numberofencryptionsizeerrors*/__u32tdb_replaywin_errs;/*numberofpktsequenceerrors*/__u8tdb_replaywin;/*replaywindowsize*/__u8tdb_state;/*stateofSA*/__u32tdb_replaywin_lastseq;/*lastpktsequencenum*/__u64tdb_replaywin_bitmap;/*bitmapofreceivedpkts*/__u32tdb_replaywin_maxdiff;/*maximumpktsequencedifference*/__u32tdb_flags;/*genericxformflags*/__u32tdb_lifetime_allocations_c;/*seerfc2367*/__u32tdb_lifetime_allocations_s;__u32tdb_lifetime_allocations_h;__u64tdb_lifetime_bytes_c;__u64tdb_lifetime_bytes_s;__u64tdb_lifetime_bytes_h;__u64tdb_lifetime_addtime_c;__u64tdb_lifetime_addtime_s;__u64tdb_lifetime_addtime_h;__u64tdb_lifetime_usetime_c;__u64tdb_lifetime_usetime_s;__u64tdb_lifetime_usetime_h;__u64tdb_lifetime_packets_c;__u64tdb_lifetime_packets_s;__u64tdb_lifetime_packets_h;__u64tdb_lifetime_usetime_l;/*lasttimetransformwasused*/structsockaddr*tdb_addr_s;/*srcsockaddr*/structsockaddr*tdb_addr_d;/*dstsockaddr*/structsockaddr*tdb_addr_p;/*proxysockaddr*/__u16tdb_addr_s_size;__u16tdb_addr_d_size;__u16tdb_addr_p_size;__u16tdb_key_bits_a;/*sizeofauthkeyinbits*/__u16tdb_auth_bits;/*sizeofauthenticatorinbits*/__u16tdb_key_bits_e;/*sizeofenckeyinbits*/__u16tdb_iv_bits;/*sizeofIVinbits*/__u8tdb_iv_size;__u16tdb_key_a_size;__u16tdb_key_e_size;caddr_ttdb_key_a;/*authenticationkey*/caddr_ttdb_key_e;/*encryptionkey*/caddr_ttdb_iv;/*InitialisationVector*/__u16tdb_ident_type_s;/*srcidentitytype*/__u16tdb_ident_type_d;/*dstidentitytype*/__u64tdb_ident_id_s;/*srcidentityid*/__u64tdb_ident_id_d;/*dstidentityid*/__u8tdb_ident_len_s;/*srcidentitytype*/__u8tdb_ident_len_d;/*dstidentitytype*/caddr_ttdb_ident_data_s;/*srcidentitydata*/caddr_ttdb_ident_data_d;/*dstidentitydata*/#if0sens#endif};函数说明intipsec_tdbinit(void)目的:初始化tdb链。参数:
无返回值:算法描绘:
0将
――成功,非tdb链清空。
0值――失败inttdb_init(structtdb*tdbp,structencap_msghdr*em)目的:参数:返回值:0――成功,非0值――失败算法描绘:intputtdb(structtdb*tdbp)目的:将一个新的tdb块-tdbp参加在tdbh链中参数:tdbp――要增添的tdb块返回值:0――成功,非0值――失败算法描绘:判断传入的tdbp能否为空,假定为空,返回失败信息;计算依据tdbp->tdb_spi、tdbp->和tdbp->tdb_proto计算出hashval;将tdb链加锁,免得同时有其余存取tdb链的行为;将tdbp插入tdb链中:tdbp->tdb_hnext=tdbh[hashval];tdbh[hashval]=tdbp;将tdb链解锁。structtdb*gettdb(structsa_id*said)目的:
依据给出的
said值查找相应的
tdb
块。参数:
said
――与要查找的
tdb
块相应的
said值返回值:
structtdb
――找到的
tdb
块,NULL
――失败算法描绘:判断
said值能否有效,假定为空,返回
NULL;依据
said
计算
hashval;依据hashval值找到所要的tdb块,失败那么返回NULL。intdeltdb(structtdb*tdbp)目的:删除某个指定的tdb块。参数:tdbp――要删除的tdb块返回值:0――成功,非0值――失败算法描绘:判断tdbp的有效性,假定无效,那么返回失败信息;计算hashval值;依据hashval找到tdbp,并删除它,假定失败,返回错误。intdeltdbchain(structtdb*tdbp)目的:删除整个tdbp链。参数:tdbp――要删除的tdb链返回值:0――成功,非0值――失败算法描绘:判断tdbp能否有效,假定无效,返回错误信息;将tdbp移至最后的tdbp->tdb_onext;删除所有的tdb块。intipsec_tdbwipe(structtdb*tdbp)目的:将指定tdb块中的所有值清空。参数:tdbp――要清空的tdb块返回值:0――成功,非0值――失败算法描绘:将所有值置为NULL。安全策略数据库的管理模块纲要说明功能实现了对SPD数据库的初始化,增添、删除eroute。构成文件,变量说明eroutestructeroute{structrjtentryer_rjt;structsa_ider_said;structsockaddr_encaper_eaddr;structsockaddr_encaper_emask;};函数说明intipsec_radijinit(void)目的:初始化radij树参数:无返回值:0――成功,非0值――失败算法描绘:调用rj_init()函数初始化。intipsec_makeroute(structsockaddr_encap*eaddr,structsockaddr_encap*emask,structsa_idsaid)目的:依据said值,生成新的eroute项。参数:eaddr――封装的有效目的地点,emask――封装的目的地点掩码,said――传入的said值返回值:0――成功,非0值――失败算法描绘:分派
eroute
空间――
retrt,并先清
0;给
retrt
赋值:retrt->er_eaddr
=*eaddr;
retrt->er_emask
=*emask;retrt->er_said=said;给eroute表加锁;调用函数rj_addroute(&(retrt->er_eaddr),&(retrt->er_emask),rnh,retrt->,向eroute表中参加重生成的该项;解锁,返回。intipsec_breakroute(structsockaddr_encap*eaddr,structsockaddr_encap*emask)目的:删除指定的route。参数:eaddr――有效目的地点,emask返回值:0――成功,非0值――失败算法描绘:
-目的地点的掩码锁住eroute表;调用函数rj_delete(eaddr,emask,rnh,&rn)
删除这个指定route;解锁,将该route项清0,调用系统调用kfree开释该空间。structeroute*ipsec_findroute(structsockaddr_encap*eaddr)目的:
接收并办理
ipsec数据包。参数:
eaddr
――要查找的
route
所拥有的
eaddr
值返回值:
structeroute
――找到的
eroute
值,NULL
――
未找到算法描绘:调用函数rj_match((caddr_t)eaddr,rnh),依据eaddr查找相应的eroute项;返回找到的eroute项。intipsec_cleareroutes(void)目的:清空eroute表。参数:无返回值:0――成功,非0值――失败算法描绘:第一,锁住eroute表;调用函数radijcleartree()函数;解锁,返回。intipsec_radijcleanup(void)目的:参数:无返回值:0――成功,非0值――失败算法描绘:第一,锁住eroute表;调用函数radijcleanup()函数;解锁,返回。密钥磋商及管理模块纲要说明功能前面所描绘的KLIPS模块,根本达成了对输入、输出数据包的加密、认证工作,但其前提是办理数据包的SA已经磋商完成,而这个SA的磋商工作正是由IKE所负责的。在本程序中,Pluto模块是IKE的一个实现,它能够自动达成两个主机或网关间的安全结盟的磋商工作。源代码构成――――Pluto
源文件目录||――|――
监听
启动后台进度plutoIKE信息、whack信息和
的主程序pfkey信息,调用相应办理过程||――|――|――
由server调用,办理IKE信息办理IKE信息的头文件,主要定义信息的结构描绘成立ISAKMPSA和IPSECSA的过程|――
state头文件,主要定义
state结构|――
描绘对
state的各样操作,为成立
SA效力|――
connection头文件,定义
connection
结构|――
描绘对
connection的各样操作,为成立
SA效力|――
结构和分析
SA载荷,为成立
SA效力|――
定义了各样
ISAKMP包的信息头格式,以及结构信息头的算法和分析信息头的算法|――与成立SA有关的各样定义|――描绘对cookies值的各样操作|――调用加密算法的接口模块|――ID的表示及操作|――办理时间事件|――随机数函数模块|――SHA-1散列函数模块|――MD5散列函数模块|――DSA署名模块|――共享密钥的办理模块|――其余一些函数的定义|――|――|――|――||――由server调用,办理whack信息|――接收ipsecwhack命令,结构相应的whack信息,发送到whackfd,由监听,发到办理||――由server调用,办理pfkey信息,操作内核中的SADB库||――日记办理模块|――启动模块纲要说明功能启动Pluto后台进度。源代码构成函数说明intmain(intargc,charargv)目的:剖析使用程序的参数,做pluto进度的初始化工作参数:argcargv返回值:0――成功,非0值――失败算法:剖析使用pluto的命令行参数,并做相应的操作;调用函数init_log(),初始化日记;调用函数init_rnd_pool(),初始化随机数池;调用函数init_secret(),生成密钥值;调用函数init_states(),初始化状态表〔statetable〕;3.调用函数init_crypto(),做好加密准备;4.调用函数init_demux(),填补state_microcode_table;5.调用函数call_server(),启动效力器,监听到来的ISAKMP包和Whcak信息。intcreate_lock(void)目的:生成一个lockfile文件,以保证同时只有一个pluto进度运转参数:无返回值:0――成功,非0值――失败算法:略intdelete_lock(void)目的:删除lockfile文件参数:无返回值:0――成功,非0值――失败算法:略voidexit_pluto(intstatus)目的:以status的状态走开pluto进度。参数:status――0ok1generaldiscomfor10lockfileexists返回值:无算法:略监听模块纲要说明功能该模块主要用于监听SA磋商信息――IKE信息、whack信息和pfkey信息,收到上述几种信息后,再调用相应办理模块。源代码构成文件函数说明voidcall_server(void)目的:监听SA磋商信息――IKE信息、whack信息和pfkey信息,收到上述几种信息后,再调用相应办理模块。参数:无返回值:无算法:调用函数init_pfkeyed(),创办PF_KEY种类的套接口;调用函数init_whackfd(),创办AF_UNIX型套接口,用于通讯;进入循环等候,接收到来的信息:假如收到
IKE磋商信息,调用函数
comm_handle()
办理;假如收到
whack
信息,调用函数
whack_handle()办理;假如收到
pfkey
信息,调用函数
pfkey_handle()办理。voidfind_ifaces(void)目的:参数:无返回值:无算法:staticintinit_pfkeyfd(void)目的:创办PF_KEY型的套接口参数:无返回值:-1――失败,其余――成功算法:调用系统调用socket()创办socket,返回之。staticintinit_whackfd(void)目的:创办AF_UNIX型的套接口。参数:无返回值:-1――失败,其余――成功算法:调用系统调用socket()创办套接口,并用bind()绑定到ctl_addr上,调用系统调用listen()监听。磋商安全结盟的模块纲要说明功能磋商ISAKMPSA和IPSECSA。源代码构成详尽说明ISAKMPSA的成立过程(主模式)信息1:倡始方的Cookie值CKY-、I倡始方提出的一个或多个对ISAKMP信息的保护方案staticstf_statusmain_outI1(intwhack_sock,structconnection*c,boolpending_quick,lset_tpolicy,unsignedlongtry)目的:倡始连结c的SA的磋商,在这个初始磋商信息中,将发送倡始方的
cookie
值,和对ISAKMP信息的保护方案。参数:whack_sock――whack套接口c――这个初始磋商信息是为c这个连结发出的pending_quick――表记在生成ISAKMPSA后,能否需要立刻磋商policy――安全策略try――倡始方最多能够重试的磋商次数
IPSECSA返回值:STF_NO_REPLY――成功;其余――有错误算法:调用函数
new_state(),为这个
connection-c结构一个新的
state;给这个
state
结构
st
的成员变量赋值,此中局部值以下:st->st_connection=c;
st->st_try=try;
nterface
等于
NULL,返回
TRUE;与内核SADB引擎的交互模块纲要说明功能将磋商好的SA安装到内核中的SADB库中,或依照要求从SADB中删除作废的SA,等等。原理是,结构pfkey信息,发送到pfkey套接口,内核的SADB引擎收到后,分析信息,达成相应操作。〔pfkey的详情拜见PF_KEY模块〕源代码构成文件函数说明voidpfkey_handle(void)目的:从读取pfkeyfd套接口读取pfkey信息,并剖析此信息参数:无返回值:无算法:调用系统调用read(),从pfkeyfd套接口读取pfkey信息;调用函数pfkey_msg_parse()剖析收到的信息;ipsec_spi_tget_ipsec_spi(ipsec_spi_tavoid)目的:生成独一的SPI值参数:avoid返回值:ipsec_spi_t算法:略booldo_command(structconnection*c,constchar*verb)目的:启动_updown脚本,履行此中的防火墙命令规那么参数:返回值:算法:boolpfkey_build(interror,constchar*description,constchar*text_said,sturctsadb_ext*extensions[SADB_EXT_MAX+1])目的:调用其余结构函数,假如结构成功,返回TRUE,失败,在开释extensions的空间返回FALSE。参数:返回值:TRUE――,FALSE――算法:略boolfinish_pfkey_msg(structsadb_ext*extensions[SADB_EXT_MAX+1],constchar*description,constchar*text_said)目的:结束pfkey信息的结构。参数:extensions[]――description――text_said――返回值:FALSE――失败,TURE――成功算法:调用函数pfkey_msg_build(&pfkey_msg,extensions,EXT_BITS_IN),结构pfkey信息,假定结构失败,返回FALSE;调用系统调用write(pfkeyfd,pfkey_msg,len),将pfkey信息发送出去如发送失败,那么返回FALSE;调用函数pfkey_extensions_free(extensions)和pfkey_msg_free(&pfkey_msg)开释空间。booldo_eroute(structstate*st,unsignedop,constchar*opnameUNUSED)目的:依据要成立的一个SA,结构一个eroute表项〔结构和发送的都是地点信息〕。参数:st――描绘一个SA的状态op――UNUSED――返回值:TRUE――成功,FALSE――失败算法:依据st获取SPI值和protocol;调用函数set_text_said(),将计算所得的said放入text_said中;将六个地点转变为结构的变量:、、、、、;调用函数pfkey_extensions_init(extensions),初始化extensions;调用信息结构函数pfkey_build结构信息,并调用finish_pfkey_build()发送出去。
达成结构,把信息booldel_spi(ipsec_spi_tspi,intproto,structin_addrsrc,structin_addrdest)目的:删除一个SA。参数:spi――SPI值proto――协议src――源地点dst――目的地点返回值:TRUE――成功,FALSE――失败算法:调用函数pfkey_extensions_init(extensions),进行结构信息以前的初始化;调用函数set_text_said(),设置text_said值;调用函数pfkey_build(),结构删除一个SA的pfkey信息,调用函数finish_pfkey_build()结束结构,并发送。boolsetup_half_ipsec_sa(structstate*st,boolinbound)目的:成立半个SA〔即,两个网关或主机之间,对于此中某一个来说,数据包进入或出去的所用SA〕参数:st――描绘一个SA的状态INBOUND――表示此SA是进入的仍是出门的返回值:TRUE――成功,FALSE――失败算法:依据st,调用函数pfkey_build()结构适合的pfkey信息,再调用函数finish_pfkey_build()发送;假定此过程中有错误发生,那么返回FALSE,否那么,返回TRUE。boolteardown_half_ipsec_sa(structstate*st,boolinbound)目的:删除半个SA〔即,两个网关或主机之间,对于此中某一个来说,数据包进入或出去的所用SA〕参数:st――描绘一个SA的状态INBOUND――表示此SA是进入的仍是出门的返回值:TRUE――成功,FALSE――失败算法:依据st,拿出该SA中设置的spi、proto,调用函数del_spi删除它。boolcould_eroute(structconnection*c,structconnection*ero)目的:参数:c――描绘一个connectionero――返回值:TRUE――成功,FALSE――失败算法:boolinstall_inbound_ipsec_sa(structstate*st)目的:
安装
SA,仅被被响应方使用,响应方接着会用
install_ipsec_sa
来安装
outbound
的SA;而倡始方使用
install_ipsec_sa
来安装
inbound
和
outbound
的SA。参数:st――描绘一个SA的状态返回值:TRUE――成功,FALSE――失败算法:假如对方的client有固定的IP地点,检查我们能否有一条抵达那边的路由,此刻的相矛盾〔不知道这样说对不对〕;假如有,那么删除之;
这条路由与用函数could_eroute(c,route_owner(c,TRUE)),我能否有eroute表,假如没有,返回FALSE;用函数route_connection(c,FALSE),我能否能够将出门的数据包路由到某个ipsec虚接口。事上,只了我的peer不在他的子网中,或许假如他在,我使用UDP500端口的IKE信息,使得它不被理;用函数setup_half_ipsec_sa(st),成立入的SA。boolinstall_ipsec_sa(structstate*st,boolinbound_alse)目的:安装SA。参数:st――描绘一个SA的状inbound_also――个SA是inbound,或outbound返回:TRUE――成功,FALSE――失算法:用函数route_owner(c,TRUE),找是有个
eroute;用函数could_eroute(c,ero),;用函数route_connection(c,TRUE),我能否能够将出门的数据包路由到某个ipsec虚接口;用函数
setup_half_ipsec_sa(),依据
inbound_also,成立入的或出门的
SA;假如成立成功,假如c->eroute_ownerSOS_NOBODY,用函数do_eroute(⋯,〞add〞)增添eroute表,再用函数do_command()启脚本;假如不是SOS_NOBODY,用do_eroute(⋯,〞replace更新〞)eroute表。booldelete_ipsec_sa(structstate*st,boolinbound_only)目的:安装SA。参数:st――描绘一个SA的状inbound_only――能否只inbound的SA返回:TRUE――成功,FALSE――失算法:假如inbound_onlyTRUE,用函数teardown_half_ipsec_sa()除半个SA;假如inbound_onlyFALSE,判断能否c->eroute_owner==st->st_serialno,假如相等,用函数do_command(⋯,〞down〞)启脚本关,及用do_eroute(⋯,〞delete〞)除eroute;假如上述步骤成功,再调用teardown_half_ipsec_sa()删除SA。PF_KEY模块纲要说明PF_KEY是一种新式的协议族,由
PF_ROUTE衍生而来。在协议族中,
PF_KEY被定义为15。目前,实现所依照的时
PF_KEY的第二个版本。密钥管理进度能够使用它与操作系统中的“keyengine〞或安全结盟数据库〔SADB〕通讯,并使用PF_INET经过网络与远程密钥管理进度进行通讯。密钥管理进度与PF_KEY的关系以下列图:++|KeyMgmtDaemon|++||||Applications=====[PF_KEY]====[PF_INET]==========================||OSKernel++++|KeyEngine||TCP/IP,||orSADB||includingIPsec|++||++|++|Network||Interface|++Figure1:RelationshipofKeyMgmttoPF_KEY该模块大概由四局部构成:PF_KEYv2KeymanagementAPIdomainsocketI/FPF_KEYv2KeymanagementAPImessageparser供给了一个可用于IPsec密钥管理函数库〔keymanagementAPI〕。PF_KEYv2KeymanagementAPImessageparser实现用户层与核心之间对于密钥磋商的交互办理功能实现pfkey_v2协议族,用于密钥磋商进度pluto与内核的管理SADB的进度间通讯。构成文件,,,,,PF_KEY的信息体制PF_KEY有一套独到的信息行为,不像其余大部分BSDsocket采纳的bind()、connect()、accept()、listen()等操作来实现通讯。正常状况下,正确格式的信息发给内核,内核将应答信息返回到PF_KEYsocket中。假如内核检测到错误,错误表记会随应答信息一同被发送出去。PF_KEY有以下几种信息行为:SADB_REGISTER信息:进度向内核注册一个socket以便能够从内核获取新的SA。信息格式为:<base>,即只包含信息根本头。内核将发送SADB_REGISTER信息进行应答,格式为:<base,supported>,supported扩展说明内核所支持的考证算法和密钥算法。SADB_ACQUIRE信息:这个信息是由内核发出的,能够用于两种状况:⑴.内核向密钥管理进度申请创办一个SA。信息格式为:<base,address,proposal>,此中,proposal扩展给出了SA的几种提案,即采纳什么协议〔AH或ESP〕、采纳什么考证方法和加密方法等;扩展数据中还可包含的选项有:Identity扩展,Sensitivity扩展。但,密钥管理进度其实不向内核发送SADB_ACQUIRE应答信息。⑵.当密钥磋商过程失败后,内核经过发送SADB_ACQUIRE信息来通知密钥管理进度。信息格式为:<base>,即只包含一个信息根本头,此中,信息错误号代表了错误的原由。密钥管理进度不向内核发送SADB_ACQUIRE应答信息。3.SADB_GETSPI信息:密钥管理进度向内核申请一个SPI。信息格式为:<base,address,SPIrange>,SPIrange扩展指出了所申请的SPI的范围。内核发送SADB_GETSPI应答信息,格式为:<base,SA(*),address>,此中,SA(*)表示SA扩展的各个字段,除了扩展长度、扩展种类和SPI外,其余字段应设为0被忽视掉。4.SADB_UPDATE信息:密钥管理进度恳求内核更新〔或〕增添一条SA记录,该信息随SADB_GETSPI信息一同使用。信息格式为:<base,SA,address,key>,扩展数据中还可包含的选项有:lifetime扩展、identity扩展、sensitivity扩展。内核发送SADB_UPDATE应答信息,格式为:<base,SA,address>,或许还包含与恳求信息相应的扩展数据。5.SADB_ADD信息:在手工配置密钥或知道SPI的状况下,不必先使用GETSPI信息而直接申请内核更新〔或增添〕一条SA记录。信息格式与SADB_UPDATE信息同样。内核发送的SADB_ADD应答信息与SADB_UPDATE应答信息同样。6.SADB_DELETE信息:密钥管理进度恳求内核删除一条SA记录。信息格式为:<base,SA(*),address>,即依据SA种类、SPI、地点三因素删除相应的SA。内核发送SADB_DELETE应答信息为:<base,SA(*),address>。7.SADB_GET信息:密钥管理进度恳求从内核检索一条SA记录。信息格式为:<base,SA(*),address>。内核发送SADB_GET应答信息为:<base,SA,address,key>,扩展数据中还可包含的选项有:lifetime扩展、identity扩展、sensitivity扩展,即应答信息给出SA的详尽信息。8.SADB_EXPIRE信息:内核向密钥管理进度发送SA过期信息。信息格式为:<base,SA,lifetime,address>,lifetime扩展给出了SA的目前时间和过期时间〔软过期和硬过期〕。密钥管理进度不向内核发送SADB_EXPIRE应答信息。9.SADB_FLUSH信息:密钥管理进度恳求内核将某种种类的SA从信息根本头中SA种类字段给出了所要删除的
SADB中所有删除。信息格式为:<base>,SA种类的值。内核发送SADB_REGISTER应答信息,格式为:
<base>。10.SADB_DUMP信息:一般用于PF_KEY实现的调试。工作原理下边介绍使用PF_KEY的根来源理:REGISGTER:当密钥管理进度〔pluto〕开始运转时,它需要通知PF_KEY它要接收两种IPsec的信息——AH和ESP〔ItmusttellPF_KEYthatitiswillingtoacceptmessageforthetwoIPsecservices,AHandESP.〕:Pluto-?Kernel:SADB_REGISTERforESPKernel-?Registered:SADB_REGISTERforESP,SupporetedAlgorithmsPluto-?Kernel:SADB_REGISTERforAHKernel-?Registered:SADB_REGISTERforAH,SupporetedAlgorithms每一个REGISTER信息都会致使对所有PF_SOCKET套接口的回应〔包含恳求者〕。SADB_ACQUIRE:当KernelIPsec需要数据经AH办理时,它需要有能够使用的SA,那么进行以下操作:1).Kernel-?Registered:SADB_ACQUIREforAH,addrs,ID,sens,proposals;2).Pluto读取到这个ACQUIRE信息〔特别注意sadb_msg_seq〕后,它就会开始磋商SA:①第一,它向内核发送一个SADB_GETSPI信息,此中的sadb_msg_seq值与刚才收到的信息中该值相等;即:Pluto-?Kernel:SADB_GETSPIforAH,addr,SPIrange②内核把GETSPI的结果返回给所有的listeningsockets;即:Kernel-?All:SADB_GETSPIforAH,assoc,addrs③假如需要双向的SPI值的话,pluto还会再次进行GETSPI操作;④此时,Pluto已经有了能够使用的SPI值,他能够进行磋商了;⑤在Pluto获取密钥资料,磋商好其余参数以后,它将发送一个或多个SADB_UPDATE信息,此中的sadb_msg_seq的值与以前的同样。假如在磋商时期发生错误,那么:Pluto-?Kernel:SADB_ACQUIREforAH,assoc〔withanerror〕Kernel-?All:SADB_ACQUIREforAH,assoc〔sameerror〕假如磋商成功,那么:Pluto-?Kernel:SADB_UPDATEforAH,assoc,addrs,keys,etc.Kernel-?All:SADB_UPDATEforAH,assoc,addrs,etc.即,Kernel会把UPDATE的结果〔除了密钥〕返回给所有的监听端口。SADB_ADD:假如只在当地确立了一个SPI值,那么另一方一定用SADB_ADD信息增添SA:Pluto-?Kernel:SADB_ADDforAH,assoc,addrs,keys,etc.Kernel-?All:SADB_ADDforAH,assoc,addrs,etc.SADB_EXPIRE:数据结构PF_KEY信息是由根本信息头及后边跟从的SA有关数据构成的。根本的信息头格式structsadb_msg{uint8_tsadb_msg_version;/*PF_KEY信息的版本号,应当为PF_KEY_V2,否那么视为错误*/uint8_tsadb_msg_type;/*描绘了该信息的种类,详见下一节*/uint8_tsadb_msg_errno;/*发送方应当将该变量置为0,而响应方那么应在此填写错误代码〔假如有错〕*/uint8_tsadb_msg_satype;uint16_tsadb_msg_len;/*为单位*/
/*描绘了SA的种类*/整个信息〔包含根本信息头和邻近数据〕
的长度,以
64-bituint16_tsadb_msg_reserved;
/*保留值。发送方一定置
0。*/uint32_tsadb_msg_seq;/*这个信息的序列号。这个序列号和
sadb_msg_pid
一同,能够用于独一地表示一个对一个进度地恳求。发送方负责填写这个字段
*/uint32_tsadb_msg_pid;/*
产生这个信息进度的进度号,比方,假定一个进度号为2112
的进度向内核发送一个
SADB_UPDATE的信息,那么一定在此信息中将此地点为2112,而内核的回应信息中,也要
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 现代办公室的多元化功能区设置与员工休闲舒适性
- 班级学期医疗知识普及工作总结
- 环保科技下的电力安全创新应用
- 生物多样性保护与生态旅游的商业价值挖掘
- 2025年度水产品电商平台物流仓储服务合同
- 2025年度跨境电商进口商品采购合同-@-1
- 2025年度网络安全保障服务共同担保合同范本
- 现代教育管理体系的创新策略
- 现代心理咨询方法在应对职场冲突中的应用
- 现代农业装备的物联网技术集成与优化
- 公司违规违纪连带处罚制度模版(2篇)
- 2025届高考物理二轮总复习第一编专题2能量与动量第1讲动能定理机械能守恒定律功能关系的应用课件
- T型引流管常见并发症的预防及处理
- 2024-2025学年人教新版九年级(上)化学寒假作业(九)
- 内业资料承包合同个人与公司的承包合同
- 【履职清单】2024版安全生产责任体系重点岗位履职清单
- 2022年全国医学博士英语统一考试试题
- 学校工作总结和存在的不足及整改措施
- 《工业自动化技术》课件
- (绩效考核)钳工技能鉴定考核试题库
- 2024年江苏农牧科技职业学院单招职业适应性测试题库参考答案
评论
0/150
提交评论