lwip单网卡多ip的实现

news2025/1/14 20:57:18

1、今天要实现lwip的多个ip配置,本来以为需要自己修改很多核心代码

2、查阅资料才发现,lwip已经把接口留出来了

/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type)
 * to a filter function that returns the correct netif when using multiple
 * netifs on one hardware interface where the netif's low-level receive
 * routine cannot decide for the correct netif (e.g. when mapping multiple
 * IP addresses to one hardware interface).
 */

/** 将此定义为1,并将LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type)定义为一个过滤函数,该函数在使用单个硬件接口上的多个netif时返回正确的netif。当netif的低级接收例程无法确定正确的netif时(例如,当将多个IP地址映射到单个硬件接口时),需要使用此过滤函数。
*/


#ifndef LWIP_ARP_FILTER_NETIF
#define LWIP_ARP_FILTER_NETIF 0
#endif

3、所以我们只需要定义好宏

        #define LWIP_ARP_FILTER_NETIF    1        //多ip的支持

和写好

struct netif * LWIP_ARP_FILTER_NETIF_FN(struct pbuf *p, struct netif *netifIn, u16_t type)

函数即可

4、我的操作

        4.1> 在lwipopt.h定义使能宏LWIP_ARP_FILTER_NETIF ,以支持多ip的操作

4.2、编写LWIP_ARP_FILTER_NETIF_FN函数,以能根据ip能找到对应的网卡

/*
*********************************************************************************************************
* Function Name : LWIP_ARP_FILTER_NETIF_FN
* Description   : 多ip,识别正确的网卡
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
#include  "lwip/prot/etharp.h"
struct netif * LWIP_ARP_FILTER_NETIF_FN(struct pbuf *p, struct netif *netifIn, u16_t type)
{
	struct netif *netif = NULL;
	struct etharp_hdr *hdr = NULL;
	struct ip_hdr *iphdr = NULL;
	ip_addr_t dest/*, src*/;
	switch (type)
	{
		/*ARP*/
	case	0x0806:
		hdr = (struct etharp_hdr *)((unsigned char*)p->payload + 14);
		memcpy(&dest, &(hdr->dipaddr), sizeof(ip4_addr_t));
		//memcpy(&src, &hdr->sipaddr, sizeof (ip4_addr_t));
		for (netif = netif_list; netif != NULL; netif = netif->next)
		{
			if (netif_is_up(netif))
			{
				if (ip4_addr_cmp(&dest,&(netif->ip_addr)))
				{
					break;
				}
			}
		}
		break;
		/*IP*/
	case	0x0800:
		iphdr = (struct ip_hdr *) ((unsigned char*)p->payload + 14);
		ip_addr_copy_from_ip4(dest, iphdr->dest);
		//ip_addr_copy_from_ip4(src, iphdr->src);
		for (netif = netif_list; netif != NULL; netif = netif->next)
		{
			if (netif_is_up(netif))
			{
				if (ip4_addr_cmp(&dest, &(netif->ip_addr)))
				{
					break;
				}
			}
		}
		break;

	default:
		netif = netif_list;
		break;
	}
	netifIn = netif;
    if(netif==NULL)
    {
        pbuf_free(p);
    }
	return netif;
    
}

根据ip去匹配netif,arp需要单独处理,因为ip通信首先都要发送arp去找物理地址,不加这个arp处理,会出现你ping不通ip。所以如果知道物理地址,不加这个arp处理也可以,直接自己填mac即可,加到你自己的静态arp表中。

大家注意:

这个一定要加上,我刚开始没加,结果刚开始通,运行一段时间导致不通了,就是因为这里没释放申请的内存,导致无法处理新的数据

