linux内核调用用户空间程序
//内核发送端----------->
1 #include <linux/netlink.h> 2 #include <linux/kernel.h> 3 #include <linux/module.h> 4 #include <linux/types.h> 5 #include <linux/sched.h> 6 #include <net/sock.h> 7 8 #include <linux/init.h> 9 #include <linux/timer.h> 10 #include <linux/time.h> 11 12 #define NETLINK_TEST 17 13 #define MAX_MSGSIZE 1024 14 struct sock *nl_sk = NULL; 15 16 static int ForkBroadprocess(void); 17 static int netlink_init(void); 18 // Send message by netlink 19 static void sendnlmsg(char *message); 20 static void netlink_exit(void); 21 static int stringlength(char *s); 22 23 24 /* 25 * 开启发送二层广播进程 26 */ 27 static int ForkBroadprocess(void) 28 { 29 netlink_init(); 30 //netlink_exit(); 31 /* 32 static char * argv_init[] = { "/usr/sbin/sendBroadcast", NULL}; 33 char * envp_init[] = {"HOME=/", "TERM=linux", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL}; 34 kernel_execve(argv_init[0], argv_init, envp_init); 35 printk("===============kernel_execve=================\n"); 36 */ 37 return 0; 38 } 39 40 static int netlink_init(void) 41 { 42 if(nl_sk == NULL) 43 { 44 nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, 1,NULL, NULL, THIS_MODULE); 45 } 46 if(!nl_sk){ 47 printk(KERN_ERR "my_net_link: create netlink socket error.\n"); 48 return 1; 49 } 50 51 printk("my_net_link: create netlink socket ok.\n"); 52 sendnlmsg("sendBroadcast"); 53 54 return 0; 55 } 56 57 static int stringlength(char *s) 58 { 59 int slen = 0; 60 61 for(; *s; s++){ 62 slen++; 63 } 64 65 return slen; 66 } 67 68 // Send message by netlink 69 static void sendnlmsg(char *message) 70 { 71 struct sk_buff *skb = NULL; 72 struct nlmsghdr *nlh = NULL; 73 char szMessage[32] = {0}; 74 int len = NLMSG_SPACE(MAX_MSGSIZE); 75 int slen = 0; 76 77 if(!message || !nl_sk){ 78 return; 79 } 80 81 // Allocate a new sk_buffer 82 skb = alloc_skb(len, GFP_KERNEL); 83 if(!skb){ 84 printk(KERN_ERR "my_net_link: alloc_skb Error.\n"); 85 return; 86 } 87 88 slen = stringlength(message); 89 printk("my_net_link: send message slen '%d'.\n", slen); 90 //Initialize the header of netlink message 91 nlh = nlmsg_put(skb, 0, 0, 0, MAX_MSGSIZE, 0); 92 NETLINK_CB(skb).pid = 0; // from kernel 93 NETLINK_CB(skb).dst_group = 1; // multi cast 94 //message[slen] = '/0'; 95 96 memset(szMessage, 0x0, 32); 97 memcpy(szMessage, message, slen); 98 memcpy(NLMSG_DATA(nlh), szMessage, slen + 1); 99 printk("my_net_link: send message '%s'.\n", (char *)NLMSG_DATA(nlh)); 100 101 //send message by multi cast 102 netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL); 103 return; 104 } 105 106 static void netlink_exit(void) 107 { 108 if(nl_sk != NULL){ 109 sock_release(nl_sk->sk_socket); 110 } 111 112 printk("my_net_link: self module exited/n"); 113 }
//用户空间接收端
1 #include <sys/stat.h> 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <sys/socket.h> 6 #include <sys/types.h> 7 #include <string.h> 8 #include <asm/types.h> 9 #include <linux/netlink.h> 10 #include <linux/socket.h> 11 #include <errno.h> 12 #include <sys/time.h> 13 14 #define NETLINK_TEST 17 15 #define MAX_PAYLOAD 1024 // maximum payload size 16 17 static int OperateFun(); 18 19 int main(int argc, char* argv[]) 20 { 21 struct sockaddr_nl src_addr, dest_addr; 22 struct nlmsghdr *nlh = NULL; 23 struct iovec iov; 24 struct msghdr msg; 25 int sock_fd, retval; 26 27 // Create a socket 28 sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST); 29 if(sock_fd == -1){ 30 printf("error getting socket: %s", strerror(errno)); 31 return -1; 32 } 33 printf(" getting socket: %d\n", sock_fd); 34 // To prepare binding 35 memset(&src_addr, 0, sizeof(src_addr)); 36 src_addr.nl_family = AF_NETLINK; 37 src_addr.nl_pid = getpid(); // self pid 38 src_addr.nl_groups = 1; // multi cast 39 printf(" src_addr.nl_pid: %d\n", src_addr.nl_pid); 40 retval = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); 41 if(retval < 0){ 42 printf("bind failed: %s", strerror(errno)); 43 close(sock_fd); 44 return -1; 45 } 46 //printf(" ====================0000\n"); 47 // To prepare recvmsg 48 nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 49 if(!nlh){ 50 printf("malloc nlmsghdr error!/n"); 51 close(sock_fd); 52 return -1; 53 } 54 //printf(" ====================11111\n"); 55 memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); 56 iov.iov_base = (void *)nlh; 57 iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); 58 //printf(" ====================22222\n"); 59 memset(&msg, 0, sizeof(msg)); 60 memset(&dest_addr, 0, sizeof(dest_addr)); 61 msg.msg_name = (void *)&dest_addr; 62 msg.msg_namelen = sizeof(dest_addr); 63 msg.msg_iov = &iov; 64 msg.msg_iovlen = 1; 65 //printf(" ====================33333\n"); 66 // Read message from kernel 67 68 int nSelectRet = 0; 69 fd_set fdReadSet; 70 struct timeval stTimeOut = {0}; 71 72 for(;;) 73 { 74 //wait for a message 75 //printf(" ====================4444444\n"); 76 FD_ZERO(&fdReadSet); 77 FD_SET(sock_fd, &fdReadSet); 78 //printf(" ====================55555555\n"); 79 stTimeOut.tv_sec = 2; 80 stTimeOut.tv_usec = 0; 81 nSelectRet = select(sock_fd + 1, &fdReadSet, NULL, NULL, &stTimeOut); 82 83 84 if(0 > nSelectRet) 85 { 86 printf( "select error !"); 87 } 88 else if(0 == nSelectRet) 89 { 90 printf( "select time out !\n"); 91 92 } 93 else 94 { 95 if(FD_ISSET(sock_fd, &fdReadSet)) 96 { 97 recvmsg(sock_fd, &msg, 0); 98 printf("Received message: %s\n", NLMSG_DATA(nlh)); 99 OperateFun(); 100 } 101 } 102 } 103 close(sock_fd); 104 105 return 0; 106 }