科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件推荐:Linux用户态与内核态的交互 (7)

推荐:Linux用户态与内核态的交互 (7)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这个结束函数中,向内核发送一个“我已经退出了”的消息,然后调用close函数关闭netlink套接字,退出程序。

作者:Kendo 来源:赛迪网技术社区 2007年11月2日

关键字: Linux

  • 评论
  • 分享微博
  • 分享邮件
 

这个结束函数中,向内核发送一个“我已经退出了”的消息,然后调用close函数关闭netlink套接字,退出程序。

内核空间

与应用程序内核,内核空间也主要完成三件工作:

n 创建netlink套接字

n 接收处理用户空间发送的数据

n 发送数据至用户空间

API函数netlink_kernel_create用于创建一个netlink socket,同时,注册一个回调函数,用于接收处理用户空间的消息:



struct sock *

netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len));
参数unit表示netlink协议类型,如NL_IMP2,参数input则为内核模块定义的netlink消息处理函数,当有消息到达这个netlink socket时,该input函数指针就会被引用。函数指针input的参数sk实际上就是函数netlink_kernel_create返回的struct sock指针,sock实际是socket的一个内核表示数据结构,用户态应用创建的socket在内核中也会有一个struct sock结构来表示。
static int __init init(void)

{

  rwlock_init(&user_proc.lock);		/*初始化读写锁*/



  /*创建一个netlink socket,协议类型是自定义的ML_IMP2,kernel_reveive为接受处理函数*/

  nlfd = netlink_kernel_create(NL_IMP2, kernel_receive);

  if(!nlfd)		/*创建失败*/

  {

      printk("can not create a netlink socket
");

      return -1;

  }



  /*注册一个Netfilter 钩子*/

  return nf_register_hook(&imp2_ops);

}
module_init(init); 用户空间向内核发送了两种自定义消息类型:IMP2_U_PID和IMP2_CLOSE, 分别是请求和关闭。kernel_receive 函数分别处理这两种消息:
DECLARE_MUTEX(receive_sem);							
/*初始化信号量*/

static void kernel_receive(struct sock *sk, int len)

{
do
{
struct sk_buff *skb;
if(down_trylock(&receive_sem))				
/*获取信号量*/
return;
/*从接收队列中取得skb,然后进行一些基本的长度的合法性校验*/
while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
{
{
struct nlmsghdr *nlh = NULL;
if(skb->len >= sizeof(struct nlmsghdr))
{
/*获取数据中的nlmsghdr 结构的报头*/
nlh = (struct nlmsghdr *)skb->data;
if((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
&& (skb->len >= nlh->nlmsg_len))
{
/*长度的全法性校验完成后,处理应用程序自定义消息类型,
主要是对用户PID的保存,即为内核保存“把消息发送给谁”*/

if(nlh->nlmsg_type == IMP2_U_PID)		/*请求*/

{
write_lock_bh(&user_proc.pid);

user_proc.pid = nlh->nlmsg_pid;

write_unlock_bh(&user_proc.pid);

}

else if(nlh->nlmsg_type == IMP2_CLOSE)	/*应用程序关闭*/

{

write_lock_bh(&user_proc.pid);

if(nlh->nlmsg_pid == user_proc.pid)

user_proc.pid = 0;

write_unlock_bh(&user_proc.pid);

}

}

}

}

kfree_skb(skb);

        }

up(&receive_sem);				/*返回信号量*/

}while(nlfd && nlfd->receive_queue.qlen);

}
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章