4.3、增加多ip的设置

	//开始虚拟多ip--1
	IP4_ADDR(&ipaddr_v[1], 192,168,20,48);
	IP4_ADDR(&netmask_v[1], 255,255,255,0);
	IP4_ADDR(&gw_v[1], 192, 168, 20,1);
	netif_add(&g_netif_v[1], &ipaddr_v[1], &netmask_v[1], &gw_v[1], NULL, &ethernetif_init, &tcpip_input);	//网卡初始化和网卡输入
	netif_set_up(&g_netif_v[1]);

	//开始虚拟多ip--2
	IP4_ADDR(&ipaddr_v[2], 192,168,30,48);
	IP4_ADDR(&netmask_v[2], 255,255,255,0);
	IP4_ADDR(&gw_v[2], 192, 168, 30,1);
	netif_add(&g_netif_v[2], &ipaddr_v[2], &netmask_v[2], &gw_v[2], NULL, &ethernetif_init, &tcpip_input);	//网卡初始化和网卡输入
	netif_set_up(&g_netif_v[2]);

4.4、然后运行测试,OK

5、测试结果

刚开始测试结果是这样,我没在意,以为是硬件还是那里问题,ping移植有超时,或者卡顿较大

有时,还会出现几十上百ms的延迟,特别是多个电脑同时ping时。

6、ping超时,卡顿较大原因

1> 原来多个neif_add时:

会每次都初始化网卡,这里网卡在初始化时,会创建解析网络中断数据包的任务,所以存在多个任务去读网卡数据,造成数据的竞争,从而导致可能出现超时,卡顿较大

2> 我们只有一个网卡,所以只需初始化1次解析网络中断数据包的任务

改了之后就OK了

像下面这篇文章这样:

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

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

相关文章

《零基础Go语言算法实战》【题目 2-22】Go 调度器优先调度问题

《零基础Go语言算法实战》 【题目 2-22】Go 调度器优先调度问题 下面代码的输出是什么?请说明原因。 package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) wg : sync.WaitGroup{} wg.Add(10)…

浏览器输入http形式网址后自动跳转https解决方法

一、问题描述 使用浏览器 网上冲浪 时会遇到一个情况: 在浏览器中输入“http域名”后会自动变成“https 域名”的形式,此时“https 域名”的网站可能已停止对外提供服务了,这时会出现如下不友好的网页提示: 二、处理方法&#x…

【UE5 C++课程系列笔记】27——多线程基础——ControlFlow插件的基本使用

目录 步骤 一、搭建基本同步框架 二、添加委托 三、添加蓝图互动框架 四、修改为异步框架 完整代码 通过一个游戏初始化流程的示例来介绍“ControlFlows”的基本使用。 步骤 一、搭建基本同步框架 1. 勾选“ControlFlows”插件 2. 新建一个空白C类,这里…

WeakAuras NES Script(lua)

