阅读:2372回复:4
netlink 2.6.25 及以后的示例,转自网上
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> #include <net/sock.h> #include <net/netlink.h> #define NETLINK_TEST 21 struct sock *nl_sk = NULL; EXPORT_SYMBOL_GPL(nl_sk); void nl_data_ready (struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; u32 pid; int rc; int len = NLMSG_SPACE(1200); char str[100]; printk("net_link: data is ready to read.\n"); skb = skb_get(__skb); if (skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); printk("net_link: recv %s.\n", (char *)NLMSG_DATA(nlh)); memcpy(str,NLMSG_DATA(nlh), sizeof(str)); pid = nlh->nlmsg_pid; /*pid of sending process */ printk("net_link: pid is %d\n", pid); kfree_skb(skb); skb = alloc_skb(len, GFP_ATOMIC); if (!skb){ printk(KERN_ERR "net_link: allocate failed.\n"); return; } nlh = nlmsg_put(skb,0,0,0,1200,0); NETLINK_CB(skb).pid = 0; /* from kernel */ memcpy(NLMSG_DATA(nlh), str, sizeof(str)); printk("net_link: going to send.\n"); rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); if (rc < 0) { printk(KERN_ERR "net_link: can not unicast skb (%d)\n", rc); } printk("net_link: send is ok.\n"); } return; } static int test_netlink(void) { nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE); if (!nl_sk) { printk(KERN_ERR "net_link: Cannot create netlink socket.\n"); return -EIO; } printk("net_link: create socket ok.\n"); return 0; } int init_module() { test_netlink(); return 0; } void cleanup_module( ) { if (nl_sk != NULL){ sock_release(nl_sk->sk_socket); } printk("net_link: remove ok.\n"); } 可惜的是没有发送给用户层数据的代码 MODULE_LICENSE("GPL"); MODULE_AUTHOR("kidoln"); |
|
|
沙发#
发布于:2009-03-02 17:05
linux kernel 在2.6.25及以后, netlink_kernel_create 改了很多,导致以前的代码无法编译.
|
|
|
板凳#
发布于:2009-03-05 22:59
很好. 支持
|
|
|
地板#
发布于:2009-04-09 16:09
再支持一下,今天也用到了。不过znsoft提供的代码有点乱,我先给出一个内核框架版的,然后再给一个应用层的框架版。
#include <linux/kernel.h> #include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> #include <net/sock.h> #include <net/netlink.h> /*--------------------------------------------*/ #define NETLINK_SEC_AUTH 25 /*--------------------------------------------*/ static DEFINE_MUTEX(auth_kernel_mutex); /*--------------------------------------------*/ /* 用户自己的数据逻辑处理 */ static int auth_kernel_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int ret = -1; /* user data type */ u16 msg_type = nlh->nlmsg_type; u32 pid = NETLINK_CREDS(skb)->pid; u32 uid = NETLINK_CREDS(skb)->uid; u32 sessionid = NETLINK_CB(skb).sessionid; uid_t loginuid = NETLINK_CB(skb).loginuid; u32 sid = NETLINK_CB(skb).sid; u32 seq = nlh->nlmsg_seq; void *data = NLMSG_DATA(nlh); if (nlh->nlmsg_len < sizeof(struct your_self data)) { return -EINVAL; } struct your_self status_get = (struct your_self *)data; .... return ret; } /* 获取netlink 中的msg数据, 并验证 */ static void auth_kernel_recv_skb (struct sk_buff *skb) { if ((security_netlink_recv(skb, CAP_NET_ADMIN) == 0) /* 如果应用空间进程不需要权限,则可去掉该句 */ && (skb->len >= NLMSG_SPACE(0))) { int err = 0; int rlen = 0; struct nlmsghdr *nlh = nlmsg_hdr(skb); if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) { return; } rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) { rlen = skb->len; } if ((err = auth_kernel_recv_msg(skb, nlh))) { netlink_ack(skb, nlh, err); } else if (nlh->nlmsg_flags & NLM_F_ACK) { netlink_ack(skb, nlh, err); } skb_pull(skb, rlen); } } /* socket 内核接收来自应用空间的数据 */ static void auth_kernel_data_ready (struct sk_buff *skb) { mutex_lock(&auth_kernel_mutex); / * 如果是多线程,并有全局变量,要加锁保护,防止重入 注意:这里用的是mutex,而不是spin_lock,原因不言自明 */ auth_kernel_recv_skb(skb); mutex_unlock(&auth_kernel_mutex); } /* 初始化或者销毁模块 */ static struct sock *g_nl_sk = NULL; static int __init auth_kernel_init(void) { int ret = -1; g_nl_sk = netlink_kernel_create(&init_net, NETLINK_SEC_AUTH, 0, auth_kernel_data_ready, NULL, THIS_MODULE); if(g_nl_sk) { ret = 0; } return ret; } static void __exit auth_kernel_fini(void) { if(g_nl_sk != NULL) { netlink_kernel_release(g_nl_sk); g_nl_sk = NULL; } } /* 声明 */ module_init(auth_kernel_init) module_exit(auth_kernel_fini) MODULE_LICENSE("GPL"); MODULE_AUTHOR("jonathan <sprbeyond@sohu.com>"); |
|
|
地下室#
发布于:2009-04-10 19:45
感谢你:) 我正好也用到这儿.hehe
|
|
|