1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > linux netlink 编程示例(二)应用层

linux netlink 编程示例(二)应用层

时间:2022-09-07 07:54:46

相关推荐

linux netlink 编程示例(二)应用层

这篇文章给出一个netlink应用层程序用例,和上一篇博客内核篇结合起来参考。

内核版本:3.4.39

nlclient.c

/** Description : 应用层netlink编程* Date :0529* Author:mason* Mail : mrsonko@**/#include <linux/netlink.h>#include <linux/socket.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include "nlclient.h"void main() {int nlfd;int *value;int opt, arg;unsigned int len;struct iovec iov[1];struct msghdr msg;struct sockaddr_nl src, dst; struct nlmsghdr *nlh, *nlh1, *nlh2 = NULL;// 创建netlink套接字nlfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_TEST_MODULE);if (nlfd == -1) {log("create netlink socket fail\n");return;}memset(&src, 0, sizeof(struct sockaddr_nl));memset(&dst, 0, sizeof(struct sockaddr_nl));memset(&msg, 0, sizeof(struct msghdr)); // 设置本地地址src.nl_family = AF_NETLINK; src.nl_pid = getpid(); src.nl_groups = 0; // 设置内核netlink地址dst.nl_family = AF_NETLINK;dst.nl_pid = 0; dst.nl_groups = 0;// 绑定本地地址bind(nlfd, (struct sockaddr*)&src, sizeof(struct sockaddr_nl));// 申请netlink消息头域nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(int));while(1) {log("input option :\n""1 : set \n""2 : get \n""default : quit\n");scanf("%d", &opt);switch (opt) {// set case 1 :log("input value to set:");scanf("%d", &arg); memset(nlh, 0, NLMSG_SPACE(sizeof(int)));nlh->nlmsg_len = NLMSG_SPACE(sizeof(int));// 设置netlink 应用层的pidnlh->nlmsg_pid = getpid();// 设置消息类型nlh->nlmsg_type = NLKERNEL_SET;// 设置标志位nlh->nlmsg_flags = NLM_F_REQUEST;// 填充发送消息结构体iov[0].iov_base = (void *)nlh;iov[0].iov_len = nlh->nlmsg_len;value = (int *)NLMSG_DATA(nlh);*value = arg;msg.msg_name = (void *)&dst;msg.msg_namelen = sizeof(struct sockaddr_nl);msg.msg_iov = &iov[0];msg.msg_iovlen = 1;// 发送netlink 消息给内核sendmsg(nlfd, &msg, 0);log("send set msg to kernel success \n\n");break;// getcase 2 : memset(nlh, 0, NLMSG_SPACE(int));nlh->nlmsg_len = NLMSG_SPACE(int);nlh->nlmsg_pid = getpid();// 设置netlink消息类型nlh->nlmsg_type = NLKERNEL_GET;nlh->nlmsg_flags = NLM_F_REQUEST;iov[0].iov_base = (void *)nlh;iov[0].iov_len = nlh->nlmsg_len;msg.msg_name = (void *)&dst;msg.msg_namelen = sizeof(struct sockaddr_nl);msg.msg_iov = &iov[0];msg.msg_iovlen = 1;// 发送消息log("send get msg to kernel success \n");sendmsg(nlfd, &msg, 0);memset(nlh, 0, NLMSG_SPACE(sizeof(int)));nlh->nlmsg_len = NLMSG_SPACE(sizeof(int));iov[0].iov_base = (void *)nlh;iov[0].iov_len = nlh->nlmsg_len;msg.msg_iov = &iov[0];msg.msg_iovlen = 1; // 接收netlink内核端消息len = recvmsg(nlfd, &msg, 0);value = (int *)NLMSG_DATA(nlh);log("kernel return : %d \r\n\n", *value);break;default :goto end;}}end: close(nlfd);if (nlh)free(nlh);return ; }

nlclient.h

#ifndef _NLCLIENT_H#define _NLCLIENT_H#define log(fmt,arg...) \printf("[nlclient] "fmt,##arg)#define NETLINK_TEST_MODULE 17/* 抓包 netlink 协议 */typedef enum netlink_msg_type {NLKERNEL_GET = NLMSG_MIN_TYPE +1, /* value : 17 */NLKERNEL_SET, /* value : 18 */NLKERNEL_END,}NETLINK_MSG_TYPE;#endif

Makefile

nlclient:$(CC) -o nlclient lean:@rm -rf *.o nlclient

代码可以在github上 clone下来运行

git@:FuYuanDe/nlnetlink.git

编译完成后先运行netlink内核端再运行应用层程序,否则会出现创建netlink套接字失败问题。

运行截图如下:

应用层:分别执行了get, set, get 操作,通过netlink与内核通信

内核端:

相比其它的用户空间与内核空间通信方式,netlink的交互性非常好。此外在实际应用的时候要注意字节对齐问题。

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