当前位置: 首页 > news >正文

Netlink 通信机制

文章目录

  • 前言
  • 一、Netlink 介绍
  • 二、示例代码
  • 参考资料

前言

一、Netlink 介绍

Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。

在Linux 内核中,使用netlink 进行应用与内核通信的应用有很多,如

  • 路由 daemon(NETLINK_ROUTE)
  • 用户态 socket 协议(NETLINK_USERSOCK)
  • 防火墙(NETLINK_FIREWALL)
  • netfilter 子系统(NETLINK_NETFILTER)
  • 内核事件向用户态通知(NETLINK_KOBJECT_UEVENT)
  • 通用netlink(NETLINK_GENERIC)

Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用 netlink。

一般来说用户空间和内核空间的通信方式有三种:/proc、ioctl、Netlink。而前两种都是单向的,而Netlink可以实现双工通信。

Netlink 相对于系统调用,ioctl 以及 /proc文件系统而言,具有以下优点:

  • netlink使用简单,只需要在include/linux/netlink.h中增加一个新类型的 netlink 协议定义即可,(如 #define NETLINK_TEST 20 然后,内核和用户态应用就可以立即通过 socket API 使用该 netlink 协议类型进行数据交换)
  • netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息
  • 使用 netlink 的内核部分可以采用模块的方式实现,使用 netlink 的应用部分和内核部分没有编译时依赖
  • netlink 支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink 组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性
  • 内核可以使用 netlink 首先发起会话

Netlink协议基于BSD socket和AF_NETLINK地址簇,使用32位的端口号寻址,每个Netlink协议通常与一个或一组内核服务/组件相关联,如NETLINK_ROUTE用于获取和设置路由与链路信息、NETLINK_KOBJECT_UEVENT用于内核向用户空间的udev进程发送通知等。

二、示例代码

  • netlink_test.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <net/sock.h>
#include <linux/netlink.h>#define NETLINK_TEST     25
#define MSG_LEN            125
#define USER_PORT        100MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangwj");
MODULE_DESCRIPTION("netlink example");struct sock *nlsk = NULL;
extern struct net init_net;/* 向用户空间发送消息的接口 */
int send_usrmsg(char *pbuf, uint16_t len)
{struct sk_buff *nl_skb;struct nlmsghdr *nlh;  // 消息头int ret;/* 创建sk_buff 空间 */nl_skb = nlmsg_new(len, GFP_ATOMIC);if(!nl_skb){printk("netlink alloc failure\n");return -1;}/* 设置netlink消息头部 */nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);if(nlh == NULL){printk("nlmsg_put failaure \n");nlmsg_free(nl_skb);return -1;}/* 拷贝数据发送 */memcpy(nlmsg_data(nlh), pbuf, len);ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); /* 发送单播消息 */return ret;
}static void netlink_rcv_msg(struct sk_buff *skb)
{struct nlmsghdr *nlh = NULL;char *umsg = NULL;char *kmsg = "hello users!!!";if(skb->len >= nlmsg_total_size(0)){nlh = nlmsg_hdr(skb);umsg = NLMSG_DATA(nlh);/* 宏NLMSG_DATA(nlh)用于取得消息的数据部分的首地址,设置和读取消息数据部分时需要使用该宏 */if(umsg){printk("kernel recv from user: %s\n", umsg);send_usrmsg(kmsg, strlen(kmsg));}}
}struct netlink_kernel_cfg cfg = { .input  = netlink_rcv_msg, /* set recv callback */
};  int test_netlink_init(void)
{/* create netlink socket */nlsk = (struct sock *)netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);if(nlsk == NULL){   printk("netlink_kernel_create error !\n");return -1; }   printk("test_netlink_init\n");return 0;
}void test_netlink_exit(void)
{if (nlsk){netlink_kernel_release(nlsk); /* release ..*/nlsk = NULL;}   printk("test_netlink_exit!\n");
}module_init(test_netlink_init);
module_exit(test_netlink_exit);
  • Makefile
