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

Linux下C语言使用 netlink sockets与内核模块通信

netlink简介

Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。在Linux标准内核中,系统默认集成了很多netlink实例,比如日志上报、路由系统等,netlink消息是双向的,应用层可以发送消息到内核,同时内核也可以发送消息到应用层进程,非常适合涉及到内核信息采集的模块。

与ioctl的区别

netlink采用sock方式实现,而ioctl采用驱动注册方式实现。netlink通常用于传输大量消息,而ioctl通常用于下发系统命令,不支持内核主动发送消息到应用层。
什么情况下用netlink?
在开发过程中,我们会面临消息通信机制的选型,这和应用层消息通信选型一样,每个通信方式都有自己的优缺点。采用netlink机制一般需要应用层单独起进程用于监听内核发送上来的消息,开发工作量相对于ioctl较大,而ioctl主要用于驱动消息下发,比如无线驱动的iwpriv命令实现,就采用ioctl机制。

内核模块hello_kernel.c

#include <linux/module.h>
#include <net/sock.h> 
#include <linux/netlink.h>
#include <linux/skbuff.h> 
#define NETLINK_USER 31struct sock *nl_sk = NULL;static void hello_nl_recv_msg(struct sk_buff *skb)
{struct nlmsghdr *nlh;int pid;struct sk_buff *skb_out;int msg_size;char *msg = "Hello from kernel";int res;printk(KERN_INFO "Entering: %s\n", __FUNCTION__);msg_size = strlen(msg);nlh = (struct nlmsghdr *)skb->data;printk(KERN_INFO "Netlink received msg payload:%s\n", (char *)nlmsg_data(nlh));pid = nlh->nlmsg_pid; /*pid of sending process */skb_out = nlmsg_new(msg_size, 0);if (!skb_out) {printk(KERN_ERR "Failed to allocate new skb\n");return;}nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */strncpy(nlmsg_data(nlh), msg, msg_size);res = nlmsg_unicast(nl_sk, skb_out, pid);if (res < 0)printk(KERN_INFO "Error while sending bak to user\n");
}static int __init hello_init(void)
{printk("Entering: %s\n", __FUNCTION__);//nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg, NULL, THIS_MODULE);struct netlink_kernel_cfg cfg = {.input = hello_nl_recv_msg,};nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);if (!nl_sk) {printk(KERN_ALERT "Error creating socket.\n");return -10;}return 0;
}static void __exit hello_exit(void)
{printk(KERN_INFO "exiting hello module\n");netlink_kernel_release(nl_sk);
}module_init(hello_init); 
module_exit(hello_exit);
MODULE_LICENSE("GPL");

应用层代码hello.c

#include <linux/netlink.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>#define NETLINK_USER 31#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;int main()
{sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);if (sock_fd < 0)return -1;memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid(); /* self pid */bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0; /* For Linux Kernel */dest_addr.nl_groups = 0; /* unicast */nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);nlh->nlmsg_pid = getpid();nlh->nlmsg_flags = 0;strcpy(NLMSG_DATA(nlh), "Hello");iov.iov_base = (void *)nlh;iov.iov_len = nlh->nlmsg_len;msg.msg_name = (void *)&dest_addr;msg.msg_namelen = sizeof(dest_addr);msg.msg_iov = &iov;msg.msg_iovlen = 1;printf("Sending message to kernel\n");sendmsg(sock_fd, &msg, 0);printf("Waiting for message from kernel\n");/* Read message from kernel */recvmsg(sock_fd, &msg, 0);printf("Received message payload: %s\n", NLMSG_DATA(nlh));close(sock_fd);return 0;
}

 Makefile

bin=hello
obj-m = hello_kernel.o
KVERSION = $(shell uname -r)
all:$(bin)make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
bin:gcc hello.c -o hello
clean:make -C /lib/modules/$(KVERSION)/build M=$(PWD) cleanrm -rf hello.o hello

Makefile问题记录一下

