O4 - Netlink学习
2015-10-30 09:30
1026 查看
/* kernl.c netlink 内核部分 */ #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/module.h> #include <linux/types.h> #include <net/sock.h> #include <net/netlink.h> #ifndef TEST_NETLINK #define TEST_NETLINK 25 #endif #ifndef TEST_GROUP #define TEST_GROUP 2 #endif #define TYPE_REQ_KERMSG 1 #define TYPE_REQ_USERPID 2 typedef struct netlink_msg { int type; int opt; char path[4096]; int gid; int uid; }netlink_msg; struct sock *g_nlsocket = NULL; static int g_userpid = 0; static int create_netlink(void); static int get_userpid(void) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; netlink_msg message = { .type = TYPE_REQ_USERPID, }; int len = NLMSG_SPACE(sizeof(netlink_msg) + sizeof(struct nlmsghdr)); if(!g_nlsocket) if (create_netlink()) return -1; skb = alloc_skb(len, GFP_KERNEL); if(!skb){ printk(KERN_ERR "ERROR: KERNEL NETLINK - userpid miss.\n"); return -1; } nlh = nlmsg_put(skb, 0, 0, 0, len, 0); NETLINK_CB(skb).creds.pid = 0; NETLINK_CB(skb).portid = 0; NETLINK_CB(skb).dst_group = TEST_GROUP; memcpy(NLMSG_DATA(nlh), &message, sizeof(netlink_msg)); netlink_broadcast(g_nlsocket, skb, 0, TEST_GROUP, GFP_KERNEL); return 0; } int netlink_sendmsg(void *msg, int msglen) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; int skblen = 0; if (g_userpid <= 0) { get_userpid(); mdelay(8); /* sleep 8ms */ } skblen = NLMSG_SPACE(msglen + sizeof(struct nlmsghdr)); skb = alloc_skb(skblen, GFP_ATOMIC); if (!skb){ printk("ERROR: KERNEL NETLINK - allocate failed.\n"); return -1; } nlh = nlmsg_put(skb, 0, 0, 0, skblen, 0); NETLINK_CB(skb).creds.pid = 0; memcpy(NLMSG_DATA(nlh), msg, msglen); if (g_userpid > 0) { netlink_unicast(g_nlsocket, skb, g_userpid, MSG_DONTWAIT); } else { NETLINK_CB(skb).portid = 0; NETLINK_CB(skb).dst_group = TEST_GROUP; netlink_broadcast(g_nlsocket, skb, 0, TEST_GROUP, GFP_KERNEL); } return 0; } static int netlink_recvmsg(netlink_msg *msg) { if (IS_ERR_OR_NULL(msg)) return -1; printk("receive message:\ntype: %d\nopt: %d\npath: %s\ngid: %d uid: %d\n", msg->type, msg->opt, msg->path, msg->gid, msg->uid); return 0; } void nl_data_ready (struct sk_buff *__skb) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; netlink_msg *nlmsg = (netlink_msg* )kmalloc(sizeof(netlink_msg), GFP_ATOMIC); if (IS_ERR_OR_NULL(nlmsg)) return; memset(nlmsg, 0, sizeof(netlink_msg)); skb = skb_get(__skb); if(skb && skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); g_userpid = nlh->nlmsg_pid; memcpy(nlmsg, NLMSG_DATA(nlh), nlh->nlmsg_len); netlink_recvmsg(nlmsg); kfree_skb(skb); } kfree(nlmsg); } static int create_netlink(void) { struct netlink_kernel_cfg cfg = { .input = nl_data_ready, }; g_nlsocket = netlink_kernel_create(&init_net, TEST_NETLINK, &cfg); if (!g_nlsocket) { printk("ERROR: KERNEL NETLINK - Cannot create netlink socket.\n"); return -EIO; } return 0; } static struct task_struct *taskp = NULL; static int stime = 2; module_param(stime, int ,S_IRUGO); static int thread_fun(void *data) { netlink_msg sendmsg; int msgcnt = 1; while (!kthread_should_stop()) { ssleep(stime); sendmsg.type = TYPE_REQ_KERMSG; sendmsg.opt = msgcnt++; snprintf(sendmsg.path, sizeof(sendmsg.path), "%s", "/where/is/the/file"); sendmsg.gid = 4; sendmsg.uid = 5; netlink_sendmsg(&sendmsg, sizeof(netlink_msg)); } return 0; } int __init init_netlink(void) { create_netlink(); taskp = kthread_run(thread_fun, NULL, "%s", "netlink_thread"); return 0; } void __exit exit_netlink(void ) { kthread_stop(taskp); if (g_nlsocket != NULL) sock_release(g_nlsocket->sk_socket); } module_init(init_netlink); module_exit(exit_netlink); MODULE_LICENSE("GPL");
obj-m := kernl.o KERNELDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install install: insmod kernl.ko remove: rmmod kernl clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers .tmp* .ker_*
<pre name="code" class="cpp">/*
usernl.c
netlink 用户态部分
*/#include <sys/stat.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <sys/types.h>#include <string.h>#include <asm/types.h>#include <linux/netlink.h>#include <linux/socket.h>#include <sys/select.h>#include
<errno.h>#include <pthread.h>#ifndef TEST_NETLINK#define TEST_NETLINK 25#endif#ifndef TEST_GROUP#define TEST_GROUP 2#endif#define TYPE_ACK_KERMSG 0x01#define TYPE_REQ_DOWN 0x10static int run = 1;typedef struct netlink_msg {int type;int opt;char path[4096];int
gid;int uid;}netlink_msg;int nl_create_bind(int netlinkid, int netlinkgid){int sock_fd, retval, group;struct sockaddr_nl src_addr;/* Create a socket */sock_fd = socket(AF_NETLINK, SOCK_RAW, netlinkid);if(sock_fd == -1){printf("error create socket: %s", strerror(errno));return
-1;}/* bind */memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();src_addr.nl_groups = netlinkgid;retval = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));if(retval < 0){printf("error bind socket:
%s", strerror(errno));close(sock_fd);return -1;}/* 270 is SOL_NETLINK */group = netlinkgid;retval = setsockopt(sock_fd, 270, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));if (retval < 0) {printf("error setsockopt: %s", strerror(errno));close(sock_fd);return
-1;}return sock_fd;}int nl_sendmsg(int sock_fd, void *msgsend, int msgsize){struct msghdr msg;struct nlmsghdr *nlh = NULL;struct sockaddr_nl dest_addr;struct iovec iov;int state_smg = 0;int payload = NLMSG_SPACE(msgsize + sizeof(struct nlmsghdr));nlh = (struct
nlmsghdr *)malloc(NLMSG_SPACE(payload));if(!nlh){printf("error malloc nlmsghdr: %s", strerror(errno));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 = TEST_GROUP;nlh->nlmsg_len
= NLMSG_SPACE(payload);nlh->nlmsg_pid = getpid();nlh->nlmsg_flags = 0;memcpy(NLMSG_DATA(nlh), msgsend, msgsize);iov.iov_base = (void *)nlh;iov.iov_len = NLMSG_SPACE(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);if(state_smg == -1)printf("get error sendmsg = %s\n",strerror(errno));free(nlh);return state_smg;}typedef void (*recv_cbfun)(struct netlink_msg *);recv_cbfun nl_recvmsg = NULL;void recvmsg_cb(struct
netlink_msg *nlmsg){printf("receive message:\ntype: %d\nopt: %d\npath: %s\ngid: %d uid: %d\n",nlmsg->type, nlmsg->opt, nlmsg->path, nlmsg->gid, nlmsg->uid);if (nlmsg->type == TYPE_REQ_DOWN) run = 0;//nlh->nlmsg_pid = getpid();//sendmsg(sock_fd, &msg, 0);}void
register_recvcb(recv_cbfun cb){nl_recvmsg = cb;}void *recvmsg_thread(void *param){int sock_fd = *(int *)param;struct msghdr msg;struct nlmsghdr *nlh = NULL;struct iovec iov;int payload = NLMSG_SPACE(sizeof(struct netlink_msg) + sizeof(struct nlmsghdr));nlh
= (struct nlmsghdr *)calloc(NLMSG_SPACE(payload), 1);if(!nlh){printf("error malloc nlmsghdr: %s", strerror(errno));return NULL;}iov.iov_base = (void *)nlh;iov.iov_len = NLMSG_SPACE(payload);memset(&msg, 0, sizeof(msg));msg.msg_iov = &iov;msg.msg_iovlen = 1;while
(1) {recvmsg(sock_fd, &msg, 0);struct netlink_msg *nlmsg = (struct netlink_msg *)NLMSG_DATA(nlh);if (nl_recvmsg) (*nl_recvmsg)(nlmsg);if (!run) break;}return NULL;}int main(int argc, char* argv[]){int sock_fd = nl_create_bind(TEST_NETLINK, TEST_GROUP);if (sock_fd
< 0) return -1;struct netlink_msg u2k = {.type = TYPE_ACK_KERMSG,.opt = 1,.path = {"/HELLO/THIS/IS/USERSPACE."},.gid = 2,.uid = 3,};int state_smg = nl_sendmsg(sock_fd, &u2k, sizeof(netlink_msg));if(state_smg == -1)printf("get error sendmsg\n");register_recvcb(recvmsg_cb);pthread_t
pthid;pthread_create(&pthid, NULL, recvmsg_thread, &sock_fd);while (run) {usleep(1000 * 500); /* 200ms */nl_sendmsg(sock_fd, &u2k, sizeof(netlink_msg));}pthread_join(pthid, NULL);close(sock_fd);return 0;}
参考文档:
http://qos.ittc.ku.edu/netlink/netlink.pdf http://1984.lsi.us.es/~pablo/docs/spae.pdf
相关文章推荐
- 产品图外边框CSS样式
- Masonary简单使用
- table 表格样式
- ARM寄存器
- java 代理模式 详解(奶粉代购例子)
- 《从零开始学Swift》学习笔记(Day 29)——访问级别
- 第七周-队列数组
- 【Bug】c#使用oleDB读excel读取不到最后一列,把Excel表格打开随便改动一列的格式就能读取出来了。请问这是什么问题
- 错误:Underlying DBMS error[ORA-01653]:unable to extend table SDE……
- spring mvc 的传参方式by pangzi
- Eclipse下导入jar/zip源文件的方法
- 记录20151030
- vs2008生成的各种文件
- 通过点击cell上的Button获取tableView的indexPath
- 解决ScrollView与ListView事件冲突
- 怎样用U盘安装Ubuntu系统/ubuntu系统怎么安装
- gitlab安装
- 第七周实践项目~排队模拟看病
- 第9周项目1猴子选大王(数组版)
- 最大似然估计、MAP及贝叶斯估计