Linux 系统内核空间与用户空间通信

说明请看这里http://www.ibm.com/developerworks/cn/linux/l-netlink/index.html

这里主要是贴在新的内核版本(3.2.0-29)能运行的代码。

imp2_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/init.h>
 12 #include <linux/types.h>
 13 #include <linux/netdevice.h>
 14 #include <linux/skbuff.h>
 15 #include <linux/netfilter_ipv4.h>
 16 #include <linux/inet.h>
 17 #include <linux/in.h>
 18 #include <linux/ip.h>
 19 #include <linux/netlink.h>
 20 #include <linux/spinlock.h>
 21 #include <linux/semaphore.h>
 22 #include <net/sock.h>
 23 #include "imp2.h"
 24 
 25 struct semaphore receive_sem;
 26 
 27 DEFINE_SEMAPHORE(receive_sem);
 28 
 29 static struct sock *nlfd;
 30 
 31 struct
 32 {
 33   __u32 pid;
 34   rwlock_t lock;
 35 }user_proc;
 36 
 37 static void kernel_receive(struct sk_buff *skb)
 38 {
 39     struct nlmsghdr *nlh = NULL;
 40     //printk("%s: skb->user: %d\n", __func__, atomic_read(&skb->users)); return;
 41 
 42 
 43 
 44     if(down_trylock(&receive_sem))
 45         return;
 46 
 47     if(skb->len < sizeof(struct nlmsghdr))
 48         goto out;
 49 
 50     nlh = nlmsg_hdr(skb);
 51 
 52     if((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
 53             && (skb->len >= nlh->nlmsg_len)) {
 54         if(nlh->nlmsg_type == IMP2_U_PID) {
 55             write_lock_bh(&user_proc.lock);
 56             user_proc.pid = nlh->nlmsg_pid;
 57             write_unlock_bh(&user_proc.lock);
 58         } else if(nlh->nlmsg_type == IMP2_CLOSE) {
 59             write_lock_bh(&user_proc.lock);
 60             if(nlh->nlmsg_pid == user_proc.pid)
 61                 user_proc.pid = 0;
 62             write_unlock_bh(&user_proc.lock);
 63         }
 64     }
 65 
 66     //kfree_skb(skb);
 67 
 68 
 69 out:
 70     up(&receive_sem);
 71 }
 72 
 73 static int send_to_user(struct packet_info *info)
 74 {
 75   int ret;
 76   int size;
 77   unsigned char *old_tail;
 78   struct sk_buff *skb;
 79   struct nlmsghdr *nlh;
 80   struct packet_info *packet;
 81 
 82   size = NLMSG_SPACE(sizeof(*info));
 83 
 84   skb = alloc_skb(size, GFP_ATOMIC);
 85   old_tail = skb->tail;
 86 
 87   nlh = NLMSG_PUT(skb, 0, 0, IMP2_K_MSG, size-sizeof(*nlh));
 88   packet = NLMSG_DATA(nlh);
 89   memset(packet, 0, sizeof(struct packet_info));
 90 
 91   packet->src = info->src;
 92   packet->dest = info->dest;
 93 
 94   nlh->nlmsg_len = skb->tail - old_tail;
 95   NETLINK_CB(skb).dst_group = 0;
 96 
 97   read_lock_bh(&user_proc.lock);
 98   ret = netlink_unicast(nlfd, skb, user_proc.pid, MSG_DONTWAIT);
 99   read_unlock_bh(&user_proc.lock);
100 
101   return ret;
102 
103  nlmsg_failure:
104   if(skb)
105     kfree_skb(skb);
106   return -1;
107 }
108 
109 static unsigned int get_icmp(unsigned int hook,
110                  struct sk_buff *pskb,
111                  const struct net_device *in,
112                  const struct net_device *out,
113                  int (*okfn)(struct sk_buff *))
114 {
115   struct iphdr *iph = ip_hdr(pskb);
116   struct packet_info info;
117 
118   if(iph->protocol == IPPROTO_ICMP)
119     {
120       printk("get a packet.\n");
121       read_lock_bh(&user_proc.lock);
122       if(user_proc.pid != 0)
123     {
124       read_unlock_bh(&user_proc.lock);
125       info.src = iph->saddr;
126       info.dest = iph->daddr;
127       send_to_user(&info);
128     }
129       else
130     read_unlock_bh(&user_proc.lock);
131     }
132 
133   return NF_ACCEPT;
134 }
135 
136 static struct nf_hook_ops imp2_ops =
137 {
138   .hook = get_icmp,
139   .pf = PF_INET,
140   .hooknum = NF_INET_PRE_ROUTING,
141   .priority = NF_IP_PRI_FILTER -1,
142 };
143 
144 static int __init init(void)
145 {
146   rwlock_init(&user_proc.lock);
147 
148   nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL,THIS_MODULE);
149   if(!nlfd)
150     {
151       printk("can not create a netlink socket\n");
152       return -1;
153     }
154 
155   return nf_register_hook(&imp2_ops);
156 }
157 
158 static void __exit fini(void)
159 {
160   if(nlfd)
161     {
162       sock_release(nlfd->sk_socket);
163     }
164   nf_unregister_hook(&imp2_ops);
165 }
166 
167 module_init(init);
168 module_exit(fini);

转载于:https://www.cnblogs.com/handchaos/archive/2012/08/30/2663248.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值