织梦CMS - 轻松建站从此开始!

罗索

linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换

jackyhwei 发布于 2011-08-31 10:44 点击:次 
linux学习 内核提供 copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中
TAG:

linux学习 内核提供 copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中

在下面的代码中,内核模块注册了一组设置套接字选项的函数使得用户空间进程可以调用此组函数对内核态数据进行读写。

下面是有关操作步骤及源代码:

头文件:imp1.h

  1. /*imp1.h*/ 
  2. #ifndef __IMP1_H__ 
  3. #define __IMP1_H__ 
  4.  
  5. #define IMP1_OPS_BASIC  128 
  6. #define IMP1_SET IMP1_OPS_BASIC 
  7. #define IMP1_GET IMP1_OPS_BASIC 
  8. #define IMP1_MAX IMP1_OPS_BASIC+1 
  9.  
  10. #endif 

module:

编译:gcc -c -D__KERNEL__ -DMODULE imp1_k.c
查看module输出:方法一:dmesg, 方法二:tail -f /var/log/messages

/*imp1_k.c*/

  1. #ifndef __KERNEL__ 
  2. #define __KERNEL__ 
  3. #endif 
  4.  
  5. #ifndef MODULE 
  6. #define MODULE 
  7. #endif 
  8.  
  9. #include <linux/module.h> 
  10. #include <linux/kernel.h> 
  11. #include <linux/types.h> 
  12. #include <linux/string.h> 
  13. #include <linux/netfilter_ipv4.h> 
  14. #include <linux/netfilter.h> 
  15. #include <linux/init.h> 
  16. #include <asm/uaccess.h> 
  17. #include "imp1.h" 
  18.  
  19. #define KMSG      "a message from kernel/n" 
  20. #define KMSG_LEN  sizeof("a message from kernel/n") 
  21.  
  22. static int data_to_kernel(struct sock *sk, int cmd, void *user, 
  23.      unsigned int len) 
  24.   switch(cmd) 
  25.     { 
  26.     case IMP1_SET: 
  27.       { 
  28.         char umsg[64]; 
  29.  memset(umsg, 0, sizeof(char)*64); 
  30.         copy_from_user(umsg, user, sizeof(char)*64); 
  31.         printk("umsg: %s", umsg); 
  32.       } 
  33.       break
  34.     } 
  35.   return 0; 
  36.  
  37. static int data_from_kernel(struct sock *sk, int cmd, void *user, int *len) 
  38.   switch(cmd) 
  39.     { 
  40.     case IMP1_GET: 
  41.       { 
  42.         copy_to_user(user, KMSG, KMSG_LEN); 
  43.       } 
  44.       break
  45.     } 
  46.   return 0; 
  47.  
  48. static struct nf_sockopt_ops imp1_sockops = 
  49.   .pf = PF_INET, 
  50.   .set_optmin = IMP1_SET, 
  51.   .set_optmax = IMP1_MAX, 
  52.   .set = data_to_kernel, 
  53.   .get_optmin = IMP1_GET, 
  54.   .get_optmax = IMP1_MAX, 
  55.   .get = data_from_kernel, 
  56. }; 
  57.  
  58. static int __init init(void
  59.   return nf_register_sockopt(&imp1_sockops); 
  60.  
  61. static void __exit fini(void
  62.   nf_unregister_sockopt(&imp1_sockops); 
  63.  
  64. module_init(init); 
  65. module_exit(fini); 

用户测试程序:

编译:gcc -o user imp1_u.c

/*imp1_u.c*/

  1. #include <unistd.h> 
  2. #include <stdio.h> 
  3. #include <sys/socket.h> 
  4. #include <linux/in.h> 
  5. #include "imp1.h" 
  6.  
  7. #define UMSG      "a message from userspace/n" 
  8. #define UMSG_LEN  sizeof("a message from userspace/n") 
  9.  
  10. char kmsg[64]; 
  11.  
  12. int main(void
  13.   int sockfd; 
  14.   int len; 
  15.  
  16.   sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 
  17.   if(sockfd < 0) 
  18.     { 
  19.       printf("can not create a socket/n"); 
  20.       return -1; 
  21.     } 
  22.  
  23.   /*call function data_to_kernel()*/ 
  24.   setsockopt(sockfd, IPPROTO_IP, IMP1_SET, UMSG, UMSG_LEN); 
  25.  
  26.   len = sizeof(char)*64; 
  27.  
  28.   /*call function data_from_kernel()*/ 
  29.   getsockopt(sockfd, IPPROTO_IP, IMP1_GET, kmsg, &len); 
  30.   printf("kmsg: %s", kmsg); 
  31.  
  32.   close(sockfd); 
  33.   return 0; 

用insmod加载module

用rmmod删除module

用lsmod查看有没有加载成功

dmesg:

umsg: a message from userspace
umsg: a message from userspace

[root@localhost ipc_sockopt]# ./user
kmsg: a message from kernel
[root@localhost ipc_sockopt]# ./user
kmsg: a message from kernel

(max415)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201108/14922.html]
本文出处:blog.csdn.net/max415 作者:max415
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容