#
#Desgin of Netlink
#MODULE_NAME :=netlink_test
obj-m :=$(MODULE_NAME).oKERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)all:$(MAKE) -C $(KERNELDIR) M=$(PWD)clean:$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
  • sender.c
#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_TEST    25
#define MSG_LEN            125
#define MAX_PLOAD        125typedef struct _user_msg_info
{struct nlmsghdr hdr;char  msg[MSG_LEN];
} user_msg_info;int main(int argc, char **argv)
{int skfd;int ret;user_msg_info u_info;socklen_t len;struct nlmsghdr *nlh = NULL;struct sockaddr_nl saddr, daddr;char *umsg = "hello netlink!!";/* 创建NETLINK socket */skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);if(skfd == -1){perror("create socket error\n");return -1;}memset(&saddr, 0, sizeof(saddr));saddr.nl_family = AF_NETLINK; //AF_NETLINKsaddr.nl_pid = 100;  //端口号(port ID) saddr.nl_groups = 0;/* 将套接字和Netlink地址结构体进行绑定 */if(bind(skfd, (struct sockaddr *)&saddr, sizeof(saddr)) != 0){perror("bind() error\n");close(skfd);return -1;}memset(&daddr, 0, sizeof(daddr));daddr.nl_family = AF_NETLINK;daddr.nl_pid = 0; // to kernel daddr.nl_groups = 0;/* 填充Netlink消息头部 */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 = saddr.nl_pid; //self port/* 设置Netlink的消息内容 */memcpy(NLMSG_DATA(nlh), umsg, strlen(umsg));/* 发送单播消息 */ret = sendto(skfd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));if(!ret){perror("sendto error\n");close(skfd);exit(-1);}printf("send kernel:%s\n", umsg);/*这个是模板,暂时不用纠结为什么要这样用。有时间详细讲解socket时再说*/memset(&u_info, 0, sizeof(u_info));len = sizeof(struct sockaddr_nl);/* 接收消息 */ret = recvfrom(skfd, &u_info, sizeof(user_msg_info), 0, (struct sockaddr *)&daddr, &len);if(!ret){perror("recv form kernel error\n");close(skfd);exit(-1);}printf("from kernel:%s\n", u_info.msg);close(skfd);free((void *)nlh);return 0;
}

运行结果:

root@xxx# gcc sender.c -o sender && ./sender 
send kernel:hello netlink!!
from kernel:hello users!!!
[20840.743223] kernel recv from user: hello netlink!!

参考资料

  1. linux下netlink的使用简介
  2. 用户空间和内核空间通讯之【Netlink 上】
  3. 用户空间和内核空间通讯之【Netlink 中】
  4. 用户空间和内核空间通讯之【Netlink 下】
  5. linux netlink遇到的问题

相关文章:

Netlink 通信机制

文章目录 前言一、Netlink 介绍二、示例代码参考资料 前言 一、Netlink 介绍 Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 在Linux 内核中&#xff0c;使用netlink 进行应用与内核通信的应用有…...

2024.1.8每日一题

LeetCode 回旋镖的数量 447. 回旋镖的数量 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定平面上 n 对 互不相同 的点 points &#xff0c;其中 points[i] [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 &#xff0c;其中 i 和 j 之间的距离和 i 和 k 之间的欧式…...

看了致远OA的表单设计后的思考

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…...

mmdetection训练自己的数据集

mmdetection训练自己的数据集 这里写目录标题 mmdetection训练自己的数据集一&#xff1a; 环境搭建二&#xff1a;数据集格式转换(yolo转coco格式)yolo数据集格式coco数据集格式yolo转coco数据集格式yolo转coco数据集格式的代码 三&#xff1a; 训练dataset数据文件配置config…...

MySQL取出N列里最大or最小的一个数据

