博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux netlink套接字学习资料
阅读量:4030 次
发布时间:2019-05-24

本文共 3127 字,大约阅读时间需要 10 分钟。

理论:

http://blog.csdn.net/unbutun/article/details/3394061

进一步深入:

http://edsionte.com/techblog/archives/4134

http://edsionte.com/techblog/archives/4140

http://edsionte.com/techblog/archives/4134

实践:

http://bbs.chinaunix.net/thread-3766684-1-1.html

附录代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NETLINK_TEST 18#define MAX_PAYLOAD 1024struct req { struct nlmsghdr nlh; char [MAX_PAYLOAD];};void eprint(int err_no, char *str, int line){ printf("Error %d in line %d:%s() with %s\n", err_no, line, str, strerror(errno));}int main(){int sock_fd;sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);if (sock_fd < 0) { eprint(errno, "socket", __LINE__); return errno;}//将本地套接字与源地址绑定struct sockaddr_nl src_addr;memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid(); //nl_pid字段指明发送消息一方的pidsrc_addr.nl_groups = 0; //nl_groups表示多播组的掩码 这里我们并没有涉及多播,因此默认为0if (bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) { eprint(errno, "bind", __LINE__); return errno;}//绑定了套接字之后,用户进程最终发送的是msghdr结构的消息,因此必须对这个结构进行初始化,//而msghdr结构又与//初始化msghdr结构 sockaddr_nl,iovec和nlmsghdr三个结构相关,因此必须依次对这些数据结构进行初始化/*struct msghdr { void * msg_name; // Socket name int msg_namelen; //Length of name struct iovec * msg_iov; // Data blocks __kernel_size_t msg_iovlen; // Number of blocks void * msg_control; // Per protocol magic (eg BSD file descriptor passing) __kernel_size_t msg_controllen; // Length of cmsg list unsigned msg_flags;};*//*struct sockaddr_nl { __kernel_sa_family_t nl_family; // AF_NETLINK unsigned short nl_pad; //zero __u32 nl_pid; // port ID __u32 nl_groups; // multicast groups mask };*/struct sockaddr_nl dest_addr;memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0; //即nl_pid必须为0,表示接收方为内核。 dest_addr.nl_groups = 0; //req类型的数据报进行初始化,即依次对其封装的两个数据结构初始化:struct req r;//自定义协议数据结构 使用netlink进行用户进程和内核的数据交互时 用到r.nlh.nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); /*这里的nlmsg_len为为sizeof(structnlmsghdr)+MAX_PAYLOAD的总和。宏NLMSG_SPACE会自动将两者的长度相加#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) */r.nlh.nlmsg_pid = getpid();r.nlh.nlmsg_flags = 0;memset(r.buf, 0, MAX_PAYLOAD);strcpy(NLMSG_DATA(&(r.nlh)), "hello, I am edsionte!"); //#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))//接下来对缓冲区向量iov进行初始化,让iov_base字段指向数据报结构,而iov_len为数据报长度。struct iovec iov;iov.iov_base = (void *)&r;iov.iov_len = sizeof(r);//一切就绪后,将目的套接字地址与当前要发送的消息msg绑定,即将目的套接字地址复制给msg_name。再将要发送的数据iov与msg_iov绑定,如果一次///性要发送多个数据包,则创建一个iovec类型的数组。struct msghdr msg;msg.msg_name = (void *)&dest_addr;msg.msg_namelen = sizeof(dest_addr);msg.msg_iov = &iov;msg.msg_iovlen = 1;//.向内核发送消息if (sendmsg(sock_fd, &msg, 0) < 0) { eprint(errno, "sendmsg", __LINE__); return errno;}//接收内核发来的消息memset(&r.nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));if (recvmsg(sock_fd, &msg, 0) < 0) { eprint(errno, "recvmsg", __LINE__); return errno;}printf("Received message payload:%s\n", (char *)NLMSG_DATA(r.nlh));close(sock_fd);}

你可能感兴趣的文章
Matlab与CUDA C的混合编程配置出现的问题及解决方案
查看>>
2017阿里内推笔试题--算法工程师(运筹优化)
查看>>
python自动化工具之pywinauto(零)
查看>>
python自动化工具之pywinauto(四)——批量转换exe视频
查看>>
python一句话之利用文件对话框获取文件路径
查看>>
PaperDownloader——文献命名6起来
查看>>
PaperDownloader 1.5.1——更加人性化的文献下载命名解决方案
查看>>
如何将PaperDownloader下载的文献存放到任意位置
查看>>
C/C++中关于动态生成一维数组和二维数组的学习
查看>>
系统架构:Web应用架构的新趋势---前端和后端分离的一点想法
查看>>
JVM最简生存指南
查看>>
漂亮的代码,糟糕的行为——解决Java运行时的内存问题
查看>>
Java的对象驻留
查看>>
自己动手写GC
查看>>
Java 8新特性终极指南
查看>>
logback高级特性使用(二) 自定义Pattern模板
查看>>
JVM并发机制探讨—内存模型、内存可见性和指令重排序
查看>>
可扩展、高可用服务网络设计方案
查看>>
如何构建高扩展性网站
查看>>
微服务架构的设计模式
查看>>