代码: |
struct sodkaddr_nl { sa_family_t nl_family; /*AF_NETLINK*/ unsigned short nl_pad; /*zero*/ __u32 nl_pid; /*process pid*/ __u32 nl_groups; /*mcast groups mask*/ }nladdr; |
代码: |
struct nlmsghdr { __u32 nlmsg_len; /* Length of message */ __u16 nlmsg_type; /* Message type*/ __u16 nlmsg_flags; /* Additional flags */ __u32 nlmsg_seq; /* Sequence number */ __u32 nlmsg_pid; /* Sending process PID */ }; |
代码: |
struct iovec iov; iov.iov_base = (void *)nlh; iov.iov_len = nlh->nlmsg_len; msg.msg_iov = &iov; msg.msg_iovlen = 1; |
代码: |
struct sockaddr_nl nladdr; struct msghdr msg; struct iovec iov; iov.iov_base = (void *)nlh; iov.iov_len = MAX_NL_MSG_LEN; msg.msg_name = (void *)&(nladdr); msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; recvmsg(fd, &msg, 0); |
引用: |
#define NETLINK_TEST 17 |
代码: |
struct sock * netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)); |
代码: |
void input (struct sock *sk, int len) { struct sk_buff *skb; struct nlmsghdr *nlh = NULL; u8 *payload = NULL; while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { /* process netlink message pointed by skb->data */ nlh = (struct nlmsghdr *)skb->data; payload = NLMSG_DATA(nlh); /* process netlink message with header pointed by * nlh and payload pointed by payload */ } |
代码: |
void input (struct sock *sk, int len) { wake_up_interruptible(sk->sleep); } |
代码: |
NETLINK_CB(skb).groups = local_groups; NETLINK_CB(skb).pid = 0; /* from kernel */ |
代码: |
NETLINK_CB(skb).dst_groups = dst_groups; NETLINK_CB(skb).dst_pid = dst_pid; |
代码: |
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock); |
代码: |
void netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, u32 group, int allocation); |
代码: |
sock_release(nl_sk->socket); |
代码: |
#i nclude #i nclude #define MAX_PAYLOAD 1024 /* maximum payload size*/ struct sockaddr_nl src_addr, dest_addr; struct nlmsghdr *nlh = NULL; struct iovec iov; int sock_fd; void main() { sock_fd = socket(PF_NETLINK, SOCK_RAW,NETLINK_TEST); 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; /* not in mcast groups */ bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.nl_family = AF_NETLINK; dest_addr.nl_pid = 0; /* For Linux Kernel */ dest_addr.nl_groups = 0; /* unicast */ nlh=(struct nlmsghdr *)malloc( NLMSG_SPACE(MAX_PAYLOAD)); /* Fill the netlink message header */ nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); /* self pid */ nlh->nlmsg_flags = 0; /* Fill in the netlink message payload */ strcpy(NLMSG_DATA(nlh), "Hello you!"); iov.iov_base = (void *)nlh; iov.iov_len = nlh->nlmsg_len; msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; sendmsg(fd, &msg, 0); /* Read message from kernel */ memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); recvmsg(fd, &msg, 0); printf(" Received message payload: %s\n", NLMSG_DATA(nlh)); /* Close Netlink Socket */ close(sock_fd); } |
代码: |
#i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude struct sock *nl_sk = NULL; void nl_data_ready (struct sock *sk, int len) { wake_up_interruptible(sk->sleep); } void netlink_test() { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; int err; u32 pid; nl_sk = netlink_kernel_create(NETLINK_TEST, nl_data_ready); /* wait for message coming down from user-space */ skb = skb_recv_datagram(nl_sk, 0, 0, &err); nlh = (struct nlmsghdr *)skb->data; printk("%s: received netlink message payload:%s\n", __FUNCTION__, NLMSG_DATA(nlh)); pid = nlh->nlmsg_pid; /*pid of sending process */ NETLINK_CB(skb).groups = 0; /* not in mcast group */ NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_pid = pid; NETLINK_CB(skb).dst_groups = 0; /* unicast */ netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); sock_release(nl_sk->socket); } static int my_module_init(void){ printk(KERN_INFO "initializing Netlink Socket!\n"); netlink_test(); return 0; } static void netlink_clear(void) { printk(KERN_INFO"GOod Bye!\n"); } module_init(my_module_init); module_exit(netlink_clear); |
引用: |
Received message payload: Hello you! |
引用: |
netlink_test: received netlink message payload: Hello you! |
代码: |
#i nclude #i nclude #i nclude #define MAX_PAYLOAD 1024 /* maximum payload size*/ struct sockaddr_nl src_addr, dest_addr; struct nlmsghdr *nlh = NULL; struct msghdr msg; struct iovec iov; int sock_fd; int ret = 1; void main() { sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST); if (sock_fd == -1){ perror("socket error"); exit(1); } memset(&src_addr, 0, sizeof(src_addr)); src_addr.nl_family = AF_NETLINK; src_addr.nl_pid = getpid(); /*self pid */ /* interested in group 1<<0 */ src_addr.nl_groups = 35; if(bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr))== -1) { perror("bind error"); exit(1); } memset(&dest_addr, 0, sizeof(dest_addr)); nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; printf("\nWaiting for message from kernel\n"); /* Read message from kernel */ ret = recvmsg(sock_fd, &msg, 0); printf("%d\n",ret); printf("Received message payload: %s\n",NLMSG_DATA(nlh)); close(sock_fd); } |
代码: |
#ifndef __KERNEL__ #define __KERNEL__ #endif #ifndef MODULE #define MODULE #endif #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #define MAX_PAYLOAD 1024 struct sock *nl_sk = NULL; int bc; void nl_data_ready(struct sock *sk,int len) { wake_up_interruptible(sk->sleep); } void netlink_test() { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; nl_sk = netlink_kernel_create(NETLINK_TEST,nl_data_ready); skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL); nlh = (struct nlmsghdr *)skb->data; nlh = (struct nlmsghdr *)skb->data; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = 0; /*from kernel */ nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh), "Greeting From Kernel!"); /* sender is in group 1<<0 */ NETLINK_CB(skb).groups = 1; NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_pid = 0; /* multicast */ /* to mcast group 1<<0 */ NETLINK_CB(skb).dst_groups = 1; /*multicast the message to all listening processes*/ bc = netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL); /* bc = netlink_unicast(nl_sk,skb,0,MSG_DONTWAIT); */ printk(KERN_INFO"netlinkbroadast :%d\n",bc); /*sock_release(nl_sk->socket);*/ } static int my_module_init(void){ printk(KERN_INFO "initializing Netlink Socket!\n"); netlink_test(); return 0; } static void netlink_exit(void) { sock_release(nl_sk->socket); printk(KERN_INFO "Good Bye Netlink!\n"); } module_init(my_module_init); module_exit(netlink_exit); MODULE_LICENSE("GPL"); |
引用: |
./nl_recv & Waiting for message from kernel ./nl_recv & Waiting for message from kernel |
引用: |
Received message payload: Greeting from kernel! Received message payload: Greeting from kernel! |