如题&#xff0c;现在有3列&#xff0c;都是数字类型&#xff0c;要取出这3列里最大或最小的的一个数字 -- N列取最小 SELECT LEAST(temperature_a,temperature_b,temperature_c) min FROM infrared_heat-- N列取最大 SELECT GREATEST(temperature_a,temperature_b,temperat…...

编写.NET的Dockerfile文件构建镜像

创建一个WebApi项目&#xff0c;并且创建一个Dockerfile空文件&#xff0c;添加以下代码&#xff0c;7.0代表的你项目使用的SDK的版本&#xff0c;构建的时候也需要选择好指定的镜像tag FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443F…...

【C语言】浙大版C语言程序设计(第三版) 练习7-4 找出不是两个数组共有的元素

前言 最近在学习浙大版的《C语言程序设计》&#xff08;第三版&#xff09;教材&#xff0c;同步在PTA平台上做对应的练习题。这道练习题花了比较长的时间&#xff0c;于是就写篇博文记录一下我的算法和代码。 2024.01.03 题目 练习7-4 找出不是两个数组共有的元素 作者 张彤…...

7.27 SpringBoot项目实战 之 整合Swagger

文章目录 前言一、Maven依赖二、编写Swagger配置类三、编写接口配置3.1 控制器Controller 配置描述3.2 接口API 配置描述3.3 参数配置描述3.4 忽略API四、全局参数配置五、启用增强功能六、调试前言 在我们实现了那么多API以后,进入前后端联调阶段,需要给前端同学提供接口文…...

创建第一个SpringMVC项目,入手必看!

文章目录 创建第一个SpringMVC项目&#xff0c;入手必看&#xff01;1、新建一个maven空项目&#xff0c;在pom.xml中设置打包为war之前&#xff0c;右击项目添加web框架2、如果点击右键没有添加框架或者右击进去后没有web框架&#xff0c;点击左上角file然后进入项目结构在模块…...

go 切片长度与容量的区别

切片的声明 切片可以看成是数组的引用&#xff08;实际上切片的底层数据结构确实是数组&#xff09;。在 Go 中&#xff0c;每个数组的大小是固定的&#xff0c;不能随意改变大小&#xff0c;切片可以为数组提供动态增长和缩小的需求&#xff0c;但其本身并不存储任何数据。 …...

回归和分类区别

回归任务&#xff08;Regression&#xff09;&#xff1a; 特点&#xff1a; 输出是连续值&#xff0c;通常是实数。任务目标是预测或估计一个数值。典型应用包括房价预测、销售额预测、温度预测等。 目标&#xff1a; 最小化预测值与真实值之间的差异&#xff0c;通常使用…...

docker nginx滚动日志配置

将所有日志打印到控制台 nginx.conf user nginx; worker_processes auto; # 日志打印控制台 error_log /dev/stdout; #error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/m…...

大数据分析案例-基于LinearRegression回归算法构建房屋价格预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…...

React-hook-form-mui(一):基本使用

前言 在项目开发中&#xff0c;我们选择了ReactMUI作为技术栈。在使用MUI构建form表单时&#xff0c;我们发现并没有与antd类似的表单验证功能&#xff0c;于是我们选择了MUI推荐使用的react-hook-form-mui库去进行验证。但是发现网上关于这个库的使用方法和demo比较少且比较简…...

python总结-生成器与迭代器

生成器与迭代器 生成器生成器定义为什么要有生成器创建生成器的方式一(生成器表达式) 创建生成器的方式二(生成器函数)生成器函数的工作原理总结 迭代器概念可迭代对象和迭代器区别for循环的本质创建一个迭代器 动态添加属性和方法运行过程中给对象、类添加属性和方法types.Met…...

MySQL如何从数据中截取所需要的字符串

MySQL如何从数据中截取所需要的字符串 背景 有这样的一个场景,我想从我的表里面进行数据截取&#xff0c;我的数据内容大致如下&#xff1a; 张三-建外SOHO-2-16 POA 20210518.pdf 我想获取数据中的&#xff1a;20210518这一日期部分&#xff0c;需要如何实现&#xff1f; 解…...

