Netlink socket problem

From: Mikado
Date: Sat Jan 07 2006 - 02:02:07 EST


Hi,

I write a kernel module and a userspace client. They use netlink sockets to communicate with each
other. The source codes are attached below. Inserting the module is ok but when I ran the client,
my kernel crashed after the client received first message from the module. Is there anything wrong
in my codes?

Thank you.

=== nltest.c - kernel module ===
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <net/sock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>

#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)

static struct sock *nl_sk = NULL;

static void nltest_rcv(struct sock *sk, int len)
{
struct sk_buff *nl_skb;
struct nlmsghdr *nl_hdr;
int pid;

while ((nl_skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
nl_hdr = (struct nlmsghdr *)nl_skb->data;
pid = nl_hdr->nlmsg_pid;
printk(KERN_ALERT "nltest: message from user (pid = %d) = %s\n", pid, (char
*)NLMSG_DATA(nl_hdr));
nl_skb = alloc_skb(MSG_SIZE, in_interrupt() ? GFP_ATOMIC : 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 = pid;
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello user abcd1234");
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, 0);
kfree_skb(nl_skb);
}
}

static int __init nltest_init(void)
{
printk(KERN_ALERT "nltest: init\n");

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;
}

return 0;
}

static void __exit nltest_exit(void)
{
printk(KERN_ALERT "nltest: exit\n");

sock_release(nl_sk->sk_socket);

return;
}

module_init(nltest_init);
module_exit(nltest_exit);

MODULE_DESCRIPTION("Netlink Test");
MODULE_LICENSE("GPL");

=== nlclient.c - userspace client ===
#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>

#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)

int main(void)
{
int nl_sd;
struct sockaddr_nl src_addr;
struct nlmsghdr *nl_hdr;
unsigned char buf[MSG_SIZE];
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;

bind(nl_sd, (struct sockaddr *)&src_addr, sizeof(struct sockaddr));

nl_hdr = (struct nlmsghdr *)buf;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = getpid();
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);
if (ret == -1)
return ret;

while (1) {
ret = recv(nl_sd, buf, MSG_SIZE, 0);
printf("message from kernel = %s\n", (char *)NLMSG_DATA(nl_hdr));
}

return 0;
}

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Attachment: nltest.c
Description: 938020532-nltest.c

Attachment: nlclient.c
Description: 3903798118-nlclient.c