Linux内核 -- Netlink多播组消息处理技术

Netlink多播组消息处理技术文档

概述

Netlink是一种用户态与内核态之间通信的机制,支持单播和多播模式。多播组允许多个用户态进程接收同一组的广播消息,广泛应用于网络事件、系统通知等场景。

本文将详细介绍如何在内核态发送多播组消息,以及用户态如何接收并处理这些消息。


内核态:发送多播组消息

实现步骤

  1. 创建Netlink套接字:通过netlink_kernel_create创建一个Netlink套接字。
  2. 构建消息:填充nlmsghdr头部和数据部分。
  3. 发送消息:使用netlink_broadcast将消息广播到指定多播组。

示例代码

#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/skbuff.h>#define NETLINK_USER 31
#define MULTICAST_GROUP1 (1 << 0)
#define MULTICAST_GROUP2 (1 << 1)static struct sock *nl_sock = NULL;// 初始化Netlink套接字
static int __init netlink_init(void) {struct netlink_kernel_cfg cfg = {.groups = MULTICAST_GROUP1 | MULTICAST_GROUP2, // 支持的多播组.input = NULL, // 无需接收消息};nl_sock = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);if (!nl_sock) {printk(KERN_ERR "Failed to create Netlink socket\n");return -ENOMEM;}printk(KERN_INFO "Netlink socket created\n");return 0;
}// 向多播组发送消息
static void send_multicast_message(const char *message, uint32_t group) {struct sk_buff *skb;struct nlmsghdr *nlh;int msg_size = strlen(message) + 1;skb = nlmsg_new(msg_size, GFP_KERNEL);if (!skb) {printk(KERN_ERR "Failed to allocate sk_buff\n");return;}nlh = nlmsg_put(skb, 0, 0, NLMSG_DONE, msg_size, 0);strcpy(nlmsg_data(nlh), message);netlink_broadcast(nl_sock, skb, 0, group, GFP_KERNEL);printk(KERN_INFO "Message sent to group %u: %s\n", group, message);
}// 模块加载函数
static int __init netlink_multicast_init(void) {int ret = netlink_init();if (ret) return ret;send_multicast_message("Hello Group 1", MULTICAST_GROUP1);send_multicast_message("Hello Group 2", MULTICAST_GROUP2);return 0;
}// 模块卸载函数
static void __exit netlink_multicast_exit(void) {if (nl_sock) {netlink_kernel_release(nl_sock);printk(KERN_INFO "Netlink socket released\n");}
}module_init(netlink_multicast_init);
module_exit(netlink_multicast_exit);
MODULE_LICENSE("GPL");

用户态:接收多播组消息

实现步骤

  1. 创建Netlink套接字:使用socket()创建用户态的Netlink套接字。
  2. 订阅多播组:通过setsockopt()将套接字加入一个或多个多播组。
  3. 接收消息:使用recvmsg()从套接字中接收消息。
  4. 处理消息:解析nlmsghdr头部并处理数据。

示例代码

#include <linux/netlink.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>#define NETLINK_USER 31
#define MULTICAST_GROUP1 (1 << 0)
#define MULTICAST_GROUP2 (1 << 1)
#define MAX_PAYLOAD 1024struct nl_msg {struct nlmsghdr hdr;char data[MAX_PAYLOAD];
};// 初始化Netlink套接字并订阅多播组
int init_netlink_socket(int *sock_fd, uint32_t groups) {struct sockaddr_nl src_addr;*sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);if (*sock_fd < 0) {perror("socket");return -1;}memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid(); // 当前进程PIDsrc_addr.nl_groups = groups;if (bind(*sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {perror("bind");close(*sock_fd);return -1;}if (setsockopt(*sock_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &groups, sizeof(groups)) < 0) {perror("setsockopt NETLINK_ADD_MEMBERSHIP");close(*sock_fd);return -1;}return 0;
}// 动态加入多播组
int join_multicast_group(int sock_fd, uint32_t group) {if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group)) < 0) {perror("setsockopt NETLINK_ADD_MEMBERSHIP");return -1;}printf("Joined multicast group: %u\n", group);return 0;
}// 动态退出多播组
int leave_multicast_group(int sock_fd, uint32_t group) {if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &group, sizeof(group)) < 0) {perror("setsockopt NETLINK_DROP_MEMBERSHIP");return -1;}printf("Left multicast group: %u\n", group);return 0;
}// 接收并处理消息
void receive_messages(int sock_fd) {struct nl_msg msg;struct sockaddr_nl src_addr;struct iovec iov;struct msghdr msghdr;while (1) {memset(&msg, 0, sizeof(msg));memset(&src_addr, 0, sizeof(src_addr));memset(&msghdr, 0, sizeof(msghdr));iov.iov_base = &msg;iov.iov_len = sizeof(msg);msghdr.msg_name = &src_addr;msghdr.msg_namelen = sizeof(src_addr);msghdr.msg_iov = &iov;msghdr.msg_iovlen = 1;int ret = recvmsg(sock_fd, &msghdr, 0);if (ret < 0) {perror("recvmsg");break;}printf("Received message from group: %u\n", src_addr.nl_groups);printf("Message: %s\n", msg.data);}
}int main() {int sock_fd;uint32_t groups = MULTICAST_GROUP1; // 初始订阅组if (init_netlink_socket(&sock_fd, groups) < 0) {return -1;}// 动态加入组2join_multicast_group(sock_fd, MULTICAST_GROUP2);printf("Listening for multicast messages...\n");receive_messages(sock_fd);// 动态退出组2leave_multicast_group(sock_fd, MULTICAST_GROUP2);close(sock_fd);return 0;
}

