Broadcast via netlink

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello!

I'm trying to use netlink for sending broacasts from the kernel to 
applications in userspace. I have managed to write a test kernel module and 
an application. The module sends a broadcast and the applications receive it 
and display its payload. For some reason the messages received by the 
applications contain no payloads.

First the applications registers itself into a broadcast group and listens for 
messages. On loading the kernel module it sends the broacast immediately.

[Console 1]
# ./clientnl
Waiting for message from kernel

[Console 2]
# insmod ./netlink.ko

[Console 1]
# ./clientnl
Waiting for message from kernel
 Received message payload:

[Console 2]
# rmmod netlink
#

The payload is a buffer. In the module the buffer is copied with NLMSG_DATA 
into the netlink message before it is sent off to the clients. The client gets 
the payload by using the same macro after the message has been received. 
Thus, sending the broadcast works but the payload gets lost somehow.

I've looked over the code but was not able to find the possible mistake. Could 
you please have a look? I'm thankful for all your suggestions.

The attached files are:
* Makefile: for building netlink.ko and nlclient
* netlink.c: kernel module source file
* nlclient.c: userspace application source file

-Andreas
obj-m += netlink.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
	gcc -o nlclient nlclient.c

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
#include <sys/socket.h>
#include <linux/netlink.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define MAX_PAYLOAD 1024  /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct msghdr msg;
struct iovec iov;
int sock_fd;

int main(int argc, char *argv[]) {
 sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);

 memset(&src_addr, 0, sizeof(src_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\n");

 /* Read message from kernel */
 recvmsg(sock_fd, &msg, 0);
 printf(" Received message payload: %s\n", 
        NLMSG_DATA(nlh));
 close(sock_fd);

 return 0;
}
#include <linux/kernel.h>
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>

#define MAX_PAYLOAD 1024 
struct sock *nl_sk = NULL;

void nl_data_ready (struct sock *sk, int len)
{
  wake_up_interruptible(sk->sk_sleep);
}

void netlink_test(void) {
 struct sk_buff *skb = NULL;
 struct nlmsghdr *nlh;

 nl_sk = netlink_kernel_create(NETLINK_FIREWALL, 
                               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->sk_socket);
}

static int __init init_mod(void)
{
 netlink_test();
 return 0;
}

static void __exit cleanup_mod(void)
{
}

module_init(init_mod);
module_exit(cleanup_mod);

MODULE_LICENSE("GPL");

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux