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

libnl教程(2):发送请求

文章目录

    • 前言
    • 示例
      • 示例代码
      • 构造请求
      • 创建套接字
      • 发送请求
    • 简化示例

前言

前置阅读要求:libnl教程(1):订阅内核的netlink广播通知

本文介绍,libnl如何向内核发送请求。这包含三个部分:构建请求;创建套接字;发送请求。

同样,本文使用示例说明libnl的API该如何组合使用。

本文使用的示例是,发送netlink请求,以创建一张dummy网卡。


示例

示例代码

运行该示例代码,即可创建一个dummy类型的网卡。网卡名为dummy0

代码参考自:https://github.com/FDio/vpp/blob/master/src/vnet/devices/netlink.c

上面的参考代码很好,完整的显示了构建请求-创建套接字-发送请求-接收回复的过程。

但是上面参考代码的路子有点野。因为它很少调用libnl的API。它作为参考是好的。但是日常编程中,还是尽量调用libnl的API。

下面的示例代码中,我在展示逻辑结构的基础上,尽量调用了libnl的API。

#include <linux/rtnetlink.h>
#include <netlink/msg.h>
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#include <netlink/socket.h>int netlink_add(const char *iftype, const char *ifname) {int ret = 0;struct nl_msg *msg = NULL;struct nl_sock *sk = NULL;// 构建请求msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK |NLM_F_CREATE | NLM_F_EXCL);struct ifinfomsg ifi = {};ifi.ifi_family = AF_UNSPEC;ret = nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO);if (ret < 0) {printf("%s", nl_geterror(ret));goto end;}#if 0ret = nla_put_string(msg, IFLA_INFO_KIND, iftype);if (ret < 0) {goto end;}
#endifstruct nlattr *info = nla_nest_start(msg, IFLA_LINKINFO);ret = nla_put_string(msg, IFLA_INFO_KIND, iftype);if (ret < 0) {printf("%s", nl_geterror(ret));goto end;}nla_nest_end(msg, info);ret = nla_put_string(msg, IFLA_IFNAME, ifname);if (ret < 0) {printf("%s", nl_geterror(ret));goto end;}// 创建套接字sk = nl_socket_alloc();nl_connect(sk, NETLINK_ROUTE);// 发送请求ret = nl_send_auto(sk, msg);if (ret < 0) {printf("%s", nl_geterror(ret));goto end;}// 接收回复ret = nl_recvmsgs_default(sk);if (ret < 0) {printf("%s", nl_geterror(ret));goto end;}end:nlmsg_free(msg);nl_socket_free(sk);return 0;
}int main(int argc, char *argv[]) { netlink_add("dummy", "dummy0"); }

构造请求

一个Link请求包含三部分:

  • netlink header(struct nlmsghdr): netlink消息本身的头。其余部分都是netlink消息的负载。整个消息都遵循TLV(Type–length–value)。消息头中记录着消息的整体长度。后面的负载中的属性也遵循TLV。
  • netlink link messages header(struct ifinfomsg): Link请求的消息头。
  • netlink attributes(struct nlattr): 一个属性的类型和长度,后面要跟着具体的属性。

请求的整体格式如下。

在这里插入图片描述

在内存中,有对齐要求,格式如下。

在这里插入图片描述

接下来介绍,该如何填充这些内容。

  • struct nlmsghdr的填充:可以使用 nlmsg_alloc_simple(int nlmsg_type, int flags)函数填充。调用这些API的好处是,可以屏蔽 sequence numbers、port等细节。代码中的消息类型是RTM_NEWLINK表示创建网卡。标志的含义表示,这是一个请求,需要回复,请求创建一张网卡,如果网卡已经存在,则不在创建。
  • struct ifinfomsg的填充:示例代码没有填充任何内容。因为是创建网卡。如果是查询/修改网卡等操作,需要根据不同情况填充不同内容。
  • struct nlattr的填充:示例追加了两个属性,分别用来设置网卡类型和网卡名称。为什么网卡类型使用嵌套属性。因为我们用户层是发起请求,这个是内核路由部分的要求。我是咋知道的呢?因为我去看来libnl中rtnl_link_add()函数的源码知道的。

创建套接字

使用libnl的接口创建套接字。当然,我们也可以跳过libnl的API,直接使用socket创建套接字,但是没必要。

