netlink测试程序的编写

来源:互联网 发布:佛山市2015年经济数据 编辑:程序博客网 时间:2024/06/15 08:50

有幸看到文章的童鞋,送上一句话。

linux内核的编程遥遥无期,也不知到何时才是头,至少我们知道未来是光明的,而且也为解决的每一个问题感到兴奋无比。


下面是我查找大牛的相关netlink详解和代码,重新写了一遍,也想大家能自己写一遍,熟悉一下流程。

the kernel moduule:

/**                    how to program use netlink to communicate*                    between the kernel space and the user spaece *                                                         by:dead_angel*                                                       date:Apr.19,2013*//**                        the kernel space module.             */#include<linux/kernel.h>#include<linux/init.h>#include<linux/module.h>#include<net/netlink.h>#include<net/sock.h>#define NETLINK_TEST 25  /*VALUE>16*/#define MAXMSGSIZE 1024int pid = 0;int flag = 0;struct sock* sock = NULL;/* send the message */void nl_sendmsg(char * msg){  //1)declare a struct sk_buff*  //2)declare a struct nlmsghdr *  //3)call alloc_skb() to alloc the struct skb_buff   //4)appenxid the struct nlmsg to the tail of the struct skb_buff  //5)get the nlmsghdt ponit to the field of the struct skb_buff  //6)init the fiels of the nlmsg  //7)insrt the meg into the mlmsg  //8)call the netlink_unicast() to transmit the struct skb_buff  struct sk_buff * skbuftmp = NULL;  struct nlmsghdr* nlh = NULL;   unsigned int len_msg = 0;  //len_msg = get_len(msg);  len_msg=strlen(msg);  int len = NLMSG_SPACE(MAXMSGSIZE);  if(!msg&&!sock)    {      return ;    }  skbuftmp = alloc_skb(len,GFP_KERNEL);  if(!skbuftmp)    {      printk("alloc_skb();failed!\n");       return ;    }  nlh = nlmsg_put(skbuftmp,0,0,0,MAXMSGSIZE,0);  NETLINK_CB(skbuftmp).pid = 0;  NETLINK_CB(skbuftmp).dst_group = 0;  msg[len_msg] = '\0';    memcpy(NLMSG_DATA(nlh),msg,len_msg+1);  printk("the send str = %s \n ", (char*)NLMSG_DATA(nlh));  netlink_unicast(sock,skbuftmp,pid,MSG_DONTWAIT);}/*the callback function */void  nl_data_ready(struct sk_buff* skbuf){  struct completion cmpl;  struct nlmsghdr* nlh = NULL;  struct sk_buff * skbbuftmp = skb_get(skbuf);  if(skbbuftmp->len>=NLMSG_SPACE(0))    {      /* point to the nlmsg */      nlh = nlmsg_hdr(skbbuftmp);      char buf[MAXMSGSIZE] = "";      memcpy(buf,NLMSG_DATA(nlh),MAXMSGSIZE);      printk("the get msg = %s",buf);      pid = nlh->nlmsg_pid;          int i = 10;      while(i--)          {             init_completion(&cmpl);             wait_for_completion_timeout(&cmpl,3*HZ);             nl_sendmsg("this is a kernel program which use the netlink to communicate with the user space !\n");             printk("send ok !\n");          }      flag = 1;      kfree_skb(skbbuftmp);    }}/* the module init */static int netlink_init(void){  printk("the netlink test!\n");  sock = netlink_kernel_create(&init_net,NETLINK_TEST,1,nl_data_ready,NULL,THIS_MODULE);  return 0;}/* the module exit */static void netlink_exit(void){  if(sock!=NULL)    {     sock_release(sock->sk_socket);    }  printk("quit the netlink test!\n");}module_init(netlink_init);module_exit(netlink_exit);MODULE_AUTHOR("dead_angel");MODULE_LICENSE("GPL");

the user program:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/socket.h>#include<sys/types.h>#include<sys/stat.h>#include<linux/socket.h>#include<linux/netlink.h>#define NETLINK_TEST 25#define MAX_PAYLOAD  1024void main(){   /* create the socket */   unsigned int sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_TEST);   if(sock==-1)     {       printf("create the socket frailed!\n");       return ;     }   /* init the src addr */   struct sockaddr_nl  src,dst;   memset(&src,0,sizeof(struct sockaddr_nl));   src.nl_family = AF_NETLINK;   src.nl_pid = getpid();   src.nl_groups = 0;   if(bind(sock,(struct sockaddr*)&src,sizeof(struct sockaddr_nl))<0)     {        printf("bind failed!\n");        close(sock);        return ;     }   /* init the dst addr */   memset(&dst,0,sizeof(struct sockaddr_nl));   dst.nl_family = AF_NETLINK;   dst.nl_pid = 0;   dst.nl_groups = 0;      /* create the netlink packet */   struct nlmsghdr* nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));   if(nlh == NULL)     {        printf("malloc failed!\n");        close(sock);        return;     }   nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);   nlh->nlmsg_pid = getpid();    nlh->nlmsg_flags = 0;   strcpy(NLMSG_DATA(nlh),"hello! the kernel module!\n");     struct iovec iov;   memset(&iov,0,sizeof(struct iovec));   iov.iov_base = (void*)nlh;   iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);     struct msghdr msgh;   memset(&msgh,0,sizeof(struct msghdr));   msgh.msg_name = (void*)&dst;   msgh.msg_namelen = sizeof(struct sockaddr_nl);   msgh.msg_iov = &iov;   msgh.msg_iovlen = 1;   printf("send msg to kernel!\n");   if(sendmsg(sock,&msgh,0)==-1)     {       printf("send failed!\n");       close(sock);       return;     }       memset(nlh,0,NLMSG_SPACE(MAX_PAYLOAD));   printf("begin to recv msg!\n");   while(1)        {           if(recvmsg(sock,&msgh,0)!=-1)            {              printf("msg = %s\n",(char*)NLMSG_DATA(nlh));            }        }       close(sock);   return ;    }

the Makefile:

obj-m := netlink_kernel.oKERNELBUILD := /lib/modules/`uname -r`/build default: @echo "BUILE Kmod" @make -C $(KERNELBUILD) M=$(shell pwd) modules gcc -o netlink_user netlink_user.c clean: @echo " CLEAN kmod" @rm -rf *.o @rm -rf .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers .*.d


原创粉丝点击