您的位置:首页 >> 操作系统 >> Linux >> 正文
RSS
 

PF_KEY接口在OpenBSD内核中的实现

http://www.rdxx.com 03年09月08日 08:35 互连网 我要投稿

关键词: 接口 , OpenBSD , 内核 , Open , BSD

  PF_KEY协议是IPSec的重要组成部分。密钥管理进程利用PF_KEY与内核的SADB进行通信,实现SA(Security Association,安全联盟)和SP(Security Policy,安全策略)的管理。本文将从PF_KEY协议构造和PF_KEY相关系统调用等方面描述OpenBSD内核中的PF_KEY实现。
  
  利用IPSec技术可在IP层实现对数据包进行保护,降低了互联网通信的风险。IPsec的安全服务是由通信双方建立的安全联盟(SA)来提供的。IPsec系统在处理输入/输出IP 流时必须参考安全策略库(SPD),并根据从SPD中提取的策略对IP流进行不同的处理,例如拒绝、绕过和进行IPsec保护。SA和SPD的管理是利用PF_key API来实现用户进程和内核之间的通信,可以通过手工进行,也可以通过IKE来进行动态协商。
  
  PF_KEY是用户进程操作内核中的SADB(Security Associations Database)和SPD的编程接口。下面将从协议族构造、系统调用和PF_KEY socket实现三部分加以描述。
  
  协议族构造
  
  Net/3组把协议关联到一个域中,并且用一个协议族常量来标识每个域。在OpenBSD定义的域包含以下的四个,分别是路由协议族、IP协议族、Unix协议族和PF_KEY协议族。同时定义了全局指针型变量domains,由它将协议族结构链接在一起。
  
  初始化完成后,内核构建了图1所示的数据结构。pfkey_domain定义的协议族为PF_KEY,Socket地址为PF_KEY。
  
  在PF_KEY协议初始化过程中,系统还定义了指针数组,用于指向含有Socket操作函数的不同版本pfkey_version结构。pfkey_version结构定义在sys/net/pfkeyv2.h文件中。
  
   "
  
  图1 初始化后的domain链表和protosw数组
  
  目前OpenBSD实现的PF_KEY版本是2.0,该指针数组结构定义如下:
  
  struct pfkey_version
  {  int protocol;  
       int (*create)(struct socket socket); 
       int (*release)(struct socket *socket);
       int (*send)(struct socket *socket, void *message, int len);
  } = { PFKEYV2_PROTOCOL, &pfkeyv2_create, &pfkeyv2_release, &pfkeyv2_send };
  
  PF_KEY socket实现
  
  PF_KEY socket系统调用
  
  当一个应用调用Socket时,进程用系统调用机制将三个独立的整数传给内核。syscall将参数复制到32bit值的数组中,并将数组指针作为第二个参数传给Socket的内核版。内核版的Socket将第二个参数“uap”作为指向sys_socket_args结构的指针。图2显示了上述过程。
  
   "
  
  图2 用户空间Socket参数到内核空间转换图
  
  当进程调用socket(PF_KEY,SOCK_RAW, PF_KEY_V2)时,内核sys_socket()向PF_KEY协议中pfkey_protosw(见图1)定义的pfkey_usrreq()发送PRU_ATTACH,调用如下:
  
  error=(*prp->pr_usrreq)(so,PRU_ATTACH,NULL,(struct mbuf *)(long)proto,NULL);
  
  Pfkey_usrreq()处理PRU_ATTACH请求,创建协议控制块。
  
  PF_KEY close()系统调用
  
  内核中sys_close()对应用户空间的close()系统调用,用来关闭各类描述符。当fd是引用对象的最后描述符时,与对象有关的close函数被调用如下:
  
  error=(*fp->f_ops->fo_close)(fp, p);
  
  Socket的fp->f_ops->fo_close是soo_close()函数。soo_close()是soclose()函数的封装器。soclose()取消Socket上相关连接并释放不需要的数据结构,发送PRU_DETACH请求断开Socket与PF_KEY协议的联系,最后调用sofree()释放PF_KEY socket。
  
  error2=(*so->so_proto->pr_usrreq)(so, PRU_DETACH, NULL,NULL, NULL);
  
  Pfkey_usrreq()响应soclose()的PRU_DETACH请求,释放该Socket协议控制块,并将该Socket从pfkeyv2_sockets链表中删除。
9 7 3 1 2 4 8 :

 
 
标签: 接口 , OpenBSD , 内核 , Open , BSD 打印本文
 
 
  热点搜索
 
 
 



Valid XHTML 1.0 Transitional
Copyright ©2005 - 2008 Rdxx.Com,All Rights Reserved
收藏本页
收藏本站