~~~~MARK~~~~~~~:
看了几遍关于netlink的文章:
Kernel Korner - Why and How to Use Netlink Socket:
http://www.linuxjournal.com/article/7356
对应翻译:
http://bbs.chinaunix.net/thread-2029813-1-1.html
相当不错,感谢!
由于netlink的内容一直在变,这些帖子也是有些年头了,所以具体的调用方法与当前的linux kernel有些不匹配,配合linux-3.14.2的code:
netlink_kernel.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/netlink.h>
#define NETLINK_TEST 17
static struct sock *generic_nlsk;
static void nl_process_data(struct sk_buff *skb)
{
//printk("nl_recv_data in\n");
struct nlmsghdr* nlh = NULL;
void* data = NULL;
printk("skb->len %u\n", skb->len);
if (skb->len >= nlmsg_total_size(0)) {
nlh = nlmsg_hdr(skb);
//printk("nlh->nlmsg_len %u, nlh->nlmsg_flags %u, nlh->nlmsg_pid %u\n", nlh->nlmsg_len, nlh->nlmsg_flags, nlh->nlmsg_pid);
data = NLMSG_DATA(nlh);
if (data) {
printk("data: %s\n", (char*)data);
}
//printk("NETLINK_CB(skb).portid %u\n", NETLINK_CB(skb).portid);
//netlink_unicast(skb->sk, skb, NETLINK_CB(skb).portid, MSG_DONTWAIT);
}
return;
}
static int netlink_k_init(void)
{
struct netlink_kernel_cfg cfg = {
.input = nl_process_data,
};
generic_nlsk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
if (!generic_nlsk) {
printk("create NETLINK_GENERIC fail!\n");
return -1;
}
printk("create NETLINK_GENERIC done\n");
return 0;
}
static int netlink_init(void)
{
printk("netlink_k init\n");
netlink_k_init();
return 0;
}
static void netlink_exit(void)
{
if (generic_nlsk) {
netlink_kernel_release(generic_nlsk);
}
printk("netlink exit\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chuchen");
module_init(netlink_init);
module_exit(netlink_exit);
user.c参考以上链接的帖子就可以了。
主要的变动:
1 create API
2 struct nlmsghdr定义