Cha*_*pps 1 c linux networking linux-kernel
我正在编写一个使用netlink的Linux驱动程序来在用户空间和内核空间之间进行通信.但是我找不到一些有用的资料,因为netlink已经从Linux内核> = 2.6.24改变了.谁可以给我一些关于如何创建netlink套接字的建议.提前致谢!
下面的代码演示了使用netlink将数据从用户空间应用程序发送到内核模块的基础知识.此代码适用于Linux 2.6.28.9,其中包含libnl的git版本(ef8ba32).有关更多详细信息,请查看libnl 文档以及广泛使用netlink的iw代码.
核心
#include <linux/kernel.h>
#include <linux/module.h>
#include <net/sock.h>
#include <net/netlink.h>
#define MY_MSG_TYPE (0x10 + 2) // + 2 is arbitrary. same value for kern/usr
static struct sock *my_nl_sock;
DEFINE_MUTEX(my_mutex);
static int
my_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
int type;
char *data;
type = nlh->nlmsg_type;
if (type != MY_MSG_TYPE) {
printk("%s: expect %#x got %#x\n", __func__, MY_MSG_TYPE, type);
return -EINVAL;
}
data = NLMSG_DATA(nlh);
printk("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", __func__,
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]);
return 0;
}
static void
my_nl_rcv_msg(struct sk_buff *skb)
{
mutex_lock(&my_mutex);
netlink_rcv_skb(skb, &my_rcv_msg);
mutex_unlock(&my_mutex);
}
static int
my_init(void)
{
my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0,
my_nl_rcv_msg, NULL, THIS_MODULE);
if (!my_nl_sock) {
printk(KERN_ERR "%s: receive handler registration failed\n", __func__);
return -ENOMEM;
}
return 0;
}
static void
my_exit(void)
{
if (my_nl_sock) {
netlink_kernel_release(my_nl_sock);
}
}
module_init(my_init);
module_exit(my_exit);
Run Code Online (Sandbox Code Playgroud)
用户空间
#include <stdio.h>
#include <stdlib.h>
#include <netlink/netlink.h>
#define MY_MSG_TYPE (0x10 + 2) // + 2 is arbitrary but is the same for kern/usr
int
main(int argc, char *argv[])
{
struct nl_sock *nls;
char msg[] = { 0xde, 0xad, 0xbe, 0xef, 0x90, 0x0d, 0xbe, 0xef };
int ret;
nls = nl_socket_alloc();
if (!nls) {
printf("bad nl_socket_alloc\n");
return EXIT_FAILURE;
}
ret = nl_connect(nls, NETLINK_USERSOCK);
if (ret < 0) {
nl_perror(ret, "nl_connect");
nl_socket_free(nls);
return EXIT_FAILURE;
}
ret = nl_send_simple(nls, MY_MSG_TYPE, 0, msg, sizeof(msg));
if (ret < 0) {
nl_perror(ret, "nl_send_simple");
nl_close(nls);
nl_socket_free(nls);
return EXIT_FAILURE;
} else {
printf("sent %d bytes\n", ret);
}
nl_close(nls);
nl_socket_free(nls);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)