chat:KVERSION = $(shell uname -r)去掉shell有什么区别?

在Makefile中,`$(shell ...)`是一个用于执行命令并获取其输出的内置函数。在你提到的语句中,`$(shell uname -r)`用于执行`uname -r`命令来获取当前Linux内核的版本,并将结果赋值给`KVERSION`变量。如果你去掉`shell`,那么整个语句就会变成:
KVERSION = uname -r
这将不再是一个命令执行语句,而是一个简单的变量赋值语句。这意味着`KVERSION`的值将直接设置为字符串`"uname -r"`,而不是执行`uname -r`命令并获取其输出。
因此,区别在于:
- `KVERSION = $(shell uname -r)`:这会执行`uname -r`命令,获取内核版本,并将结果作为字符串赋值给`KVERSION`变量。
- `KVERSION = uname -r`:这只是将字符串`"uname -r"`赋值给`KVERSION`变量,不会执行命令或获取内核版本。
如果你想要将内核版本赋值给`KVERSION`变量,你应该使用`$(shell ...)`来执行命令。否则,你将只是将命令字符串本身赋值给变量,而不会获取命令的输出。

make  -C什么意思?

`make -C` 是 `make` 命令的一个选项,用于指定 `make` 命令应该在哪个目录下执行。
语法为:
make -C <目录>
其中 `<目录>` 是你希望 `make` 命令执行的目录的路径。
这个选项通常用于在项目的子目录中执行 `make` 命令,以便构建子项目或依赖于其他目录中的代码的项目。这对于在大型项目中管理多个模块或组件的构建过程非常有用,因为你可以在每个子目录中维护一个独立的 `Makefile` 文件,并使用 `-C` 选项来指定要构建的子目录。
例如,如果你有一个名为 `subproject` 的子目录,并在该目录中有一个名为 `Makefile` 的构建文件,你可以使用以下命令在 `subproject` 目录中执行 `make`:
make -C subproject
这将导致 `make` 命令在 `subproject` 目录中查找并执行 `Makefile` 文件,执行与该子项目相关的构建任务。

运行结果:

应用层

内核,先加载.ko,运行hello之后,用dmesg就可查看收到的消息

代码来源:

Linux下C语言如何使用 netlink sockets与内核模块通信?_c语言nlmsghdr的使用_wellnw的博客-CSDN博客

相关文章:

Linux下C语言使用 netlink sockets与内核模块通信

netlink简介 Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。在Linux标准内核中&#xff0c;系统默认集成了很多netlink实例&#xff0c;比如日志上报、路由系统等&#xff0c;netlink消息是双向的&a…...

excel中的引用与查找函数篇3

1、INDEX(array,row_num,[col_num])&#xff1a;获取指定范围中指定行号和列号对应的数据 index(查询范围,行号,列号) 行号和列号是相对选中查询范围来写的&#xff1a;分别把第二行第三列的数据和第四行第二列的数据查找出来。 数据是单行或单列&#xff0c;后面只需要给一个参…...

【Linux学习笔记】 - 常用指令学习及其验证(下)

前言&#xff1a;本文延续上一篇文章【Linux学习笔记】 - 常用指令学习及其验证&#xff08;上&#xff09;对常用的指令进行介绍和验证。 一、mv指令 &#xff08;1&#xff09;功能&#xff1a;用来移动文件或者将文件改名 &#xff08;2&#xff09;语法及验证&#xff1a…...

面试官:请说说flex布局_番茄出品.md

面试官&#xff1a;请说说flex布局_番茄出品.md start 依然记得当初学习 flex 布局时&#xff0c;用 flex 布局&#xff1a;画麻将。一筒到九筒&#xff0c;应有尽有。但是光和面试官说&#xff0c;我用 flex 布局画过麻将&#xff0c;并没有什么用。面试官问你一个语法&…...

ChatGLM DeepSpeed/P-Tuning v2 调参

