我的个人站点:http://zhwen.org ,这里的文章基本上是来自我的个人站点。当然这里有我所有的技术文章。七度黑光--当感到一切都毫无头绪的时候,最好静下心来从基础开始.

内核和用户态异步通信实例(netlink)

上一篇 / 下一篇  2009-05-16 20:13:39 / 个人分类:linux学习笔记

内核版本:2.6.26
内核态程序:knetlink.c

  1. /*
  2. * Copyright (c) 2009-~ Helight.Xu
  3. *
  4. * This source code is released for free distribution under the terms of the
  5. * GNU General Public License
  6. *
  7. * Author:       Helight.Xu<Helight.Xu@gmail.com>
  8. * Created Time: Sat 16 May 2009 04:20:14 PM CST
  9. * File Name:    knetlink.c
  10. *
  11. * Description: 
  12. */
  13.  
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/init.h>
  17. #include <net/sock.h>
  18. #include <asm/types.h>
  19. #include <linux/netlink.h>
  20. #include <linux/skbuff.h>
  21.  
  22. #define NETLINK_XUX           21       /* testing */ 
  23. #define VFW_GROUP  1
  24. #define MSG_SIZE NLMSG_SPACE(2048)
  25.  
  26. static struct sock *xux_sock;
  27.  
  28. struct netlink_data{
  29.         struct nlmsghdr msg;
  30.         char data[1024];
  31. };
  32.  
  33. static void test_link(struct sk_buff *skb)
  34. {
  35.         struct nlmsghdr *nlh;
  36.         u32             rlen;
  37.         void            *data;
  38.  
  39.          while (skb->len >= NLMSG_SPACE(0)) {
  40.                 nlh = nlmsg_hdr(skb);
  41.                 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
  42.                         return;
  43.                 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
  44.                 if (rlen > skb->len)
  45.                         rlen = skb->len;
  46.                 data = NLMSG_DATA(nlh);
  47.                 printk("link:%s", (char *)data);
  48.                 netlink_ack(skb, nlh, 0);
  49.                 skb_pull(skb, rlen);
  50.         }
  51. }
  52.  
  53. int __init init_link(void)
  54. {
  55.         xux_sock = netlink_kernel_create(&init_net, NETLINK_XUX, 0,
  56.                                            test_link, NULL, THIS_MODULE);
  57.         if (!xux_sock){
  58.                 printk("cannot initialize netlink socket");
  59.                 return -1;
  60.         } else
  61.                 xux_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
  62.  
  63.  
  64.         printk("Init OK!\n");
  65.         return 0;
  66. }
  67.  
  68. void __exit exit_link(void)
  69. {
  70.         netlink_kernel_release(xux_sock);
  71.         printk(": Release OK!\n");
  72.         return;
  73. }
  74.  
  75. MODULE_AUTHOR("Helight.Xu");
  76. MODULE_LICENSE("Dual BSD/GPL");
  77. module_init(init_link);
  78. module_exit(exit_link);

用户态程序:unetlink.c

  1. /*
  2. * Copyright (c) 2009-~ Helight.Xu
  3. *
  4. * This source code is released for free distribution under the terms of the
  5. * GNU General Public License
  6. *
  7. * Author:       Helight.Xu<Helight.Xu@gmail.com>
  8. * Created Time: Sat 16 May 2009 04:20:14 PM CST
  9. * File Name:    unetlink.c
  10. *
  11. * Description: 
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20. #include <time.h>
  21. #include <sys/poll.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <linux/netlink.h>
  25.  
  26. #define NETLINK_XUX           21       /* testing */ 
  27. #define VFW_GROUP  1
  28.  
  29. struct netlink_data{
  30.         struct nlmsghdr msg;
  31.         char data[1024];
  32. };
  33.  
  34. int link_open(void);
  35.  
  36. int main(int args, char *argv[])
  37. {
  38.         struct netlink_data nldata;
  39.         struct nlmsghdr *msg = &nldata.msg;
  40.         int retval;
  41.         struct sockaddr_nl addr;
  42.         char *data = "hello world!\0";
  43.         int size = strlen(data);
  44.  
  45.         int fd = link_open();
  46.  
  47.         memset(&nldata, '\0', sizeof(nldata));
  48.         msg->nlmsg_len = NLMSG_SPACE(size);
  49.         msg->nlmsg_type = 0;
  50.         msg->nlmsg_flags = 0;
  51.         msg->nlmsg_seq = 0;
  52.         addr.nl_family = AF_NETLINK;
  53.         addr.nl_pid = 0;
  54.         addr.nl_groups = 0;
  55.  
  56.         memcpy(NLMSG_DATA(msg), data, size);
  57.  
  58.         retval = sendto(fd, &nldata, msg->nlmsg_len, 0,
  59.                         (struct sockaddr*)&addr, sizeof(addr));
  60.  
  61.         printf("hello:%02x len: %d  data:%s\n",
  62.                         NLMSG_DATA(msg),
  63.                         sizeof(NLMSG_DATA(msg)),
  64.                         NLMSG_DATA(msg));
  65.         close(fd);
  66.         return 0;
  67. }
  68.  
  69. int link_open(void)
  70. {
  71.         int saved_errno;
  72.         int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_XUX);
  73.  
  74.         if (fd < 0) {
  75.                 saved_errno = errno;
  76.                 if (errno == EINVAL || errno == EPROTONOSUPPORT ||
  77.                                 errno == EAFNOSUPPORT)
  78.                         printf("Error - audit support not in kernel");
  79.                 else
  80.                         printf("Error opening audit netlink socket (%s)",
  81.                                 strerror(errno));
  82.                 errno = saved_errno;
  83.                 return fd;
  84.         }
  85.         if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
  86.                 saved_errno = errno;
  87.                 close(fd);
  88.                         printf("Error setting audit netlink socket CLOEXEC flag (%s)",
  89.                         strerror(errno));
  90.                 errno = saved_errno;
  91.                 return -1;
  92.         }
  93.         return fd;
  94. }

测试结果:
xux@zhwen:~/netdev$ sudo insmod knetlink.ko
xux@zhwen:~/netdev$ ./unetlink
[ 2373.160357] Init OK!
[ 2378.000012] link:hello world!
xux@zhwen:~/netdev$



TAG:

引用 删除 Guest   /   2009-08-18 14:06:41
1
引用 删除 风雨依旧   /   2009-07-14 10:48:27
很好!!!!!!!!!!
引用 删除 Guest   /   2009-07-14 10:48:02
5
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2010-03-16  
 123456
78910111213
14151617181920
21222324252627
28293031   

数据统计

  • 访问量: 28552
  • 日志数: 86
  • 图片数: 1
  • 文件数: 1
  • 书签数: 3
  • 建立时间: 2008-03-08
  • 更新时间: 2010-01-04

RSS订阅

Open Toolbar