Problem in Netlink
Hi
I am trying to write netlink for Kernel-user interaction. But i am getting lots of problem in that.
Kernel Space source
#define NETLINK_VFW 17
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(2500)
static void nltest_rcv(struct sock *sk, int len)
{
struct nlmsghdr *nl_hdr;
struct sk_buff *nl_skb;
int err;
// nl_skb = skb_recv_datagram(nl_sk, 0, 0, &err);
if(down_trylock(&snif_sem))
return;
while ((nl_skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
{
nl_hdr = (struct nlmsghdr *)nl_skb->data;
if(nl_hdr ==NULL)
break;
pid = nl_hdr->nlmsg_pid;
printk(KERN_ALERT "nltest: message from user (pid = %d) = %s\n", pid, (char*)NLMSG_DATA(nl_hdr));
kfree_skb(nl_skb);
}
up(&snif_sem);
set_sniff_flag = 0;
#if 1
nl_skb = alloc_skb(MSG_SIZE, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
// nl_skb = alloc_skb(MSG_SIZE, GFP_KERNEL);
skb_put(nl_skb, MSG_SIZE);
nl_hdr = (struct nlmsghdr *)nl_skb->data;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = 0;
nl_hdr->nlmsg_flags =NLM_F_DUMP;// 0; // NLM_F_ATOMIC
strcpy(NLMSG_DATA(nl_hdr), "Message from Kernel To user");
NETLINK_CB(nl_skb).pid = 0;
NETLINK_CB(nl_skb).dst_pid = pid;
NETLINK_CB(nl_skb).dst_group = VFW_GROUP;
netlink_unicast(nl_sk, nl_skb, pid, MSG_DONTWAIT);
// netlink_broadcast(nl_sk, nl_skb, 0, 1, GFP_USER);
kfree_skb(nl_skb);
#endif
}
init_module()
{
nl_sk = netlink_kernel_create(NETLINK_VFW, VFW_GROUP, nltest_rcv, THIS_MODULE);
if (!nl_sk) {
printk(KERN_ALERT "nltest: netlink_kernel_create() failed\n");
return -1;
}
}
exit_module()
{
sock_release(nl_sk->sk_socket);
}
User space code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <pthread.h>
//skb_recv_datagram
#define NETLINK_VFW 17
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(2500)
int nl_sd;
unsigned char buf[MSG_SIZE];
struct nlmsghdr *nl_hdr;
struct sockaddr_nl peer = { AF_NETLINK, 0, 0, 0 };
int main(void)
{
int addrlen,status;
struct sockaddr_nl src_addr;
struct msghdr *msg;
int res;
int ret;
memset(&src_addr, 0, sizeof(struct sockaddr_nl));
memset(buf, 0, MSG_SIZE);
nl_sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_VFW);
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
src_addr.nl_groups = VFW_GROUP;
status = bind(nl_sd, (struct sockaddr *)&src_addr, sizeof(struct sockaddr));
if(status == -1)
{
printf(" Bind Failed \n");
return 0;
}
nl_hdr = (struct nlmsghdr *)buf;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = getpid(); // NLMSG_SPACE(MAX_PAYLOAD);
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello kernel");
ret = send(nl_sd, buf, MSG_SIZE, 0);
printf("send ret = %d\n", ret);
printf(" pid = %d\n", nl_hdr->nlmsg_pid);
if (ret == -1)
{
close(nl_sd);
return ret;
}
while (1) {
ret = recv(nl_sd, buf, MSG_SIZE,0);
if(nl_hdr != NULL)
printf("message from kernel = %s\n", (char *)NLMSG_DATA(nl_hdr));
}
close(nl_sd);
return 0;
}
I am able to receive message from both kernel and user .But after that the kernel crashed. Please kelp me
Thanks & Regards
Gonmathisankar.P
|