之前尝试了基于ChatGLM-6B使用LoRA进行参数高效微调,本文给大家分享使用DeepSpeed和P-Tuning v2对ChatGLM-6B进行微调,相关代码放置在GitHub上面:llm-action。 ChatGLM-6B简介 ChatGLM-6B相关的简介请查看之前的文章,这里不再赘述。 P-Tuning v2简介 P-Tuning是一种较新…...

Leetcode每日一题:打家劫舍系列Ⅰ、Ⅱ、Ⅲ、Ⅳ(2023.9.16~2023.9.19 C++)

由于之前写过打家劫舍系列&#xff0c;这里直接弄个合集&#xff0c;后面应该还有个iv。 目录 198. 打家劫舍 213. 打家劫舍 II 337. 打家劫舍 III 2560. 打家劫舍 IV 198. 打家劫舍 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都…...

容易对一个异性产生依赖感怎么办?

歌词&#xff1a;爱总让人伤心&#xff0c;但你要学会去明白~ &#x1f442; Photograph - Ed Sheeran - 单曲 - 网易云音乐 目录 &#x1f33c;前言 &#x1f61f;一、对另一个人的依赖感&#xff0c;本质是什么&#xff1f; &#x1f60a;二、如何减少对伴侣的依赖感&am…...

Windows10/11无线网卡WIFI驱动详细下载安装教程

官网下载WIFI驱动 《intel官网》 找到下载Windows 10 and Windows 11* WiFi package drivers 查看详细信息 下载对应操作系统的WIFI驱动 安装驱动&#xff0c;然后重启电脑即可。...

面向面试知识--Lottery项目

面向面试知识–Lottery项目 1.设计模式 为什么需要设计模式&#xff1f; &#xff08;设计模式是什么&#xff1f;优点有哪些&#xff1f;&#xff09; 设计模式是一套经过验证的有效的软件开发指导思想/解决方案&#xff1b;提高代码的可重用性和可维护性&#xff1b;提高团…...

SpringBoot接口中如何直接返回图片数据

SpringBoot接口中如何直接返回图片数据 目录 接口直接返回图片数据 起因 类似这种 根据个人经验 优雅的实现图片返回 接口直接返回图片数据 起因 最近在做涉及到分享推广的业务&#xff0c;需要由业务员分享二维码进入推广页面&#xff0c;由于是新项目&#xff0c;前期…...

c语言进阶部分详解(指针进阶1)

大家好&#xff01;指针的初阶内容我已经写好&#xff0c;可移步至我的文章&#xff1a;c语言进阶部分详解&#xff08;指针初阶&#xff09;_总之就是非常唔姆的博客-CSDN博客 基本内容我便不再赘述&#xff0c;直接带大家进入进阶内容&#xff1a; 目录 一.字符指针 1.讲解…...

计算机竞赛 大数据商城人流数据分析与可视化 - python 大数据分析

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的基站数据分析与可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度…...

各种电机驱动原理

步进电机 步进电机参考资料 野火官方文档 步进电机驱动原理 上面参考文档中有的内容就不写了&#xff0c;写一下我自己的总结吧。 说明&#xff1a; 电机驱动器输入信号有电机转动方向信号DIR&#xff0c;电机转速信号PWM&#xff0c;电机使能信号EN&#xff1b;电机驱动器…...

人脸图像数据增强

为什么要做数据增强 在计算机视觉相关任务中&#xff0c;数据增强&#xff08;Data Augmentation&#xff09;是一种常用的技术&#xff0c;用于扩展训练数据集的多样性。它包括对原始图像进行一系列随机或有规律的变换&#xff0c;以生成新的训练样本。数据增强的主要目的是增…...

Android 查看按键信息的常用命令详解

Android 查看按键信息的常用命令详解 文章目录 Android 查看按键信息的常用命令详解一、主要命令&#xff1a;二、命令详解1、getevent2、getevent -l3、dumsys input4、cat XXX.kl4、cat /dev/input/eventX5、getevent 其他命令6、input keyevent XX 三、简单示例修改四、总结…...

