1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | | #include <stdio.h> #include <string.h> #include <malloc.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <ctype.h> #include <sys/select.h> #include <netinet/in.h> #include <linux/types.h> #include <linux/if.h> #include <linux/netlink.h> #include <stdlib.h> #include <linux/wireless.h>
#define MAX_PAYLOAD 2048 /* maximum payload size*/ #ifndef NETLINK_CTCWIFI_DIAG_2G #define NETLINK_CTCWIFI_DIAG_2G 23 //协议号 #endif
int main(int argc, char *argv[]) { int state; struct sockaddr_nl src_addr, dest_addr; struct nlmsghdr *nlh = NULL; struct iovec iov; struct msghdr msg; int sock_fd,retval,protocol; int state_smg = 0; T_CTCWIFI_DIAG_EVENT event; //T_CTCWIFI_DIAG_EVENT 为自己定义的数据结构体类型,这里不方便给出。
sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_CTCWIFI_DIAG_2G); //创建一个socket描述符 if(sock_fd == -1) { printf("socket fail,Mesg is %s\n",strerror(errno)); exit(errno); }
memset(&src_addr, 0, sizeof(src_addr)); src_addr.nl_family = AF_NETLINK; src_addr.nl_pid = getpid(); /* self pid */ src_addr.nl_groups = 0; /*单播设置成0*/ /*将socket描述符绑定到接收地址, 函数 bind() 用于把一个打开的 netlink socket 和 netlink 源 socket 地址绑定在一起*/ retval = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); if (retval < 0) { printf("bind error,Mesg is %s\n",strerror(errno)); close(sock_fd); exit(errno); }
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); if(nlh == NULL) { close(sock_fd); return -1; }
memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.nl_family = AF_NETLINK; dest_addr.nl_pid = 0; dest_addr.nl_groups = 0;
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh),"Hello Kernel!");
memset(&iov,0,sizeof(iov)); iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1;
state_smg = sendmsg(sock_fd,&msg,0); //向内核发送"Hello Kernel!"便于内核获取应用层进程的pid号。 if(state_smg == -1) { printf("sendmsg error,Mesg is %s\n",strerror(errno)); }
while(1) { /* Read message from kernel */ memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); state = recvmsg(sock_fd, &msg, 0); //开始接收uevent if(state < 0) { printf("recvmsg error,Mesg is %s\n",strerror(errno)); }
memcpy(&event, NLMSG_DATA(nlh), sizeof(event)); /*handle kernel msg*/ /*handle kernel msg*/ /*handle kernel msg*/ } free(nlh); close(sock_fd); return 0; } |