Example #1
0
/*
 * Description: This function is called by Linux kernel when user
 *              applications sends a message on netlink socket. It
 *              dequeues the message, calls the functions to process
 *              the commands and sends the result back to user.
 *
 * Input:       skb  - Kernel socket structure
 */
static void
emf_netlink_sock_cb(struct sk_buff *skb)
{
	struct nlmsghdr	*nlh;

	nlh = nlmsg_hdr(skb);
	EMF_DEBUG("Length of the command buffer %d\n", nlh->nlmsg_len);

	/* Check the buffer for min size */
	if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
		nlh->nlmsg_len < NLMSG_LENGTH(sizeof(emf_cfg_request_t)))
	{
		EMF_ERROR("Configuration request size not > %d\n",
		          sizeof(emf_cfg_request_t));
		return;
	}

	skb = skb_clone(skb, GFP_KERNEL);
	if (skb == NULL)
		return;
	nlh = nlmsg_hdr(skb);

	/* Process the message */
	emf_cfg_request_process((emf_cfg_request_t *)NLMSG_DATA(nlh));

	/* Send the result to user process */
	NETLINK_CB(skb).pid = nlh->nlmsg_pid;
	NETLINK_CB(skb).dst_group = 0;

	netlink_unicast(emf->nl_sk, skb, nlh->nlmsg_pid, MSG_DONTWAIT);
}
Example #2
0
/*
 * Description: This function is called by Linux kernel when user
 *              applications sends a message on netlink socket. It
 *              dequeues the message, calls the functions to process
 *              the commands and sends the result back to user.
 *
 * Input:       sk  - Kernel socket structure
 *              len - Length of the message received from user app.
 */
static void
emf_netlink_sock_cb(struct sock *sk, int32 len)
{
	struct sk_buff	*skb;
	struct nlmsghdr	*nlh = NULL;
	uint8 *data = NULL;

	EMF_DEBUG("Length of the command buffer %d\n", len);

	/* Dequeue the message from netlink socket */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
#else
	while ((skb = skb_dequeue(&sk->receive_queue)) != NULL)
#endif
	{
		/* Check the buffer for min size */
		if (skb->len < sizeof(emf_cfg_request_t))
		{
			EMF_ERROR("Configuration request size not > %d\n",
			          sizeof(emf_cfg_request_t));
			return;
		}

		/* Buffer contains netlink header followed by data */
		nlh = (struct nlmsghdr *)skb->data;
		data = NLMSG_DATA(nlh);

		/* Process the message */
		emf_cfg_request_process((emf_cfg_request_t *)data);

		/* Send the result to user process */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
		NETLINK_CB(skb).pid = nlh->nlmsg_pid;
		NETLINK_CB(skb).dst_group = 0;
#else
		NETLINK_CB(skb).groups = 0;
		NETLINK_CB(skb).pid = 0;
		NETLINK_CB(skb).dst_groups = 0;
		NETLINK_CB(skb).dst_pid = nlh->nlmsg_pid;
#endif

		netlink_unicast(emf->nl_sk, skb, nlh->nlmsg_pid, MSG_DONTWAIT);
	}

	return;
}