【Java 基础篇】Properties 结合集合类的使用详解

Java 中的 Properties 类是一个常见的用于管理配置信息的工具&#xff0c;它可以被看作是一种键值对的集合。虽然 Properties 通常用于处理配置文件&#xff0c;但它实际上也可以作为通用的 Map 集合来使用。在本文中&#xff0c;我们将详细探讨如何使用 Properties 作为 Map 集…...

数字孪生体标准编程

数字孪生体标准 括ISO TC184/SC4正在制定数字孪生制造标准ISO 23247、ISO/IEC JTC1/AG11正在推动数字孪生体标准、IEEE P2806正在做有关“数字表达”的标准。赢家通吃的标准战 卡尔夏皮罗和哈尔范里安撰写了《信息规则&#xff1a;网络经济战略指南》&#xff08;Information R…...

力扣 -- 394. 字符串解码

解题方法&#xff1a; 参考代码&#xff1a; class Solution{ public:string decodeString(string s){stack<string> sst;stack<int> dst;//防止字符串栈为空的时候再追加字符串到栈顶元素sst.push("");int n s.size();int i 0;while(i<n)//最好不…...

面试官:什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、什么是虚拟DOM 二、为什么需要虚拟DOM 三、如何实现虚拟DOM 小结 一、什么是虚拟DOM 虚拟 DOM &#xff08…...

Ubuntu安装中文拼音输入法

ubuntu安装中文拼音输入法 ubuntu版本为23.04 1、安装中文语言包 首先安装中文输入法必须要让系统支持中文语言&#xff0c;可以在 Language Support 中安装中文语言包。 添加或删除语音选项&#xff0c;添加中文简体&#xff0c;然后会有Applying changes的对话框&#x…...

高端知识竞赛中用到的软件和硬件有哪些

现在单位搞知识竞赛&#xff0c;已不满足于用PPT放题&#xff0c;找几个简单的抢答器、计分牌弄一下了&#xff0c;而是对现场效果和科技感要求更高了。大屏要分主屏侧屏&#xff0c;显示内容要求丰富炫酷&#xff1b;选手和评委也要用到平板等设备&#xff1b;计分要大气些&am…...

Vue 3.3 发布

本文为翻译 原文地址&#xff1a;宣布推出 Vue 3.3 |The Vue Point (vuejs.org) 今天我们很高兴地宣布 Vue 3.3 “Rurouni Kenshin” 的发布&#xff01; 此版本侧重于开发人员体验改进 - 特别是 TypeScript 的 SFC <script setup> 使用。结合 Vue Language Tools&…...

算法|图论 3

LeetCode 130- 被围绕的区域 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目描述&#xff1a;给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域…...

【数据结构】二叉树的层序遍历(四)

目录 一&#xff0c;层序遍历概念 二&#xff0c;层序遍历的实现 1&#xff0c;层序遍历的实现思路 2&#xff0c;创建队列 Queue.h Queue.c 3&#xff0c;创建二叉树 BTree.h BTree.c 4&#xff0c;层序遍历的实现 一&#xff0c;层序遍历概念 层序遍历&#xff1a;除了先序…...

macOS文件差异比较最佳工具:Beyond Compare 4

Beyond Compare for mac是一款Scooter Software研发的文件同步对比工具。你可以选择针对多字节的文本、文件夹、源代码&#xff0c;甚至是支持比对adobe文件、pdf文件或是整个驱动器&#xff0c;检查其文件大小、名称、日期等信息。你也可以选择使用Beyond Compare合并两个不同…...

Windows+Pycharm 如何创建虚拟环境

当我们开发一个别人的项目的时候,因为项目里有很多特有的包,比如 Pyqt5.我们不想破坏电脑上原来的包版本,这个时候,新建一个虚拟环境,专门针对这个项目就很有必要了. 简略步骤: 1.新建虚拟环境 1.打开 pycharm 终端(Terminal)安装虚拟环境工具: pip install virtualenv2.创…...

