dpdk发送udp报文
dpdk接收到udp报文后,自己构造一个udp报文,将收到的报文中的源mac,目的mac,源ip,目的ip,源端口和目的端口交换下顺序填充到新的udp报文中,报文中的负载数据和收到的udp保持一致。
注:需要在udp发送端设置静态arp信息(dpdk绑定网卡的ip和mac地址映射),目前该程序还未对arp报文做处理
udp报文格式:
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#include <stdio.h>
#include <arpa/inet.h>#define NUM_MBUFS (4096-1) // 内存池中 mbuf 的数量
#define BURST_SIZE 32static uint32_t gSrcIp, gDstIp;
static uint8_t gSrcMac[RTE_ETHER_ADDR_LEN], gDstMac[RTE_ETHER_ADDR_LEN];
static uint16_t gSrcPort, gDstPort;int gDpdkPortId = 0;static const struct rte_eth_conf port_conf_default = {.rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN}
};static void ng_init_port(struct rte_mempool *mbuf_pool) {//dpdk绑定的网卡数量uint16_t nb_sys_ports = rte_eth_dev_count_avail();if (nb_sys_ports == 0) {rte_exit(EXIT_FAILURE, "not support eth\n");}struct rte_eth_dev_info dev_info;/*获取以太网设备的配置和状态信息。它通常用于初始化网络设备、*配置网络设备或者获取网络设备的状态信息。*这里的端口号和网卡是一一对应的*/rte_eth_dev_info_get(gDpdkPortId, &dev_info);const int num_rx_queues = 1; //接收队列个数const int num_tx_queues = 1; //发送队列个数struct rte_eth_conf port_conf = port_conf_default;rte_eth_dev_configure(gDpdkPortId, num_rx_queues, num_tx_queues, &port_conf);// 0是0号接收队列// 128是队列长度if (rte_eth_rx_queue_setup(gDpdkPortId, 0, 128, rte_eth_dev_socket_id(gDpdkPortId), NULL, mbuf_pool) < 0) {rte_exit(EXIT_FAILURE, "Could not setup RX queue\n");}struct rte_eth_txconf txq_conf = dev_info.default_txconf;//offloads 成员是一个 64 位无符号整数,每个比特位表示不同的接收功能选项txq_conf.offloads = port_conf.rxmode.offloads;/* 0是0号发送队列 * 1024是队列长度* 发送队列长度设置太小运行时会报错:Invalid value for nb_tx_desc(=128), should be: <= 4096, >= 512, and a product of 1*/if (rte_eth_tx_queue_setup(gDpdkPortId, 0, 1024, rte_eth_dev_socket_id(gDpdkPortId), &txq_conf) < 0) {rte_exit(EXIT_FAILURE, "Could not setup TX queue\n");}if (rte_eth_dev_start(gDpdkPortId) < 0) {rte_exit(EXIT_FAILURE, "Could not start\n");}}static void ng_encode_udp_pkt(uint8_t *msg, unsigned char *data, uint16_t total_len) {//设置以太网头struct rte_ether_hdr *eth = (struct rte_ether_hdr *)msg;rte_memcpy(eth->s_addr.addr_bytes, gSrcMac, RTE_ETHER_ADDR_LEN);rte_memcpy(eth->d_addr.addr_bytes, gDstMac, RTE_ETHER_ADDR_LEN);eth->ether_type = htons(RTE_ETHER_TYPE_IPV4);//设置ipv4头struct rte_ipv4_hdr *ip = (struct rte_ipv4_hdr *)(eth + 1);ip->version_ihl = 0x45;ip->type_of_service = 0;ip->total_length = htons(total_len - sizeof(struct rte_ether_hdr));ip->packet_id = 0;ip->fragment_offset = 0;ip->time_to_live = 64;//dpdk中没有UDP类型的定义,使用内核的协议类型ip->next_proto_id = IPPROTO_UDP;ip->src_addr = gSrcIp;ip->dst_addr = gDstIp;//计算ip头部校验和时,先把该字段置为0(ip校验和只包括头部)ip->hdr_checksum = 0;ip->hdr_checksum = rte_ipv4_cksum(ip);//设置udp头struct rte_udp_hdr *udp = (struct rte_udp_hdr *)(ip + 1);udp->src_port = gSrcPort;udp->dst_port = gDstPort;uint16_t udp_len = total_len - sizeof(struct rte_ether_hdr) - sizeof(struct rte_ipv4_hdr);udp->dgram_len = htons(udp_len);memcpy((uint8_t *)(udp + 1), data, udp_len - sizeof(struct rte_udp_hdr));//计算udp校验和,udp校验位包括负载数据udp->dgram_cksum = 0;udp->dgram_cksum = rte_ipv4_udptcp_cksum(ip, udp);
}static struct rte_mbuf *ng_send(struct rte_mempool *mbuf_pool, unsigned char *data, uint16_t length) {const unsigned total_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + length;//从内存中申请一个mbufstruct rte_mbuf *mbuf = rte_pktmbuf_alloc(mbuf_pool);if (mbuf == NULL) {rte_exit(EXIT_FAILURE, "rte_pktmbuf_alloc\n");}mbuf->pkt_len = total_len;mbuf->data_len = total_len;//用于将数据包缓冲区(packet buffer)转换为指定类型的数据指针,也就是mbuf存储数据包的首地址uint8_t *pktdata = rte_pktmbuf_mtod(mbuf, uint8_t*);ng_encode_udp_pkt(pktdata, data, total_len);return mbuf;
}int main(int argc, char *argv[]) {/*dpdk初始化资源*用于初始化 Environment Abstraction Layer (EAL)。EAL 是 DPDK 的一个核心组件,*负责抽象和管理硬件和操作系统依赖性,使得上层应用可以在不同的硬件和操作系统上*以统一的方式运行。*/if (rte_eal_init(argc, argv) < 0) {rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");}//内存池,接收的数据存在该内存池中struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NUM_MBUFS,0, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());if (mbuf_pool == NULL) {rte_exit(EXIT_FAILURE, "Could not create mbuf pool\n");}ng_init_port(mbuf_pool);//获取dpdk绑定的网卡源macrte_eth_macaddr_get(gDpdkPortId, (struct rte_ether_addr *)gSrcMac);while(1) {struct rte_mbuf *mbufs[BURST_SIZE] = {0};unsigned num_recvd = rte_eth_rx_burst(gDpdkPortId, 0, mbufs, BURST_SIZE);if (num_recvd > BURST_SIZE) {rte_exit(EXIT_FAILURE, "Error receive from eth\n");}unsigned int i = 0;for (i = 0; i < num_recvd; i++) {struct rte_ether_hdr *ehdr = rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr*);if (ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {rte_pktmbuf_free(mbufs[i]);continue;}struct rte_ipv4_hdr *iphdr = rte_pktmbuf_mtod_offset(mbufs[i], struct rte_ipv4_hdr*, sizeof(struct rte_ether_hdr));if (iphdr->next_proto_id == IPPROTO_UDP) {struct rte_udp_hdr *udphdr = (struct rte_udp_hdr *)(iphdr + 1);//两个字节以上的变量是需要大小端转换uint16_t length = ntohs(udphdr->dgram_len);*((char*)udphdr + length) = '\0';struct in_addr addr;addr.s_addr = iphdr->src_addr;printf("src: %s:%d, ", inet_ntoa(addr), ntohs(udphdr->src_port));addr.s_addr = iphdr->dst_addr;printf("dst: %s:%d, %s\n", inet_ntoa(addr), ntohs(udphdr->dst_port), (char *)(udphdr+1));//构造发送数据包rte_memcpy(gDstMac, ehdr->s_addr.addr_bytes, RTE_ETHER_ADDR_LEN);gSrcIp = iphdr->dst_addr;gDstIp = iphdr->src_addr;gSrcPort = udphdr->dst_port;gDstPort = udphdr->src_port;struct rte_mbuf *txbuf = ng_send(mbuf_pool, (unsigned char *)(udphdr+1), length);//发送报文rte_eth_tx_burst(gDpdkPortId, 0, &txbuf, 1);rte_pktmbuf_free(txbuf);}rte_pktmbuf_free(mbufs[i]);}}return 0;
}
相关文章:

dpdk发送udp报文
dpdk接收到udp报文后,自己构造一个udp报文,将收到的报文中的源mac,目的mac,源ip,目的ip,源端口和目的端口交换下顺序填充到新的udp报文中,报文中的负载数据和收到的udp保持一致。 注࿱…...

网站后端管理和构建java项目的工具-Maven
maven是用于管理和构建java项目的工具。 管理Jar包 无论是使用eclipse、IDEA创建的maven项目,格式都是统一的。 不同开发工具创建的maven项目兼容。 test是对main测试的代码。main中的resources中放置配置文件。 对于Maven,一个Maven项目就是一个对象…...

深入理解计算机系统 CSAPP 家庭作业11.10
A: //home.html <form action"/cgi-bin/adder" method"GET"><ul><li><label for"n1">n1:</label><input type"text" id"n1" name"n1" /> //name的值决定页面提交后…...

Unity3D 二进制序列化器详解
前言 在Unity3D开发中,二进制序列化是一种重要的数据持久化和网络传输技术。通过二进制序列化,游戏对象或数据结构可以被转换成二进制格式,进而高效地存储于文件中或通过网络传输。本文将详细介绍Unity3D中的二进制序列化技术,包…...

js_拳皇(上)
文章目录 架构设计:一图胜千言绪论不能正常加载动图设计的思路渲染画布开发感想角色抽象为矩形ctx 是 canvas 的对象键盘控制角色Set键盘事件流程图在 canvas 里面使用 gif 图片继承存储动作ReferenceError: gif is not definedTypeError: Cannot read properties o…...

TCP请求如何获取客户端真实源IP地址
应用场景 在基于TCP的应用程序中,获取客户端真实源IP地址可以用于以下应用场景: 访问控制和安全策略:通过获取客户端真实源IP地址,应用程序可以实施访问控制策略,限制或允许特定IP地址的访问。这可以用于身份验证、防…...

【b站-湖科大教书匠】6 应用层 - 计算机网络微课堂
课程地址:【计算机网络微课堂(有字幕无背景音乐版)】 https://www.bilibili.com/video/BV1c4411d7jb/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 6 应用层 6.1 应用层概述 6.2 客户-服务器方式和对等方…...

QT串口和数据库通信
创建串口 串口连接客户端并向服务器发送消息 client.pro #------------------------------------------------- # # Project created by QtCreator 2024-07-02T14:11:20 # #-------------------------------------------------QT core gui network QT core gui…...

WebKitWebKit简介及工作流程
简介 引擎能够解析HTML、CSS、JavaScript等网页标准,从而将互联网内容呈现给用户。 WebKit的主要特点包括: 开源性:它是一个开源项目,任何人都可以查看、修改和贡献代码。跨平台:WebKit可以在多个操作系统上运行&am…...

架构分析(CPU:ARM vs RISC-V)
ARM N2 ARM V2 对比 N2和V2,整体架构具有一致性。保证 SiFive P870 P870 Pipeline Veyron V1...

使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录
前言 RabbitMQ 是一个功能强大的开源消息队列系统,它实现了高效的消息通信和异步处理。 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验。 特点 成熟,稳定消息持久化灵活的消息路由高性能,高可用性,可扩展性高支…...

前端八股速通(持续更新中...)
1、深拷贝和浅拷贝的区别 浅拷贝:浅拷贝是拷贝一层,引用类型共享地址。 如果属性是基本类型,拷贝的就是基本类型的值。 如果属性是引用类型,拷贝的就是内存地址。 意思是,当进行浅拷贝时,对于对象的每一…...

【语音识别和生成】语音识别和语音合成技术
语音识别和生成:语音识别和语音合成技术 目录 引言语音识别技术 语音识别的基本原理语音识别系统的组成语音识别的关键技术 语音合成技术 语音合成的基本原理语音合成系统的组成语音合成的关键技术 语音识别和生成的应用 智能助理智能家居语音翻译医疗健康教育和学…...

Redis#架构师面试题
1、Redis锁存在哪些问题及如何解决? 1、死锁问题 加过期时间设定 2、原子性问题 通过“set…nx...ex…”命令,将加锁、过期命令编排到一起,它们是原子操作了,可以避免死锁。 3、释放其他线程的锁问题 当过期时间设置小于线程…...

关于#define的使用方法总结
文章目录 #define 预处理指令一、#define宏定义二、查看预处理文件三、#define 的使用方法四、C语言宏中“#”和“##”的用法五、常见的宏定义总结六、常考题目 #define 预处理指令 #define 是 C 和 C 编程语言中的预处理指令,用于定义宏(macro…...

Unity顶点动画(Vertex Animation):创造动态视觉效果
在Unity中,顶点动画(Vertex Animation)是一种强大的技术,它允许开发者直接在顶点级别上操作和变形网格,从而实现各种动态视觉效果。顶点动画不依赖于骨骼绑定,因此非常适合模拟布料、流体、面部表情等复杂的动画效果。本文将探讨顶…...

WSL for Windows
1、安装 超详细Windows10/Windows11 子系统(WSL2)安装Ubuntu20.04(带桌面环境)_wsl安装ubuntu20.04-CSDN博客https://blog.csdn.net/weixin_44301630/article/details/122390018 注意,安装之后首次启动 Ubuntu 时&…...

Matlab freqz 代码简单实现
相关代码打开matlab源码也可以看到,这里做了简单实现,与源码并不完全一样。 实现代码 [h2 w2] freqzfir(data); [h1 w1] freqz(data); h2h2; h12 [h1, h2];[h4 w4] freqziir(b,a, 2001,true); [h3 w3] freqz(b,a, w4, whole); h4 h4; h34 h…...

待办app哪款好?高效待办软件推荐
在快节奏的现代生活中,一款高效的待办事项管理软件对于提升工作效率和个人时间管理至关重要。面对市场上众多的待办app,哪款才是你的最佳选择呢?经过深入体验和对比,我发现敬业签这款高效待办软件是个不错的选择。 敬业签的快速记…...

【OSCP系列】OSCP靶机-BTRsys-2.1(原创)
OSCP系列靶机—BTRsys-2.1 原文转载已经过授权 原文链接:Lusen的小窝 - 学无止尽,不进则退 (lusensec.github.io) 一、主机发现 二、端口扫描 1、快速扫描 2、全端口扫描 3、服务系统探测 4、漏洞探测 80端口扫到了一些目录,有wordpress框…...

攻坚克难岁月长,自主腾飞世界强——回顾近代中国数据库的发展与飞跃
前言 最近看了《中国数据库前世今生》纪录片,感触颇深,也是一直在思考到底该用何种方式起笔来回顾这段筚路蓝缕却又充满民族自豪感的历程。大概构思了一周左右吧,我想,或许还是应该从那个计算机技术在国内刚刚萌芽的年代开始讲起…...

WEB前端12-axios基础
Vue2-axios基础 1.axios基本概念 在现代的前端开发中,处理网络请求是至关重要的一部分。Axios 是一个流行的基于 Promise 的 HTTP 客户端,它可以在浏览器和 Node.js 环境中使用。它的设计简单易用,支持并行请求、拦截器、CSRF 防护等特性&a…...

Ubuntu 防火墙设置
目录 1. 安装防火墙 2. 开启和关闭防火墙 3. 开放端口和服务规则 4. 关闭端口和删除服务规则 5. 查看防火墙状态 1. 安装防火墙 如果已经安装就忽略 # 安装ufw(Uncomplicated Firewall),这是Ubuntu上管理防火墙的一个简单工具 sudo ap…...

JL 跳转指令的理解
一般情况下,JU 和 JC 是最常见的跳转指令;但有时会用到JL 指令,JL 说起来更像是一组指令,类似C,C# 语言中的 switch case 语句,但是有个明显的不同,前者的判断条件可以是任意合理数字,后者范围…...

vue大屏展示组件库datav
主要用于构建大屏数据展示页面,具有多种类型组件可供使用。详情参考 datav官网 一、安装 npm 安装 npm install jiaminghi/data-viewyarn安装 yarn add jiaminghi/data-view二、使用 在main.js中注册为全局组件 import dataV from jiaminghi/data-view Vue.us…...

Vue.js 与 Ajax(vue-resource)的集成应用
Vue.js 与 Ajax(vue-resource)的集成应用 Vue.js 是一款流行的前端JavaScript框架,以其简洁、灵活和高效的特点而受到开发者的喜爱。在实际开发中,与后端服务的通信是不可或缺的,而Ajax技术是实现这一功能的关键。在V…...

【讲解下AI Native应用中的模型微调】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】
请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权,请联系删除 转自: 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …...

深度学习:如何计算感受野
感受野(Receptive Field)是卷积神经网络(CNN)中的一个重要概念,用于描述输入图像中的一个像素在输出特征图中影响的区域大小。在设计和理解卷积神经网络时,计算感受野有助于理解网络如何对输入数据进行处理…...

【状语从句】
框架 概念,特点主将从现连接词时间条件地点结果方式让步原因目的比较省略倒装 解读 1【概念,特点】 一个完整的句子,去修饰另一个完整句子中的动词,称为状语从句;特点:从句完整,只用考虑连接词是…...