sk = nl_socket_alloc();
nl_connect(sk, NETLINK_ROUTE);

发送请求

通过netlink套接字,发送netlink消息的标准方法是,使用nl_send_auto()函数。它将自动补充netlink消息头中丢失的内容信息,然后将消息传递给nl_send()


简化示例

上面示例中,最麻烦的一步是构造请求。

其实,我们想一想,构造请求基本都是固定的,只有很少的字段需要用户指定。

再想一想,其实请求和回复也基本是固定的。

这些都可以按照目的进行封装,形成更高层的接口。

下面,我们使用libnl的接口,可以更简单的实现我们的目标。(因为这个完全失去了请求的细节,所以我构造了上面的示例。)

#include <linux/rtnetlink.h>
#include <netlink/msg.h>
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#include <netlink/socket.h>int netlink_add(const char *iftype, const char *ifname) {struct rtnl_link *link = rtnl_link_alloc();rtnl_link_set_type(link, iftype);rtnl_link_set_name(link, ifname);struct nl_sock *sk = nl_socket_alloc();nl_connect(sk, NETLINK_ROUTE);rtnl_link_add(sk, link, NLM_F_CREATE | NLM_F_EXCL);return 0;
}int main(int argc, char *argv[]) { netlink_add("dummy", "dummy0"); }

相关文章:

libnl教程(2):发送请求

文章目录 前言示例示例代码构造请求创建套接字发送请求 简化示例 前言 前置阅读要求&#xff1a;libnl教程(1):订阅内核的netlink广播通知 本文介绍&#xff0c;libnl如何向内核发送请求。这包含三个部分&#xff1a;构建请求&#xff1b;创建套接字&#xff1b;发送请求。 …...

【软件测试】功能测试理论基础

目录 项目的测试流程&#x1f3f4; 需求评审 评审形式 测试人员在需求评审中职责 测试计划与方案 测试计划 问题 测试方案&#x1f3f4; 测试计划与方案的对比 功能测试设计&#x1f3f4; 测试设计的步骤 项目的测试流程&#x1f3f4; 作用&#xff1a; 有序有效开展…...

玩机进阶教程-----回读 备份 导出分区来制作线刷包 回读分区的写入与否 修改xml脚本

很多工作室需要将修改好的系统导出来制作线刷包。前面分享过很多制作线刷包类的教程。那么一个机型中有很多分区。那些分区回读后要写入。那些分区不需要写入。强写有可能会导致不开机 不进系统的故障。首先要明白。就算机型全分区导出后在写回去 都不一定可以开机进系统。那么…...

MongoDB 插入文档

MongoDB 插入文档 MongoDB 是一个流行的 NoSQL 数据库,它使用文档存储数据。在 MongoDB 中,数据以 BSON(Binary JSON)格式存储,这是一种二进制表示的 JSON 格式。MongoDB 提供了灵活的数据模型,使得插入和查询文档变得非常简单。本文将详细介绍如何在 MongoDB 中插入文档…...

【内网】服务器升级nginx1.17.0

今天用rpm包升级内网nginx版本&#xff0c;上来就给我报错 警告&#xff1a;nginx-1.27.0-2.el7.ngx.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 7bd9bf62: NOKEY 错误&#xff1a;依赖检测失败&#xff1a; libcrypto.so.10()(64bit) 被 nginx-1:1.27.0-2.el7.ngx.x…...

歌曲爬虫下载

本次编写一个程序要爬取歌曲音乐榜https://www.onenzb.com/ 里面歌曲。有帮到铁子的可以收藏和关注起来&#xff01;&#xff01;&#xff01;废话不多说直接上代码。 1 必要的包 import requests from lxml import html,etree from bs4 import BeautifulSoup import re impo…...

transformer-explainer

安装和启动 找到这个项目&#xff0c;然后装好了。 这个项目的目的如名字。 https://github.com/poloclub/transformer-explainerTransformer Explained: Learn How LLM Transformer Models Work with Interactive Visualization - poloclub/transformer-explainerhttps:/…...

C#中的S7协议

S7协议-S7COMM S7COMM 进行写 CTOP->PDU type已知枚举值 0X0E连接请求0x0d连接确认0x08断开请求0x0c断开确认0x05拒绝访问0x01加急数据0x02加急数据确认0x04用户数据0x07TPDU错误0x0f数据传输 S7Header->ROSCTR已知枚举值 0X01JOB REQUEST。主站发送请求0x02Ack。从站…...

