用户空间与内核空间通信一(多播)

/******************************************************************************
 *
 * Description:
 *   Netlink multicast kernel testing module.
 *   User space module: client.
 *   Kernel space module: server multicast.
 *
 *  Kernel space
 *****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#define MAX_PAYLOAD 1024
#define NETLINK_TEST 21

#define GRP_ID 1 
/******************************************************************************
 *
 * Description:
 *   Wake up routine.
 *
 * Parameter:
 *   sock:
 *   len:
 *
 * Return:
 *   VOID
 *
 *****************************************************************************/
void nl_data_ready(struct sock *sk, int len)
{
	wake_up_interruptible(sk->sk_sleep);
}

/******************************************************************************
 *
 * Description:
 *   Main function.
 *
 * Parameter:
 *   NULL.
 *
 * Return:
 *   VOID
 *
 *****************************************************************************/
void test_netlink(void)
{
	struct sock *nl_sk = NULL;
	struct sk_buff *skb = NULL;
	struct nlmsghdr *nlh;
	int rval = 0;

	/* Focus */
	nl_sk = netlink_kernel_create(NETLINK_TEST, GRP_ID, 
				nl_data_ready, THIS_MODULE);
	if (nl_sk == NULL) {
		printk("netlink_kernel_create failed\n");
		return;
	}

	if ((skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD), GFP_ATOMIC)) == NULL) {
		printk("alloc_skb failed.\n");
		return;
	}

	/* Initialize send buffer */
	nlh = (struct nlmsghdr*)skb->data;
	nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
	nlh->nlmsg_pid = 0; /* From kernel */
	nlh->nlmsg_flags = 0;
	nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD));
	strcpy(NLMSG_DATA(nlh), "Message from Kernel.\n");

	/* Fill in dest addr */
	/* Focus */
	NETLINK_CB(skb).dst_group = GRP_ID;
	NETLINK_CB(skb).pid = 0; /* From kernel */
	NETLINK_CB(skb).dst_pid = 0; /* Multicast */

	/* Send multicast message from kernel */
	/* Focus */
	while(1) {
		msleep(10000);	
		rval = netlink_broadcast(nl_sk, skb, 0, GRP_ID, GFP_ATOMIC);
		printk("rval = %d\n", rval);
	
		if (rval >= 0) 
			break;
	}
	printk("rval = %d\n", rval);

	sock_release(nl_sk->sk_socket);
}

/******************************************************************************
 *
 * Description:
 *   Init module.
 *
 * Parameter:
 *   NULL
 *
 * Return:
 *   VOID
 *
 *****************************************************************************/

int init_module()
{
	test_netlink();
	return 0;
}

/******************************************************************************
 *
 * Description:
 *  clean up module.
 *  
 * Parameter:
 *  NULL
 *
 * Return:
 *  VOID
 *
 *****************************************************************************/
void cleanup_module()
{
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Guo Xuebin");

你可能感兴趣的:(kernel,netlink,Multicast)