总结

通过以上步骤,内核态可以发送Netlink多播组消息,用户态可以接收并处理这些消息,同时支持动态加入和退出多播组的功能。本文提供的代码可以用于实际开发中,帮助实现高效的内核态与用户态通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL 基础教程 - SQL SELECT 语句

SQL SELECT DISTINCT 语句 SELECT DISTINCT 语句用于返回唯一不同的值。 在表中&#xff0c;一个列可能会包含多个重复值&#xff0c;有时您也许希望仅仅列出不同&#xff08;distinct&#xff09;的值。 DISTINCT 关键词用于返回唯一不同的值。 SQL SELECT DISTINCT 语法 …

使用Anaconda管理R语言环境,并使用Jupyter Notebook编写R语言

文章目录 Anaconda中创建R环境0 官方教程存在的问题1 创建R语言环境2 安装常用包集合&#xff1a;r-essentials3 用VS Code的Jupyter插件写R 相信一直使用Python搞数据分析、机器学习的同学们会习惯使用 Anaconda管理不同的Python环境&#xff0c;并使用Jupyter Notebook&#…

3.5mm耳机接口硬件连接

结构 以最复杂的结构为例 简单的结构无非就是没有MIC&#xff08;麦克风&#xff09;接口 上图的5就是Detect的作用 上面这两款产品都为3.5mm的音频插座&#xff0c;图一 为连接4节的音频座&#xff0c;而且有两个开关&#xff0c;1接地&#xff0c;2接MIC&#xff0c;3接左声…

第25天:信息收集-项目系统一键打点资产侦察企查产权空间引擎风险监测利器部署

#知识点 1、信息收集-项目推荐-自动化环境部署 2、信息收集-项目推荐-自动化资产收集管理 一、自动化-网络空间-Yakit&TscanPlus 项目地址&#xff1a;https://www.yaklang.com/ 项目地址&#xff1a;https://github.com/TideSec/TscanPlus 集成Fofa、Hunter、Quake、Zoome…

vue3学习笔记(11)-组件通信

1.props 父传子 子传夫 父传子 接收用defineProps([]) 空字符串也是假 2.自定义事件 $event:事件对象 ref定义的数据在模板里面引用的时候可以不用.value 3.子传父 宏函数 触发事件 声明事件 defineEmits() 挂载之后3s钟触发 4.命名 肉串命名 5.任意组件通信 mitt pubs…

1 数据库(下):多表设计 、多表查询 + SQL中的with查询语法(MySQL8.0以后版本才支持这种新语法)+ 数据库优化(索引优化)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、多表设计1 多表设计-概述2 三种多表关系一对多&#xff08;多对一&#xff09;&#xff08;1&#xff09;无外键约束&#xff08;逻辑外键&#xff09;&…

Supermap iClient Webgl 粒子特效案例-消防场景

作者&#xff1a;Lzzzz 前言 WebGL 粒子特效的应用场景非常广泛&#xff0c;几乎可以在任何需要丰富视觉效果或动态表现的地方看到其身影。通过灵活运用颗粒系统&#xff0c;开发者可以创造出引人入胜的用户体验和视觉表现。 一、效果展示 二、实现步骤 1&#xff0c;构建…

Eclipse常用快捷键详解

文章目录 Eclipse常用快捷键详解一、引言二、编辑快捷键三、选择和移动快捷键四、行操作快捷键五、搜索和导航快捷键六、调试快捷键七、重构快捷键八、其他快捷键九、使用案例场景一&#xff1a;代码编写代码示例 场景二&#xff1a;代码调试场景三&#xff1a;代码重构代码示例…

【MATLAB】股票(和指数)数据下载--雅虎财经

