失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Linux 内核态与用户态通信 netlink

Linux 内核态与用户态通信 netlink

时间:2020-03-01 22:02:08

相关推荐

Linux 内核态与用户态通信 netlink

参考资料:

/zqixiao_09/article/details/77131283

#include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/types.h>#include <linux/sched.h>#include <net/sock.h>#include <net/netlink.h>#include <linux/netlink.h>#define NETLINK_USER 22#define USER_MSG (NETLINK_USER 1)#define USER_PORT 50MODULE_LICENSE("GPL");MODULE_AUTHOR("arvik");MODULE_DESCRIPTION("netlink_demo");static void test_netlink_rcv(struct sk_buff *skb);struct netlink_kernel_cfg cfg = { .input = test_netlink_rcv, /*...*/};static struct sock *test_netlink_sock = NULL;int send_msg(int8_t *pbuf, uint16_t len){ struct sk_buff *nl_skb; struct nlmsghdr *nlh; int ret; nl_skb = nlmsg_new(len, GFP_ATOMIC); if (!nl_skb) { printk("netlink_alloc_skb error\n"); return -1; } /*将header填充到skb中*/ nlh = nlmsg_put(nl_skb, 0, 0, USER_MSG, len, 0); if (nlh == NULL) { printk("put error\n"); nlmsg_free(nl_skb); return -1; } /*拷贝data*/ memcpy(nlmsg_data(nlh), pbuf, len); /*发送*/ ret = netlink_unicast(test_netlink_sock, nl_skb, USER_PORT, MSG_DONTWAIT); return ret;}static void test_netlink_rcv(struct sk_buff *skb){ struct nlmsghdr *nlh = NULL; void *data = NULL; printk("skb->len %u\n", skb->len); if (skb->len >= nlmsg_total_size(0)) { nlh = nlmsg_hdr(skb); data = NLMSG_DATA(nlh); if (data) { printk("kernel receive date : %s\n", (int8_t *)data); send_msg(data, nlmsg_len(nlh)); } }}static int __init test_netlink_init(void){ printk("test netlink init\n"); test_netlink_sock = netlink_kernel_create(&init_net, USER_MSG, &cfg); if (test_netlink_sock == NULL) { printk("test netlink init error\n"); return -1; } printk("test netlink init ok\n"); return 0;}static void __exit test_netlink_exit(void){ netlink_kernel_release(test_netlink_sock); test_netlink_sock = NULL; printk("test netlink exit\n");}module_init(test_netlink_init);module_exit(test_netlink_exit);

#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <string.h>#include <linux/netlink.h>#include <stdint.h>#include <unistd.h>#include <errno.h>#define NETLINK_USER 22#define USER_MSG (NETLINK_USER 1)#define MSG_LEN 100#define MAX_PLOAD 100struct _my_msg { struct nlmsghdr hdr; int8_t data[MSG_LEN];};int main(){ char *data = "hello kernel"; socklen_t addr_len; struct sockaddr_nl local, dest_addr; int skfd; struct nlmsghdr *nlh = NULL; struct _my_msg info; int ret; //创建socket skfd = socket(AF_NETLINK, SOCK_RAW, USER_MSG); if (skfd == (-1)) { fprintf(stderr, "create socket error...%s\n", strerror(errno)); return (-1); } /*绑定*/ memset(&local, 0, sizeof(local)); local.nl_family = AF_NETLINK; local.nl_pid = 50; local.nl_groups = 0; if (bind(skfd, (struct sockaddr *)&local, sizeof(local)) != 0) { fprintf(stderr, "bind error\n"); close(skfd); 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; /*填写data*/ nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD)); memset(nlh, 0, sizeof(struct nlmsghdr)); nlh->nlmsg_len = NLMSG_SPACE(MAX_PLOAD); nlh->nlmsg_flags = 0; nlh->nlmsg_type = 0; nlh->nlmsg_seq = 0; nlh->nlmsg_pid = local.nl_pid; memcpy(NLMSG_DATA(nlh), data, strlen(data)); ret = sendto(skfd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_nl)); if (ret < 0) {// fprintf(stderr, "sendto error\n"); perror("sendto error: "); close(skfd); return (-1); } printf("wait kernel msg!\n"); memset(&info, 0, sizeof(info)); /*接受信息*/ ret = recvfrom(skfd, &info, sizeof(struct _my_msg), 0, (struct sockaddr *)&dest_addr, &addr_len); if (ret <= 0) {// fprintf(stderr, "recv from kernel error\n"); perror("recv from kernel error: "); close(skfd); return (-1); } printf("msg receive from kernel : %s\n", info.data); close(skfd); free((void *)nlh); close(skfd); return 0;}

来源:/content-3-134001.html

如果觉得《Linux 内核态与用户态通信 netlink》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。