动态加载和动态链接的区别

动态加载&#xff08;Dynamic Loading&#xff09;和动态链接&#xff08;Dynamic Linking&#xff09;是两个与程序运行时加载和使用代码相关的概念&#xff0c;它们有一些区别&#xff1a; 动态加载&#xff08;Dynamic Loading&#xff09;&#xff1a; 定义&#xff1a; 动…...

js数组循环,当前循环完成后执行下次循环

前言 上图中&#xff0c;点击播放icon&#xff0c;图中左边地球视角会按照视角列表依次执行。u3D提供了api,但是我们如何保证在循环中依次执行。即第一次执行完成后&#xff0c;再走第二次循环。很多人的第一思路就是promise。对&#xff0c;不错&#xff0c;出发的思路是正确的…...

决策树(Decision Trees)

决策树&#xff08;Decision Trees&#xff09;是一种基于树形结构进行决策的模型&#xff0c;广泛应用于分类和回归任务。它通过对数据集进行递归划分&#xff0c;构建一棵树&#xff0c;每个节点代表一个特征&#xff0c;每个分支代表一个决策规则&#xff0c;叶节点存储一个…...

湖南大学-计算机网路-2023期末考试【部分原题回忆】

前言 计算机网络第一门考&#xff0c;而且没考好&#xff0c;回忆起来的原题不多。 这门学科学的最认真&#xff0c;复习的最久&#xff0c;考的最差。 教材使用这本书&#xff1a; 简答题&#xff08;6*530分&#xff09; MTU和MSS分别是什么&#xff0c;联系是什么&#x…...

LCD—液晶显示

本节主要介绍以下内容 显示器简介 液晶控制原理 秉火3.2寸液晶屏简介 使用FSMC模拟8080时序 NOR FLASH时序结构体 FSMC初始化结构体 一、显示器简介 显示器属于计算机的I/O设备&#xff0c;即输入输出设备。它是一种将特定电子信息输出到屏幕上再反射到人眼的显示工具。…...

论正确初始化深度学习模型参数的重要性

遇到的问题&#xff1a;在一般的深度学习训练过程中&#xff0c;我们建立好模型以后&#xff0c;程序就有自动的初始化一些模型的参数&#xff0c;比如全连接层中每一个节点的权重等等&#xff0c;在之前的网络训练过程中&#xff0c;我总是事先设下随机种子以后&#xff0c;让…...

ALSA学习(5)——ASoC架构中的Machine

参考博客&#xff1a;https://blog.csdn.net/DroidPhone/article/details/7231605 &#xff08;以下内容皆为原博客转载&#xff09; 文章目录 一、注册Platform Device二、注册Platform Driver三、初始化入口soc_probe() 一、注册Platform Device ASoC把声卡注册为Platform …...

LeetCode 0447.回旋镖的数量:哈希表

【LetMeFly】447.回旋镖的数量&#xff1a;哈希表 力扣题目链接&#xff1a;https://leetcode.cn/problems/number-of-boomerangs/ 给定平面上 n 对 互不相同 的点 points &#xff0c;其中 points[i] [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 &#xff0c;其中 i 和…...

容器相关笔记

目录 1.容器 1.什么是容器 2.java中的容器 3.容器里存放的是引用数据类型&#xff08;存对象的地址&#xff0c;不是对象本身&#xff09;&#xff0c;不能存基本数据类型 4.容器存放的两种格式 5.容器类所在的包 6.容器的分类 1.Collection&#xff0c;存放单一的类型 1.List&…...

cissp 第10章 : 物理安全要求

10.1 站点与设施设计的安全原则 物理控制是安全防护的第一条防线&#xff0c;而人员是最后一道防线。 10.1.1 安全设施计划 安全设施计划描述了组织的安全要求的轮廓&#xff0c; 并且着重强调为了提供安全性所用的方法和机制。 这样的计划通过被称为关键路径分析的过程进行开…...

聊一聊 .NET高级调试 内核模式堆泄露

