- 论坛徽章:
- 0
|
谢谢各位的帮助,代码改了一下现在可以从userspace像kernel发送并且成功收到了,但是kernel返回的消息userspace还是收不到,recvmsg 一直返回 0
内核代码如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <net/sock.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/netlink.h>
#define MAX_PAYLOAD 1024
struct sock *nl_sk = NULL;
u32 pid = 0;
void nl_data_ready (struct sk_buff *skb)
{ struct sk_buff *skb2 = NULL;
printk("input()called\n");
struct nlmsghdr *nlh = NULL;
nlh = (struct nlmsghdr *)skb->data;
printk("%s: received netlink message payload:%s\n",
__FUNCTION__, NLMSG_DATA(nlh));
pid = nlh->nlmsg_pid;
printk("pid = %d\n",pid);
if(pid !=0){
skb2 = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
printk("skb allocated\n");
nlh = (struct nlmsghdr *)skb2->data;
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 0;
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh),"Greeting From Kernel!");
NETLINK_CB(skb2).pid = 0;
NETLINK_CB(skb2).dst_group = 0;
printk("ready to unicast\n");
if(netlink_unicast(nl_sk, skb2, pid, MSG_DONTWAIT)<0)
printk("error unicast\n");
else printk("unicasted to pid:%u \n",pid);
}//endif
}
void netlink_test(){
//struct net net1;
nl_sk = netlink_kernel_create(&init_net,25,0,
nl_data_ready,NULL,THIS_MODULE);
if(nl_sk<0)
printk("error create sock\n");
else printk("successful create socket\n");
}
static int my_module_init(void){
printk(KERN_INFO "initializing Netlink Socket!\n");
netlink_test();
return 0;
}
static void netlink_clear(void)
{ sock_release(nl_sk->sk_socket);
printk(KERN_INFO"GOod Bye!\n");
}
module_init(my_module_init);
module_exit(netlink_clear); |
userspace代码如下#include <sys/socket.h>
#include <linux/netlink.h>
#include <iostream>
//#include <sys/socket.h>
#include <linux/types.h>
//#include <linux/netlink.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
using namespace std;
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
struct msghdr msg;
int main(){
std::cout<<("error bind")<<std::endl;
int sock_fd = socket(PF_NETLINK, SOCK_RAW,25);
if (sock_fd <0)
std::cout<<("error create socket!")<<std::endl;
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); /* self pid */
src_addr.nl_groups = 0; /* not in mcast groups */
if (bind(sock_fd, (struct sockaddr*)&src_addr,sizeof(src_addr))<0)
std::cout<<("error bind")<<std::endl;
else std::cout<<("binded")<<std::endl;
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */
nlh=(struct nlmsghdr *)malloc(
NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = getpid(); /* self pid */
nlh->nlmsg_flags = 0;
/* Fill in the netlink message payload */
strcpy((char *)NLMSG_DATA(nlh), "Hello you!");
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
printf("%d\n",iov.iov_len);
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
if(sendmsg(sock_fd, &msg, 0) == -1){
std::cout<<("error send")<<errno<<std::endl;
}
else std::cout<<("sent")<<std::endl;
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
printf("nlh set to be %s\n",NLMSG_DATA(nlh));
int ret = recvmsg(sock_fd, &msg, 0);
if( ret < 0)
std::cout<<("error recv")<<errno<<std::endl;
else std::cout<<("received")<<ret<<std::endl;
printf("Received message payload:%s\n from kernel, length is %d\n",(char *)(NLMSG_DATA(nlh)),nlh->nlmsg_len);
/* Close Netlink Socket */
close(sock_fd);
} |
[ 本帖最后由 overcloud 于 2009-2-27 16:39 编辑 ] |
|