sockets - Unable to receive customized message sent from kernel module to user application using NETLINK_ROUTE channel -


i working netlink sockets send customized notifications regarding state of ethernet interface kernel module user space application on netlink_route channel. have gone through several articles , papers of them demonstrate approach need define own family e.g. netlink_test in netlink.h header or using netlink_generic. aware socket using netlink_route owned kernel 1 cannot create in kernel module. unable receive message in user space. guidance highly appreciated. here 2 codes:

kernel module:

#include <linux/notifier.h> #include <asm/kdebug.h>  #include <linux/netdevice.h> #include <linux/inetdevice.h> #include <linux/module.h> #include <net/sock.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <asm/types.h> #include <linux/skbuff.h>  module_license("gpl");  int my_dev_event_handler(struct notifier_block *this, unsigned long event, void *ptr) { struct sk_buff *skb = null; struct nlmsghdr *nlh; int size = 0; char buf[512];  switch (event) {     case netdev_register:             sprintf (buf, "interface:: %s registered notifier...", ((struct net_device *) ptr)->name);             break;      case netdev_up:             sprintf (buf, "interface:: %s , running...", ((struct net_device *) ptr)->name);             break;      case netdev_going_down:             sprintf (buf, "interface:: %s going down...", ((struct net_device *) ptr)->name);             break;      case netdev_down:             sprintf (buf, "interface:: %s down...", ((struct net_device *) ptr)->name);             break;     }  printk (kern_info "content of buf :: %s" , buf);      size = sizeof(buf);  skb = nlmsg_new(size, gfp_atomic);  if (skb == null)     {         printk(kern_err "\nerror allocating skb sending netlink message...\n");         return -1;     }  nlh = nlmsg_put(skb, 0, 0, nlmsg_done, size, 0); if (nlh == null)     {         printk(kern_err "\nerror putting netlink message data skb...\n");         goto nlmsg_failure;         }         netlink_cb(skb).dst_group = rtnlgrp_link;     strncpy(nlmsg_data(nlh), buf, size);     nlmsg_end(skb, nlh);      rtnl_notify(skb, &init_net, 0, rtnlgrp_link, nlh, 0);  return 0;  nlmsg_failure: kfree_skb(skb); return -emsgsize;  }  static struct notifier_block my_dev_notifier =  { .notifier_call = my_dev_event_handler, };  static int __init my_init (void) { printk(kern_alert "***ifm module loaded***\n"); register_netdevice_notifier (&my_dev_notifier);  return 0; }  static void __exit my_end(void) { printk(kern_alert "***ifm module unloaded***\n"); unregister_netdevice_notifier (&my_dev_notifier); }  module_init(my_init); module_exit(my_end); 

user space application:

#include <asm/types.h> #include <sys/socket.h> #include <unistd.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <net/if.h> #include <netinet/in.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h>  #define max_payload 1024  struct sockaddr_nl src_addr, dest_addr;  int read_event (int sockint) { int status; int ret = 0; char buf[4096]; struct iovec iov = { buf, sizeof(buf) }; struct msghdr msg = { (void *) &dest_addr, sizeof dest_addr, &iov, 1, null, 0, 0 }; struct nlmsghdr *h;  h = (struct nlmsghdr *)malloc(nlmsg_space(max_payload));     memset(h, 0, nlmsg_space(max_payload));     h->nlmsg_len = nlmsg_space(max_payload);     h->nlmsg_pid = getpid();     h->nlmsg_flags = 0;  strcpy(nlmsg_data(h), "hello"); printf("sending message kernel\n");     sendmsg(sockint, &msg, 0);  printf("waiting message kernel\n"); memset(h, 0, nlmsg_space(max_payload));  status = recvmsg (sockint, &msg, 0);  if (status < 0)     {             if (errno == ewouldblock || errno == eagain)                     return ret;              printf ("read_netlink: error recvmsg: %d\n", status);             perror ("read_netlink: error: ");             return status;     }      if (status == 0)     {             printf ("read_netlink: eof\n");     } printf("\nno. of bytes read : %d\n", status); printf("received payload data : %s", nlmsg_data (h)); return ret; }  int main (void) { fd_set rfds; struct timeval tv; int retval;  int nl_socket = socket (af_netlink, sock_raw, netlink_route);   if (nl_socket < 0)  {  printf ("socket open error!");  exit (1);  }   memset ((void *) &src_addr, 0, sizeof (src_addr));  src_addr.nl_family = af_netlink; src_addr.nl_pid = getpid (); //src_addr.nl_pid = 0; src_addr.nl_groups = rtmgrp_link; //src_addr.nl_groups = rtmgrp_link | rtmgrp_ipv4_ifaddr | rtmgrp_ipv6_ifaddr;  if (bind (nl_socket, (struct sockaddr *) &src_addr, sizeof (src_addr)) < 0) {     printf ("socket bind failed!");     exit (1); }  memset(&dest_addr, 0, sizeof(dest_addr));     dest_addr.nl_family = af_netlink;     dest_addr.nl_pid = 0; /* linux kernel */     dest_addr.nl_groups = 0; /* unicast */  while (1) {     fd_zero (&rfds);     //fd_clr (nl_socket, &rfds);     fd_set (nl_socket, &rfds);      tv.tv_sec = 5;     tv.tv_usec = 0;      retval = select (fd_setsize, &rfds, null, null, &tv);      if (retval == -1)         printf ("error in select() \n");      else if (retval)     {         printf ("event received >> ");         read_event (nl_socket);     }      else         printf ("## select timed out ## \n"); }  return 0; } 

i think mistake should cast buf struct nlmsghdr * , fill info.

char buf[4096]; struct iovec iov = { buf, sizeof(buf) }; struct msghdr msg = { (void *) &dest_addr, sizeof dest_addr, &iov, 1, null, 0, 0 }; struct nlmsghdr *h;  memset(buf, 0, sizeof(buf)); h = (struct nlmsghdr *)buf; h->nlmsg_len = nlmsg_space(max_payload); h->nlmsg_pid = getpid(); h->nlmsg_flags = 0;  strcpy(nlmsg_data(h), "hello"); printf("sending message kernel\n"); sendmsg(sockint, &msg, 0); 

Comments

Popular posts from this blog

java - How to specify maven bin in eclipse maven plugin? -

single sign on - Logging into Plone site with credentials passed through HTTP -

php - Why does AJAX not process login form? -