vant 按需导入 vue2

vant 按需导入 vue2 1、通过npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&#xff0c;安装 Vant 2&#xff1a; npm i vantlatest-v2 -S2、自动按需引入组件 babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中…...

Java手写分治算法和分治算法应用拓展案例

Java手写分治算法和分治算法应用拓展案例 1. 算法思维导图 以下是用Mermanid代码表示的分治算法的实现原理&#xff1a; #mermaid-svg-nvJwIm97kPHEXQOR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nvJwIm97kP…...

学习 CodeWhisperer 的一些总结

目前一些常见的的 AI 工具 GitHub Copilot&#xff1a;GitHub 与 OpenAI 合作开发的一个人工智能助手。 Codeium&#xff1a;是一个免费的人工智能驱动的代码生成工具 Tabnine&#xff1a;一个自动代码生成工具&#xff0c;免费版本非常有限&#xff0c;只提供简短的代码完成…...

JavaScript 中的 `this` 指向问题与其在加密中的应用

JS中的 this 关键字是一个非常重要的概念&#xff0c;它在不同情况下会指向不同的对象或值。在本文中&#xff0c;我们将深入探讨 JavaScript 中 this 的各种情况&#xff0c;并思考如何将其应用于 JS加密中的一些有趣用途。 1. 全局上下文中的 this 在全局上下文中&#xff…...

昆山做网站找哪家好/企业如何注册自己的网站

目录&#xff1a; 1 网络请求API和封装 2 展示弹窗和页面分享 3 设备信息和位置信息 4 小程序Storage存储 5 页面跳转和数据传递 6 小程序登录流程演练 小程序的网络请求&#xff0c;不管是post还是get的请求的数据都是写在data里面的。 网络请求一般写在onLoad()的页面生…...

住房和城乡建设网站方案/百度今日排行榜

安装php时候遇到的问题&#xff1a; dpkg: 处理软件包 php7.1-opcache (--configure)时出错&#xff1a; 依赖关系问题 - 仍未被配置dpkg: 依赖关系问题使得 php7.1-readline 的配置工作不能继续&#xff1a; php7.1-readline 依赖于 php7.1-common&#xff1b;然而&#xff1a…...

ui网页界面设计素材/seo教程

一个日期时间显示框的美化风格示例&#xff0c;在网页上显示时间的一个美化示例&#xff0c;为时间显示框增加了一个漂亮的外框&#xff0c;这个外框是基于图片来美化的&#xff0c;&#xff0c;虽然现在都不主张用图片来美化了&#xff0c;不过看上去还真是挺漂亮的。www.srcf…...

用wordpress做视频网站/郑州全域静态管理

sql是声明性语言&#xff1a;首先要把这个概念记在脑中&#xff1a;“声明”。 SQL 语言是为计算机声明了一个你想从原始数据中获得什么样的结果的一个范例&#xff0c;而不是告诉计算机如何能够得到结果。 SQL 语言声明的是结果集的属性&#xff0c;计算机会根据 SQL 所声明的…...

福州手机模板建站/淘宝关键词指数查询

文章目录前言一、多人音视频对话1.wxml2.js前言 微信小程序开发多人音视频对话首先得去小程序管理后台&#xff0c;「开发」-「接口设置」中自助开通该组件权限。 相关属性&#xff1a; 一级类目/主体类型二级类目小程序内容场景教育在线视频课程网课、在线培训、讲座等教育…...

咨询聊城网站建设/网站发布平台

系统环境&#xff1a; ubuntu 16.04 64bit开发环境&#xff1a;SW4STM32记录时间&#xff1a; 2017年07月01日联系方式&#xff1a; yexiaopeng1992126.com背景&#xff1a; 在ubuntu下使用ST官方推出的SW4STM32进行STM32的开发 出现的问题&#xff1a;不进入中断 原因&#xf…...