上一节说到proc文件系统,这是用户态和内核态通信的一种方法,本节将要说到另外一种通信的方法,该方法相比于其他的内核和用户通信有时在于:
Netlink相对于其他的通信机制具有以下优点:
1.使用Netlink通过自定义一种新的协议并加入协议族即可通过socket API使用Netlink协议完成数据交换,而ioctl和proc文件系统均需要通过程序加入相应的设备或文件。
2.Netlink使用socket缓存队列,是一种异步通信机制,而ioctl是同步通信机制,如果传输的数据量较大,会影响系统性能。
3.Netlink支持多播,属于一个Netlink组的模块和进程都能获得该多播消息。
4.Netlink允许内核发起会话,而ioctl和系统调用只能由用户空间进程发起。
建立netlink会话如下:
1.在内核使用netlink_kernel_create()创建套接字,指明接受函数。
2.在用户态创建套接字,并将进程ID发送至内核空间。
3.内核接受函数收到用户空间进程ID。
4.用户空间与内核空间可以通信。
需要详细描述的内容太多,下面直接给一个例子算了,以后有时间在细说,
下面是内核部分代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h> //LINUX_VERSION_CODE
#include <net/sock.h> //struct sock *
#include <linux/netlink.h> //netlink_kernel_create()
#include <linux/sched.h>
#include “netlink_k.h”
static struct sock *nlfd;
static int pid;
int netlink_deliver(uint16_t type, void *data, unsigned short dlen)
{
int ret, len;
char *old_tail;
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh = NULL;
if (0 == pid) {
return 0;
}
len = NLMSG_SPACE(dlen + sizeof(unsigned short));
skb = alloc_skb(len, GFP_ATOMIC);
if (NULL == skb) {
printk(KERN_ALERT"alloc skb failed!\n");
goto nlmsg_failure;
}
old_tail = (char *)skb->tail;
nlh = NLMSG_PUT(skb, 0, 0, type, len - sizeof(*nlh));
memcpy((char *)NLMSG_DATA(nlh), &dlen, sizeof(unsigned short));
memcpy((char *)NLMSG_DATA(nlh) + sizeof(unsigned short), data, dlen);
nlh->nlmsg_len = (char *)skb->tail - (char *)old_tail;
NETLINK_CB(skb).dst_group = 0;
http://groups.tianya.cn/post-165167-1000a2405f104deeb930d447d0307819-1.shtml
printk(KERN_ALERT"Send: data: %s, dlen = %d, nlh