一&#xff1a;背景 1. 讲故事 前几天有位朋友找到我&#xff0c;说他的机器内存在不断的上涨&#xff0c;但在任务管理器中查不出是哪个进程吃的内存&#xff0c;特别奇怪&#xff0c;截图如下&#xff1a; 在我的分析旅程中都是用户态模式的内存泄漏&#xff0c;像上图中的…...

海外代理IP在游戏中有什么作用?

随着科技的飞速发展&#xff0c;手机和电脑等电子产品已成为互联网连接万物的重要工具&#xff0c;深度融入我们的日常生活&#xff0c;我们借助互联网完成工作、休闲和购物等任务&#xff0c;以求提升生活质量。 不仅如此&#xff0c;网络游戏也是人们心中最爱&#xff0c;它…...

高防ip适合防御网站和游戏类的攻击吗?

​  作为站长&#xff0c;要学会并承受得住网站外来攻击的压力&#xff0c;尤其是所属为 DDoS 攻击高发行业的网站类业务及游戏行业&#xff0c;是很容易被竞争对手或者一些伪黑客爱好者盯上的。 加上&#xff0c;有些站长并没有提前了解&#xff0c;就盲目进军了这两个行业&…...

HTML5和JS实现明媚月色效果

HTML5和JS实现明媚月色效果 先给出效果图&#xff1a; 源码如下&#xff1a; <!DOCTYPE html> <html> <head><title>明媚月光效果</title><style>body {margin: 0;overflow: hidden;background-color: #000; /* 添加一个深色背景以便看到…...

澳大利亚网站后缀/百家号优化

#!/usr/bin/env python import socket import time import threading #Pressure Test,ddos tool ​ #--------------------------- MAX_CONN20000 PORT80 HOST"www.zhaihongyu.tech"#在双引号里输入对方IP或域名&#xff0c;要保证他联网了或开机了. PAGE"index…...

比较有设计感的网站/江苏网站seo营销模板

<?php //把字符串中的任意空格换成一个 $str1 ‘A B C ‘; echo‘<xmp>’; echopreg_replace (”/\s/”, ‘ ‘, $str1); echo‘</xmp>’; //把字符串中的任意连续字符 M 换成一个 M $str1 ‘AMMMBMMMMCMM ‘; echopreg_replace (”…...

网站被主流搜索引擎收录的网页数量是多少/磁力宅

一日从朋友处得到一网站权限&#xff0c;让我帮忙提权。拿到后看了看&#xff0c;C、D盘有只读权限&#xff0c;C:\Documents and Settings\All Users\Documents 可写。 没有装FTP软件和数据库。wscript.shell没有被禁用&#xff0c; 终端端口被改成45678 。试了试从外网连不上…...

b2b网站推广/谷歌在线浏览器免费入口

点击上方“iOS开发”&#xff0c;选择“置顶公众号” 关键时刻&#xff0c;第一时间送达&#xff01; 科技公司纷纷投入原创节目制作&#xff0c;苹果杀出重围或许不是什么难事。 如今市场竞争越来越激烈&#xff0c;对于许多电视台来说&#xff0c;能够吸引到观众观看的就是独…...

wordpress标签图片/怎么自己搭建网站

作者&#xff1a;朱金灿来源&#xff1a;http://blog.csdn.net/clever101 前天看一个系统的代码&#xff0c;突然对面向对象和面向过程有了一些新的理解。简而言之&#xff0c;面向对象采用空间换时间的策略&#xff0c;面向过程采用时间换空间的策略&#xff0c;正因为采用不同…...

wordpress 注册邮件设置/互动营销名词解释

在我们使用电脑的时候&#xff0c;有些情况下可能就会遇到我们的电脑出现没有启动服务器服务的情况。对于这种问题小编觉得可能是因为我们系统本身就没有开启服务器服务&#xff0c;只要我们手动开启即可。可以在运行中打开services.msc服务&#xff0c;然后进行相关的设置即可…...