Netlink problem

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

 



Hi All,
My kernel module use netlink socket to communicate with my program user space the kernel code is show bellow. the code was compile and load succesfull. but when my program in user space try to connect to my kernel module then my computer is hang. Could someone help me to fixed this thank you very much and appreciate for help

Kernel code:

struct des_sock{
  u32 p_grp;
  u32 p_pid;
};

struct sock *g_mntr_sock;
struct usr_msg_t *usrmsg;
struct sk_buff *skb;
struct des_sock desip;

int mntr_create_handler()
{

g_mntr_sock=netlink_kernel_create(NETLINK_MONITOR,mntr_recieved_from_user);
  if (!g_mntr_sock){
                return -ENOMEM;
  }else{
    printk("Could not create netlink socket sucess \n");
    return 1;
  }
}
int send_to_user(struct sk_buff *skb_msg)
{
    int status=0;
    if (skb_msg == NULL)
    {
      printk(" Message send to user was null \n");
      return -1;
    }
    //from kernel
    NETLINK_CB(skb_msg).groups=0;
    NETLINK_CB(skb_msg).pid=0;

    //to user process
    NETLINK_CB(skb_msg).dst_groups=desip.p_grp;
    NETLINK_CB(skb_msg).dst_pid=desip.p_pid;

    status=netlink_unicast(g_mntr_sock,skb_msg,desip.p_pid,MSG_DONTWAIT);
    if (status <  0)
    {
      printk("Message could not send to user space \n");
    }
    else if (status == 0 )
    {
printk("NO!!! Message was sent %i byte to user space \n",status);
    }
    else
    {
      printk("Message was sent %i byte to user space \n",status);
    }

    return status;
}

static inline void mntr_rcv_skb(struct sk_buff *skb)
{
	int type, flags, nlmsglen, skblen;
	struct nlmsghdr *nlh;

	skblen = skb->len;
	if (skblen < sizeof(*nlh))
  {
    printk("skblen < sizeof(*nlh) Message was broken\n");
    return;
  }


	nlh = (struct nlmsghdr *)skb->data;
	nlmsglen = nlh->nlmsg_len;
	if (nlmsglen < sizeof(*nlh) || skblen < nlmsglen)
  {
printk("nlmsglen < sizeof(*nlh) || skblen < nlmsglen Message was broken \n");
    return;
  }
	desip.p_grp=0;
  desip.p_pid= nlh->nlmsg_pid;

  printk("%s Process user id %i \n",__FUNCTION__,desip.p_pid);

	flags = nlh->nlmsg_flags;
	type = nlh->nlmsg_type;

  usrmsg=NLMSG_DATA(nlh);
}

void mntr_recieved_from_user(struct sock *sk,int len)
{
  struct sk_buff *skb;
  struct nlmsghdr *nlh;
  if (!g_mntr_sock)
                return;
  while((skb=skb_dequeue(&sk->receive_queue)) != NULL)
  {
    mntr_rcv_skb(skb);
    nlh = (struct nlmsghdr *)skb->data;
    printk("%s: message received: %s \n",__FUNCTION__,NLMSG_DATA(nlh));
    send_to_user(skb);
    //kfree_skb(skb);
  }
}
My client code:
int fd;
struct sockaddr_nl proces_sk;
struct sockaddr_nl krnl_sk;
struct msghdr msg;
struct nlmsghdr *nlhdr;
struct iovec iov;


int main()
{
  int status=0;
  //char buf[MONITOR_BUFF_SIZE];

  u_int32_t rcvbufsize=150000;


  fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_MONITOR);


  memset(&proces_sk,0,sizeof(proces_sk));
  proces_sk.nl_family=AF_NETLINK;
  proces_sk.nl_pid=getpid();
  proces_sk.nl_groups=0;

  status =bind(fd,(struct sockaddr *)&proces_sk,sizeof(proces_sk));
  if(status < 0){
    perror("Binding..");
    printf("Could not bind \n");
    return -1;
  }
  status = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
			    sizeof(rcvbufsize));
  nlhdr =(struct nlmsghdr *)malloc(NLMSG_SPACE(MONITOR_BUFF_SIZE));

  //initialize nl message header
  nlhdr->nlmsg_len=NLMSG_SPACE(MONITOR_BUFF_SIZE);
  nlhdr->nlmsg_pid=getpid();
  nlhdr->nlmsg_type=NETLINK_MONITOR;
  nlhdr->nlmsg_flags=0;

  strcpy(NLMSG_DATA(nlhdr),"Hello kernel, I am from user space");

  iov.iov_base = (void *)nlhdr;
  iov.iov_len = nlhdr->nlmsg_len;

  msg.msg_name = (void *)&krnl_sk;  /* optional address */
  msg.msg_namelen = sizeof(krnl_sk);/* size of address */
  msg.msg_iov =&iov;                /* scatter/gather array */
  msg.msg_iovlen=1;
  sendmsg(fd,&msg,0);


  //send to kernel
  memset(&krnl_sk,0,sizeof(krnl_sk));
  krnl_sk.nl_family=AF_NETLINK;
  krnl_sk.nl_pid=0;
  krnl_sk.nl_groups=0;
  recvmsg(fd,&msg,0);


  close(fd);
  return 0;
}

Nhanle


--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[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