2024-08-16升级记录:使用Android RecyclerView控件显示列表型信息

在页面上使用RecyclerView实现一个列表型信息展示&#xff1a; 步骤如下&#xff1a; 一、在页面布局中添加RecyclerView控件 <TextViewandroid:id"id/txt_gnss_info"android:layout_width"match_parent"android:layout_height"wrap_content"…...

通义千问 ( 一 ) 基础实例

1.相关概念 1.1.模型与平台 1.1.1.通义千问 通义千问 : 是阿里云研发的大语言模型&#xff1b;用于理解和分析用户输入的自然语言&#xff0c;在不同领域和任务为用户提供服务和帮助。 具体应用场景如下&#xff1a; 文字创作&#xff1a;撰写故事、公文、邮件、剧本和诗歌…...

docker 修改数据目录

1.停止 Docker 服务 sudo systemctl stop docker sudo systemctl stop docker.socket2.复制数据目录 sudo cp -rp /var/lib/docker /data/ 或 # sudo rsync -aP /var/lib/docker/ /data/docker/3.修改 Docker 配置 编辑 Docker 的配置文件&#xff0c;设置新的数据目录&#…...

r4s软路由写入iStoreOS镜像

需要用到的工具&#xff1a; 1、r4s软路由 2、32G及以上的TF卡 3、TF卡读卡器 4、镜像写入软件&#xff08;推荐Etcher&#xff0c;下载地址&#xff1a;https://github.com/balena-io/etcher/releases/download/v1.19.21/balenaEtcher-1.19.21.Setup.exe&#xff09; 5、…...

[C++][opencv]基于opencv实现photoshop算法灰度化图像

测试环境】 vs2019 opencv4.8.0 【效果演示】 【核心实现代码】 BlackWhite.hpp #ifndef OPENCV2_PS_BLACKWHITE_HPP_ #define OPENCV2_PS_BLACKWHITE_HPP_#include "opencv2/core.hpp"namespace cv {class BlackWhite { public:float red; //红色的灰度系…...

Emacs23.x版本之重要特性及用法实例(一百五十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…...

机器学习 第11章-特征选择与稀疏学习

机器学习 第11章-特征选择与稀疏学习 11.1 子集搜索与评价 我们将属性称为“特征”(feature)&#xff0c;对当前学习任务有用的属性称为“相关特征”(relevant feature)、没什么用的属性称为“无关特征”(irrelevant feature)。从给定的特征集合中选择出相关特征子集的过程&a…...

Grok 2携AI图片生成重生

埃隆马斯克&#xff08;Elon Musk&#xff09;的人工智能初创公司xAI推出其最新的AI助手Grok 2的测试版&#xff0c;添加了类似于OpenAI的DALL-E和Google的Gemini的图像生成工具&#xff0c;但对可以生成的图像类型的限制显然较少。<这是其中的一个“亮点”&#xff0c;一些…...

使用Nexus搭建Maven私服仓库

一、私服仓库简介 在Java的世界中&#xff0c;我们通常使用Maven的依赖体系来管理构件&#xff08;artifact&#xff0c;又称为二方库或三方库&#xff09;的依赖&#xff0c;Maven仓库用于存储这些构件。一般的远程仓库&#xff08;比如Maven Central&#xff09;只提供下载功…...

云计算day27

任务背景 公司的服务器越来越多, 维护⼀些简单的事情都会变得很繁琐。⽤ shell脚本来管理少量服务器效率还⾏, 服务器多了之后, shell脚本⽆ 法实现⾼效率运维。这种情况下&#xff0c;我们需要引⼊⾃动化运维⼯具, 对 多台服务器实现⾼效运维。 任务要求任务要求 通过管…...

关于HTTP HEAD介绍

一、HTTP HEAD介绍 HTTP HEAD 是一种 HTTP 请求方法&#xff0c;它用于请求服务器返回指定资源的元信息&#xff08;metadata&#xff09;&#xff0c;而不包括响应体的内容。这种请求方式常用于客户端预先评估资源的大小、最后修改日期或其他头信息&#xff0c;而无需实际下载…...

WPF Mvvm

了解MVVM 什么是MVVM&#xff1a;一种设计模式 设计模式&#xff08;Design pattern&#xff09;代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...