WeakAuras NES Script 修星脚本字符串 脚本1:NES !WA:2!TMZFWXX1zDxVAs4siiRKiBN4eV(sTRKZ5Z6opYbhQQSoPtsxr(K8ENSJtS50(J3D7wV3UBF7E6hgmKOXdjKsgAvZFaPTtte0mD60XdCmmecDMKruyykDcplAZiGPfWtSsag6myGuOuq89EVDV9wPvKeGBM7U99EFVVVV33VFFB8Z2TJ8azYMlZj7Ur3QDR(…

android进入fastboot

安装windows驱动。android进入fastboot模式后,需要Windows驱动来跟adb通信,所以需要预先安装Windows usb驱动,否则进入fastboot模式后,无法使用adb连接手机。 下载网址:https://developer.android.com/studio/run/win-…

LabVIEW光流跟踪算法

1. 光流跟踪算法的概述 光流(Optical Flow)是一种图像处理技术,用于估算图像中像素点的运动。通过比较连续帧图像,光流算法可以分析图像中的运动信息,广泛用于目标跟踪、运动检测和视频处理等场景。该示例使用了NI Vi…

系统看门狗配置--以ubuntu为例

linux系统配置看门狗 以 ubuntu 系统配置看门狗为例 配置看门狗使用的脚本文件,需要使用管理员权限来执行: 配置是:系统每 30S 喂一次狗,超过 60S 不进行投喂,就会自动重启。 1. 系统脚本内容: #!/bin/b…

Windows的Redis查看自己设置的密码并更改设置密码

查看密码 由于我的Redis安装很久了,所以忘记是否有设置密码,查看步骤如下: 启动redis,启动流程可以看这篇文章:https://blog.csdn.net/changyana/article/details/127679871 在redis安装目录下打开redis-cli.exe&…

E10.【C语言】练习:编写一个猜数字游戏

目录 1.规则 2.准备 3.游戏代码 1.规则 1.程序生成1-100间的随机数 2.用户猜数字 猜对了:游戏结束 猜错了:程序会告知猜大了或猜小了,继续进行游戏,直到猜对 3.游戏可以一直玩除非退出游戏 2.准备 1.框架:循…

《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》

哈喽,大家好!在平常开发过程中会遇到许多意想不到的坑,本篇文章就记录在开发过程中遇到一些常见的问题,看了许多博主的异步编程,我只能说一言难尽。本文详细的讲解了异步编程之美,是不可多得的好文&#xf…

kalilinux - msf和永恒之蓝漏洞

Kali最强渗透工具 - metasploit metasploit是什么? msf是一款开源安全漏洞利用和测试工具,集成了各种平台上常见的溢出漏洞和流行的sheelcode,并持续保持更新。 具体操作 1、先切换到root用户,使用msfdb init命令初始化metaspl…

【大模型入门指南 11】大模型自动评估理论和实战

【大模型入门指南】系列文章: 【大模型入门指南 01】深度学习入门【大模型入门指南 02】LLM大模型基础知识【大模型入门指南 03】提示词工程【大模型入门指南 04】Transformer结构【大模型入门指南 05】LLM技术选型【大模型入门指南 06】LLM数据预处理【大模型入门…

【SOC 芯片设计 DFT 学习专栏 -- DFT 接管 clock 和 reset】

文章目录 OverviewDFT 接管 Clock 和 Reset 的方法Clock 接管方法Reset 接管方法 什么场景下需要 DFT 来接管 Clock 和 Reset?制造测试(Manufacturing Test)静态路径扫描测试(Scan Testing)调试与故障定位(…

从 Conda 到 Pip-tools:Python 依赖管理全景探索20250113

从 Conda 到 Pip-tools:Python 依赖管理全景探索 引言 在 Python 开发中,依赖管理是一个"常见但复杂"的问题:一次简单的版本冲突可能让团队调试数小时;一次不受控的依赖升级可能让生产环境瘫痪。随着项目规模的增加和…

【数学】概率论与数理统计(五)

文章目录 [toc] 二维随机向量及其分布随机向量离散型随机向量的概率分布律性质示例问题解答 连续型随机向量的概率密度函数随机向量的分布函数性质连续型随机向量均匀分布 边缘分布边缘概率分布律边缘概率密度函数二维正态分布示例问题解答 边缘分布函数 二维随机向量及其分布 …

《自动驾驶与机器人中的SLAM技术》ch2:基础数学知识

目录 2.1 几何学 向量的内积和外积 旋转矩阵 旋转向量 四元数 李群和李代数 SO(3)上的 BCH 线性近似式 2.2 运动学 李群视角下的运动学 SO(3) t 上的运动学 线速度和加速度 扰动模型和雅可比矩阵 典型算例:对向量进行旋转 典型算例:旋转的复合 2.3 …

30_Redis哨兵模式

在Redis主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,同时数据安全性也得不到保障,因此主从模式的可用性…

苹果手机(IOS系统)出现安全延迟进行中如何关闭?

苹果手机(IOS系统)出现安全延迟进行中如何关闭? 一、设置二、隐私与安全性三、失窃设备保护关闭 一、设置 二、隐私与安全性 三、失窃设备保护关闭

【Oracle专栏】group by 和distinct 效率

Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 查阅资料: 1)有索引情况下,group by和distinct都能使用索引,效率相同。 2)无索引情况下,distinct…

linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包,文本处理sed,awk

关于文件的关键词 创建 touch 删除 rm 复制 cp 权限 chmod 移动 mv 查看内容 cat(全部); head(前10行); tail(末尾10行); more,less,grep 查找 find 压缩 gzip ; bzip 打包 tar 编辑 sed 文本处理 awk 创建文件 格式: touch 文件名 删除文件 复制文…