【发布时间】:2019-04-24 10:22:46
【问题描述】:
我正在尝试使内核(Android,内核 4.9.59)与用户空间应用程序通信。我找到了使用 Netlink 套接字的解决方案:https://stackoverflow.com/a/25071310/4190159
解决方案的第一个问题是解决方案中使用的 struct netlink_skb_parms 没有名为“pid”的成员,而是有一个名为“portid”的成员,我认为这与 pid 不同。无论如何,为了编译我的内核端代码/解决方案,我使用了 struct netlink_skb_parms 的“portid”成员来代替初始化。但是,现在我遇到了另一个错误。
我的Kernel端Netlink socket代码如下:
#include <linux/sched.h>
//For netlink socket -->
#include <net/sock.h>
//#include <net/netlink.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#define MY_GROUP 1 //For netlink socket
struct sock* socket; //For netlink socket
struct sk_buff* socket_buff; //For netlink socket
static void nl_receive_callback (struct sk_buff *skb)
{
nlmsg_free(skb);
}
static void kernel_send_nl_msg(void)
{
struct nlmsghdr *nlsk_mh;
char* msg = "hello from kernel";
socket = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 1, nl_receive_callback, NULL, THIS_MODULE);
socket_buff = nlmsg_new(256, GFP_KERNEL);
nlsk_mh = nlmsg_put(socket_buff, 0, 0, NLMSG_DONE, strlen(msg), 0);
//NETLINK_CB(socket_buff).pid = 0; // kernel pid is deprecated
NETLINK_CB(socket_buff).portid = 0;
NETLINK_CB(socket_buff).dst_group = MY_GROUP;
strcpy(nlmsg_data(nlsk_mh), msg);
nlmsg_multicast(socket, socket_buff, 0, MY_GROUP, GFP_KERNEL);
pr_info("%s", msg);//Print out the message to kernel
return;
}
我的用户空间应用端代码截取来自内核的消息如下:
#include <sys/socket.h>
#include <linux/netlink.h>
#define MY_GROUP 1
void user_recieve_nl_msg(void)
{
int sock_fd;
struct sockaddr_nl user_sockaddr;
struct nlmsghdr *nl_msghdr;
struct msghdr msghdr;
struct iovec iov;
char* kernel_msg;
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
memset(&user_sockaddr, 0, sizeof(user_sockaddr));
user_sockaddr.nl_family = AF_NETLINK;
user_sockaddr.nl_pid = getpid();
user_sockaddr.nl_groups = MY_GROUP;
bind(sock_fd, (struct sockaddr*)&user_sockaddr, sizeof(user_sockaddr));
while (1) {
nl_msghdr = (struct nlmsghdr*) malloc(NLMSG_SPACE(256));
memset(nl_msghdr, 0, NLMSG_SPACE(256));
iov.iov_base = (void*) nl_msghdr;
iov.iov_len = NLMSG_SPACE(256);
msghdr.msg_name = (void*) &user_sockaddr;
msghdr.msg_namelen = sizeof(user_sockaddr);
msghdr.msg_iov = &iov;
msghdr.msg_iovlen = 1;
recvmsg(sock_fd, &msghdr, 0);
kernel_msg = (char*)NLMSG_DATA(nl_msghdr);
print("Kernel message: %s\n", kernel_msg); // print to android logs
}
close(sock_fd);
}
当我尝试构建 android 内核时,我收到以下错误:
kernel/sched/custom_code.h:34:65: 错误: 传递参数 3 'netlink_kernel_create' 从整数生成指针,无需强制转换 [-错误]
kernel/sched/custom_code.h:34:14: 错误:参数太多 函数'netlink_kernel_create'
注意内核端的代码写在 custom_code.h 中。
我的问题如下:
我已经检查了函数“netlink_kernel_create”并且我发送了正确数量的参数,那么为什么会出现上述错误?如何解决此错误?
我应该怎么做才能在内核和用户空间应用程序之间建立有效的通信,以便在它们之间传递(来回)消息?
【问题讨论】:
标签: android c linux linux-kernel netlink