文章目录 一、构建请求二、响应解读及整理2.1 响应2.2 数据提取和保存 三、通用函数3.1 函数3.2 调用示例 四、雅虎财经股票、指数代码4.1 指数4.2 股票 五、GUI界面、可执行程序 雅虎2021年就退出中国了&#xff0c;你懂的。 能下载股票等数据的财经网站、软件也很多。我写着玩…

Unity 使用UGUI制作卷轴开启关闭效果

视频效果 代码 using UnityEngine.UI; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options;public class JuanZhou : MonoBehaviour {[SerializeField]private …

Bash 脚本教程

注&#xff1a;本文为 “Bash 脚本编写” 相关文章合辑。 BASH 脚本编写教程 as good as well于 2017-08-04 22:04:28 发布 这里有个老 American 写的 BASH 脚本编写教程&#xff0c;非常不错&#xff0c;至少没接触过 BASH 的也能看懂&#xff01; 建立一个脚本 Linux 中有…

NPM组件包 vant部分版本内嵌挖矿代码

Vant 是一个轻量、可定制的移动端组件库&#xff0c;于 2017 年开源。 目前 Vant 官方提供了 Vue 2 版本、Vue 3 版本和微信小程序版本&#xff0c;并由社区团队维护 React 版本和支付宝小程序版本。 Vant 2 版本&#xff1a;https://vant-ui.github.io/vant/v2/#/zh-CN/home V…

在基于Centos7的服务器上启用【Gateway】的【Clion Nova】(即 ReSharper C++ 引擎)

1. 检查启动报错日志&#xff0c;目录在 ~/.cache/JetBrains/CLion202x.x.x/log/backend.202x-xx-xx_xxxx.xxxx-err.log 2. 大致可能有两种报错 a. Process terminated. Couldnt find a valid ICU package installed on the system. 这个报错只需要装一下 libicu-devel 包即可…

Spring-Mybatis 2.0

前言&#xff1a; 第一点&#xff1a;过于依赖代码生成器或AI&#xff0c;导致基于mybaits的CRUD通通忘了&#xff0c;所以为了找回遗忘的记忆&#xff0c;有了该系列内容。 第二点&#xff1a;通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能…

Cypress测试框架详解:轻松实现端到端自动化测试

端到端自动化测试工具市场中&#xff0c;Cypress正以其易用性和强大功能&#xff0c;迅速成为开发者和测试人员的首选工具之一。无论是前端开发还是测试&#xff0c;Cypress都能在性能和效率上脱颖而出。 那么&#xff0c;Cypress具体能为端到端测试带来哪些便利&#xff1f;它…

ArrayList 和LinkedList的区别比较

前言 ‌ArrayList和LinkedList的主要区别在于它们的底层数据结构、性能特点以及适用场景。‌ArrayList和LinkedList从名字分析&#xff0c;他们一个是Array&#xff08;动态数组&#xff09;的数据结构&#xff0c;一个是Linked&#xff08;链表&#xff09;的数据结构&#x…

WebRTC:实现浏览器与移动应用的实时通信

1.技术简介 &#xff08;Web Real-Time&#xff09;是一种开放式实时通信技术&#xff0c;旨在使浏览器和移动应用程序通过简单的API即可实现实时音频、视频和数据传输&#xff0c;而无需安装插件或额外软件。它支持网络应用中的点对点通信&#xff0c;例如视频聊天、语音通话…

Microsoft word@【标题样式】应用不生效(主要表现为在导航窗格不显示)

背景 随笔。Microsoft word 2013基础使用&#xff0c;仅做参考和积累。 问题 Microsoft word 2013&#xff0c;对段落标题文字应用【标题样式】不生效&#xff08;主要表现为在导航窗格不显示&#xff09;。 图1 图2 观察图1和图2&#xff0c;发现图1的文字在应用【标题一】样…

kafka开机自启失败问题处理

前言&#xff1a;在当今大数据处理领域&#xff0c;Kafka 作为一款高性能、分布式的消息队列系统&#xff0c;发挥着举足轻重的作用。无论是海量数据的实时传输&#xff0c;还是复杂系统间的解耦通信&#xff0c;Kafka 都能轻松应对。然而&#xff0c;在实际部署和运维 Kafka 的…

WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)

在一个WPF项目中要用到样条曲线&#xff0c;必须过顶点&#xff0c;圆滑后还不能太走样&#xff0c;捣鼓一番&#xff0c;发现里面颇有玄机&#xff0c;于是把我多方抄来改造的方法发出来&#xff0c;方便新手&#xff1a; 如上图&#xff0c;看代码吧&#xff1a; ----------…