- 论坛徽章:
- 0
|
需要在2.6.32下面使用netlink从内核向用户空间广播消息,
看过多个netlink的实例,移植到2.6.32上,由于NETLINK_CB和skb的定义不同了,
因此都需要修改,最终还是能够成功编译,但是,这些实例多数都是从用户空间发起通信,
然后从内核里面响应,再发回到(单播或者广播)用户空间,而我需要的是内核向用户空间广播消息,
倒是看到了一个实例,就是http://www.diybl.com/course/6_sy ... 20071226/94120.html里面的,提到了广播的问题,如下:
>>>>>>>>>>>>>>>>>>引用的 华丽的分割线 开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
两个应用程序在监听同一个netlink广播组.内核模块发送一个netlink消息给这个广播组,所用的应用程序都收到它,代码如下:
#include <sys/socket.h>
#include <linux/netlink.h>
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
void main() ...{
sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
memset(&src_addr, 0, sizeof(local_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); /**//* self pid */
/**//* interested in group 1<<0 */
src_addr.nl_groups = 1;
bind(sock_fd, (struct sockaddr*)&src_addr,
sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
nlh = (struct nlmsghdr *)malloc(
NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
iov.iov_base = (void *)nlh;
iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
printf("Waiting for message from kernel ");
/**//* Read message from kernel */
recvmsg(fd, &msg, 0);
printf(" Received message payload: %s ",
NLMSG_DATA(nlh));
close(sock_fd);
}
内核代码:
#define MAX_PAYLOAD 1024
struct sock *nl_sk = NULL;
void netlink_test() ...{
sturct sk_buff *skb = NULL;
struct nlmsghdr *nlh;
int err;
nl_sk = netlink_kernel_create(NETLINK_TEST,
nl_data_ready);
skb=alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
nlh = (struct nlmsghdr *)skb->data;
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 0; /**//* from kernel */
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh), "Greeting from kernel!");
/**//* sender is in group 1<<0 */
NETLINK_CB(skb).groups = 1;
NETLINK_CB(skb).pid = 0; /**//* from kernel */
NETLINK_CB(skb).dst_pid = 0; /**//* multicast */
/**//* to mcast group 1<<0 */
NETLINK_CB(skb).dst_groups = 1;
/**//*multicast the message to all listening processes*/
netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL);
sock_release(nl_sk->socket);
}
我们运行用户程序:
./nl_recv &
Waiting for message from kernel
./nl_recv &
Waiting for message from kernel
然后我们加载内核模块到内核空间,会看到如下信息::
Received message payload: Greeting from kernel!
Received message payload: Greeting from kernel!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>引用的华丽的分割线 结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
这个我修改移植到2.6.32上,由于版本不同,必须修改netlink_kernel_create的参数,删除了NETLINK_CB(skb).dst_pid,
但是运行的时候,却没有得到预期的广播效果。
请教,问题在哪里呢?
内核是我重新编译配置过的,是否有内核选项需要额外注意呢?
谢谢!!
|
|