STM32 LwIP单网卡绑定多个IP地址

2023-05-16

STM32 LwIP单网卡绑定多个IP地址

芯片:STM32F107VC

编译器:KEIL4

作者:SY

日期:2018-6-28 11:02:53

概述

在只有一个物理网卡的情况下,可以通过软件虚拟多个 IP地址 ,分时通讯。

  • 协议栈: LwIP
  • 主芯片:STM32F107VC

实现

首先移植 LwIP ,保证单个 IP地址 时可用。

然后添加虚拟网卡:

void LwIP_Init(void)
{
    /* 添加网卡1 */
    IP4_ADDR(&ipaddr1, 192, 168, 0, 234);
    IP4_ADDR(&netmask1, 255, 255, 255, 0);
    IP4_ADDR(&gw1, 192, 168, 0, 1);
    netif_add(&netif1, &ipaddr1, &netmask1, &gw1, NULL, &ethernetif_init, &ethernet_input);
    netif_set_up(&netif1);
    netif_set_default(&netif1);

    /* 添加网卡2 */
    IP4_ADDR(&ipaddr2, 192, 168, 1, 234);
    IP4_ADDR(&netmask2, 255, 255, 255, 0);
    IP4_ADDR(&gw2, 192, 168, 1, 1);
    netif_add(&netif2, &ipaddr2, &netmask2, &gw2, NULL, &ethernetif_init, &ethernet_input);
    netif_set_up(&netif2);

    /* 新建UDP通信 */
    struct udp_pcb *UdpPcb;
    /* Create a new UDP control block  */
    UdpPcb = udp_new();  

    /* Bind the upcb to any IP address and the UDP_PORT port*/
    udp_bind(UdpPcb, IP_ADDR_ANY, UDP_CLIENT_PORT);

    /* Set a receive callback for the upcb */
    udp_recv(UdpPcb, udp_client_callback, NULL); 
}

这样处理之后,出现下面的问题:

  • 有些数据包会在网卡中逗留,在不确定的时间后,发出去
  • 数据包每次都发了两次
  • 第一张网卡的 IP地址 收不到数据,甚至于使用以太网调试助手向该 IP 发送数据都抓不到数据包。

根据以太网通信协议,局域网内数据收发,需要使用 MAC 地址通讯,因此首先需要发送 ARP 数据包,需要向目的 IP地址 发送协议包,请求对方的 MAC地址 。通过抓包工具查看,果然是这样,电脑端发送的 ARP 数据包,设备没有回复。

因此修改 ARP层

/*
*********************************************************************************************************
* Function Name : GetActiveNetif
* Description   : 获取当前活动的网卡
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
struct netif *GetActiveNetif(struct ip_addr *src_ip)
{
    struct netif *curNetif = NULL;
    if (ip_addr_cmp(src_ip, &netif1.ip_addr)) {
        curNetif = &netif1;
    } else if (ip_addr_cmp(src_ip, &netif2.ip_addr)) {
        curNetif = &netif2;
    }
    return curNetif;
}

通过解析数据包中的 源IP 字段,和当前 2 张网卡中的 源IP 字段进行比较,从而找到数据包是发送给哪一张网卡的。

void
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
    /* this interface is not configured? */
    if (netif->ip_addr.addr == 0) {
        for_us = 0;
    } else {
        /* ARP packet directed to us? */
        struct netif *GetActiveNetif(struct ip_addr *src_ip);
        struct netif *activeNetif = GetActiveNetif(&dipaddr);
        if (activeNetif != NULL) {
            for_us = 1;
            netif = activeNetif;
        }
    }

    /* ARP message directed to us? */
    if (for_us) {
        /* add IP address in ARP cache; assume requester wants to talk to us.
         * can result in directly sending the queued packets for this host. */
        update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);
        /* ARP message not directed to us? */
    } else {
        /* update the source IP address in the cache, if present */
        update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
    }
}

通过上述修改,上位机的数据包就可以收到了。

/**
 * In this function, the hardware should be initialized.
 * Called from ethernetif_init().
 *
 * @param netif the already initialized lwip network interface structure
 *        for this ethernetif
 */
static void
low_level_init(struct netif *netif)
{
    /* device capabilities */
      /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
      netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP;
}

根据上面提示,如果有多个网络,需要去掉 NETIF_FLAG_ETHARP 字段。

OK ,经过上述修改,两个 IP地址 都可以收到数据包。

总结

IP地址 需要配置为不同网段

参考 IP 路由规则:

/**
 * Finds the appropriate network interface for a given IP address. It
 * searches the list of network interfaces linearly. A match is found
 * if the masked IP address of the network interface equals the masked
 * IP address given to the function.
 *
 * @param dest the destination IP address for which to find the route
 * @return the netif on which to send to reach dest
 */
struct netif *
ip_route(struct ip_addr *dest)
{
  struct netif *netif;

  /* iterate through netifs */
  for(netif = netif_list; netif != NULL; netif = netif->next) {
    /* network mask matches? */
    if (netif_is_up(netif)) {
      if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
        /* return netif on which to forward IP packet */
        return netif;
      }
    }
  }
  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
    IP_STATS_INC(ip.rterr);
    snmp_inc_ipoutnoroutes();
    return NULL;
  }
  /* no matching netif found, use default netif */
  return netif_default;
}

如果两张网卡的 IP地址 在同一个网段,那么在遍历网卡时,会优先找到最后添加的网卡,也就是说,不管你往哪个网卡发送数据包,在设备回复数据时,都会从第二张网卡回复数据。

比如说:向 IP (192, 168, 0, 234) 发送数据包,收到数据回复时,源 IP地址 会变成 IP(192, 168, 1, 234)

如果想要两张网卡独立工作,都可以正常收发数据,需要将两张网卡的 IP地址 设置为不同的网段,同时电脑端需要和设备端设置在同一个网段!

比如:

主机1:

IP:     192.168.0.88
MASK:   255.255.255.0
GATEWAY:192.168.0.1 

设备1:

IP:     192.168.0.249
MASK:   255.255.255.0
GATEWAY:192.168.0.1 

这样,主机1 和 设备1 可以正常通讯。

主机2:

IP:     192.168.1.88
MASK:   255.255.255.0
GATEWAY:192.168.1.1 

设备2:

IP:     192.168.1.249
MASK:   255.255.255.0
GATEWAY:192.168.1.1 

这样,主机2 和 设备2 可以正常通讯。

如果交叉会怎么样呢?你会发现抓包工具会显示目标不可达,因为他们不再同一个子网内!

如果设备1和设备2在同一个子网内会怎么样呢?

主机:

IP:     192.168.0.88
MASK:   255.255.255.0
GATEWAY:192.168.0.1 

设备1:

IP:     192.168.0.249
MASK:   255.255.255.0
GATEWAY:192.168.0.1 

设备2:

IP:     192.168.0.248
MASK:   255.255.255.0
GATEWAY:192.168.0.1 

现象:

主机 –> 设备1:设备2 –> 主机

主机 –> 设备2:设备2 –>主机

因此,我们得出结论:

  • 只有在同一个子网内的主机和设备才可以正常收发数据
  • 如果两台设备在同一个子网内,主机只能和最后添加的网卡绑定的 IP地址 正常通讯。和最开始添加的网卡通讯时,由于 ip_rout 的关系,将使用最后绑定网卡的 IP地址 回复!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 LwIP单网卡绑定多个IP地址 的相关文章

  • 网监后台管理系统设计思路

    本次做的是网监系统saas服务平台的后台管理系统 xff0c 不涉及复杂功能逻辑 就是从菜单 模板 系 统 组织架构 角色 用户的设计思路 产品需求 xff1a 在各个省市网监系统的数量不断增长 xff0c 且系统逻辑和功能模块大致相同 x
  • 分类算法 c4.5 详解

    C4 5是一系列用在机器学习和数据挖掘的分类问题中的算法 它的目标是监督学习 xff1a 给定一个数据集 xff0c 其中的每一个元组都能用一组属性值来描述 xff0c 每一个元组属于一个互斥的类别中的某一类 C4 5的目标是通过学习 xf
  • 正则表达式匹配Html代码中图片路劲

    正则表达匹配图片路径 public static string GetHtmlImageUrlList string sHtmlText 定义正则表达式用来匹配 img 标签 Regex regImg 61 new Regex 64 34
  • (GPU版)Pytorch+pycharm+jupyter安装记录(截至23年3月14日)

    由于搞了一台旧主机 xff0c 主机上没有pytorch等软件程序 xff0c 所以重新装一遍 xff0c 顺便记录一下 xff01 一 安装显卡GPU的驱动程序 xff0c 搞定CUDA先 WIN 43 R打开命令行 xff0c 输入命令
  • Alibaba官方最新发布的这份Java学习导图+彩版手册,真不是吹的

    时间飞逝 xff0c 转眼间毕业七年多 xff0c 从事 Java 开发也六年了 我在想 xff0c 也是时候将自己的 Java 整理成一套体系 这一次的知识体系面试题涉及到 Java 知识部分 性能优化 微服务 并发编程 开源框架 分布式
  • linux下使用第三方商店安装应用

    安装 snap store 进行下载 xff0c 相当与第三方应用商店 xff0c 但是往往比某一个官方软件源里面的应用要丰富或更实用 到 snap docs 中选择你的 linux 版本进入安装文档 xff0c 根据指示一步一步安装即可
  • Centos7离线安装sqlserver2017

    Centos7离线安装sqlserver2017 根据操作系统版本选择下载匹配的sqlserver版本 可以在这里找一下https packages microsoft com config 我选择是先在一台有网的机器上下载好rpm安装包之
  • HC-05蓝牙模块配置

    目录 1 连接蓝牙模块a 蓝牙模块通过USB转TTL连接电脑b 打开串口助手 xff0c 波特率设置为38400c 检验是否连接成功 2 配置波特率3 修改密码4 设置主从模式5 设置蓝牙连接模式6 查询自身地址7 添加配对蓝牙地址8 测试
  • Windows沙盒技术调研

    转载自 xff1a 移动云开发者社区 一 Windows沙盒技术介绍 Windows沙盒提供了轻型桌面环境 xff0c 可安全地隔离运行应用程序 沙盒环境中Windows软件保持 34 沙盒 34 状态 xff0c 并独立于主机运行 沙盒是
  • OS + Linux Shell bash / sh / ksh / csh / tcsh / adb shell

    s Android adb shell ADB Android debug bridge Android手机实际是基于Linux系统的 Google提供的ADB工具包带有fastboot exe rar http dl iteye com
  • kali利用CVE_2019_0708(远程桌面代码执行漏洞)攻击win7

    一 漏洞说明 2019年5月15日微软发布安全补丁修复了CVE编号为CVE 2019 0708的Windows远程桌面服务 xff08 RDP xff09 远程代码执行漏洞 该漏洞在不需身份认证的情况下即可远程触发 危害与影响面极大 目前
  • 数据库系统原理1

    第一章 数据库管理技术发展的不同阶段形成不同的特点 数据描述经历了三个阶段对应于三个数据模型 第二章 数据库系统的生命周期 xff0c 书中可能和我们学习软工的时候有些出入 xff0c 其实就是不同时间有不同的理解 xff0c 横看成岭侧成
  • ssh详解

    SSH ssh secure shell protocol 22 tcp 安全的 具体的软件实现 xff1a OpenSSH ssh协议的开源实现 xff0c CentOS dropbear xff1a 另一个开源实现 SSH协议版本 v1
  • spring框架的简单配置步骤——小马同学@Tian

    spring框架配置步骤 1 导入jar包 本教程使用spring5 1 5 xff0c 在pom xml中进行导入依赖 Maven方式 xff1a span class token tag span class token tag spa
  • PSReadLine - Powershell 的强化工具

    PSReadLine Powershell 的强化工具 UPDATE 2022 3 4 根据其 Github README 的说明 xff0c If you are using Windows PowerShell on Windows 1
  • 美化 PowerShell

    美化 PowerShell UPDATE 2022 3 4 本文使用的 oh my posh 基于 V2 版本 xff0c 而更新且功能更强大的新版本已经发布 xff0c 如需使用请参考其官方文档 1 准备工作 Step1 下载并安装 Po
  • nltk下载语料库

    1 首先我们使用命令pip list查看是否安装了nltk模块 xff0c 如果没有 xff0c 则执行命令pip3 install nltk进行安装 2 之后 xff0c 我们在Jupyter Notebook中进行语料库的安装 impo
  • Spark scala和java的api使用

    Spark scala和java的api使用 1 利用scala语言开发spark的worcount程序 xff08 本地运行 xff09 package com zy spark import org apache spark rdd R
  • 解决Ubuntu18.04循环登录/卡在开机界面/无法进入图形界面的问题

    原因 xff1a NVIDIA显卡驱动损坏 解决方案 xff1a 重启进入命令行模式卸载原有NVIDIA驱动程序重新安装NVIDIA驱动后重启 xff0c 问题解决 Step1 Ubuntu系统开机进入命令行模式 系统启动后 xff0c 在
  • C++ 遍历注册表项下的所有键和值

    include 34 stdafx h 34 include lt time h gt include lt windows h gt include lt iostream gt include lt stdio h gt include

随机推荐

  • 9月10日美团网2014校招研发笔试哈尔滨站

    1 链表翻转 给出一个链表和一个数k xff0c 比如链表1 2 3 4 5 6 xff0c k 61 2 xff0c 则翻转后2 1 4 3 6 5 xff0c 若k 61 3 翻转后3 2 1 6 5 4 xff0c 若k 61 4 x
  • 2014校园招聘京东软件开发类笔试(完整版)

    时间 xff1a 2013 9 10 2013 10 8 地点 xff1a 四川大学 天津大学 职位 xff1a 软件开发工程师岗 语言 xff1a java 1 A 2 C 3 D 4 B 5 A 二 1 B 三1 D 2 B 3 C 4
  • Win8.1电脑声音可以外放但是插入耳机没有声音

    今天早上正准备学习英语 xff0c 发现耳机插入电脑没有声音 xff0c 于是开始找百度 xff0c 一步一步剥茧抽丝去查找问题来源 问题 xff1a 点击喇叭出现如下图片 xff1a 平常只有右半个图现在却有两个图标了 步骤 xff1a
  • 在线购物系统问题描述&领域词汇表

    在线购物问题描述 v2 0 时间 2017年 4月19日星期三 参与者在线客户能够通过网站完成在线购物 xff0c 顶层用况包括商品信息浏览 购物 咨询 用户注册 xff0c 用户登录 用户反馈 浏览商品用况可以用于客户寻找和浏览想要看的商
  • 在线购物领域类图

  • 在线购物系统用况分析

    一 系统用况图 1 用况图 2 xff08 1 xff09 用况图综述 系统主要是使顾客方便安全地购物 xff0c 已注册顾客可以通过系统查找 浏览 购买商品 xff0c 并且能够进行评价商品 与相应的商家沟通 或者向网站管理人员反馈问题
  • 被做成类似通信图的分析类图

    实验二博客 xff1a http blog csdn net simonruyang article details 70332294 一 注册 1 图形如下 2 文字说明 xff08 1 xff09 类图综述 目的 xff1a 让未注册顾
  • 顺序图实验记录,又懒又差劲,好懒好懒

    实验二博客 xff1a http blog csdn net simonruyang article details 70332294 一 注册 1 图形如下 2 文字说明 xff08 1 xff09 类图综述 目的 xff1a 让未注册顾
  • 承上的状态机图,又是烂图一副

    1 图形文档如下 2 文字说明 此状态机图反映了系统面向顾客从注册到购物完成的整体的状态变迁以及状态内部发生的事件 xff0c 一共有六个状态 xff0c 状态间转移如上图所示 2 1 ViewItems 中的事件 2 2 Register
  • 让Windows秒变Mac主题,还原度高达99%

    小伙伴们注意 xff1a 公众号的推送机制不再按照时间前后推送了 xff0c 微信公众号信息流乱序 君哥建议大家把科技毒瘤君公众号置顶 xff08 设为星标 xff09 xff0c 以便第一时间看到推送 xff0c 非常感谢 xff0c 方
  • 阿里Arthas(阿尔赛斯)-java诊断工具使用入门

    1 下载官方测试程序启动 doda 64 host166 game curl O https arthas aliyun com math game jar doda 64 host166 game java jar math game j
  • LHL 华为开发者大会有感 之 什么是HMS

    华为移动服务 同义词 HMS xff08 Huawei Mobile Services的英文缩写 xff09 一般指华为移动服务 华为移动服务 xff08 HMS xff09 全称为Huawei Mobile Services xff0c
  • EF Core之自动历史记录

    EF Core之自动历史记录 有的场景下需要记录特定表的增删改操作 xff0c 以便追溯 传统的做法是在增删改的方法里同步做记录 xff0c 很繁琐 在这里我们可以配合EF Core的DBContext做一个全局管控 全局管控自然就要有固定
  • SQL Server 2012 导出数据及分离MDF、LDF

    最近在设计数据库时看到自己设计的数据库和师哥师姐给我们的不一样 xff0c 于是就查了一下把数据库导出写了下来 分离数据库步骤 这是师哥师姐给我们的数据库格式 xff0c 如下 xff1a 那么如何生成MDF和LDF格式的数据库呢 xff1
  • kindeditor异步加载时无法显示编辑框

    事情是这样的 xff0c 我在A页面的div通过 jQuery load 方法载入一个页面B时 xff0c B页面带有编辑框 textarea xff0c 现在想让这个 textarea 显示为一个 kindeditor的富文本编辑区域 x
  • VR游戏设计之三大特性

    2016 年 9 月 23 24 日 xff0c 由 CSDN 和创新工场联合主办的 MDCC 2016 移动开发者大会 中国 xff08 Mobile Developer Conference China xff09 将在北京 国家会议中
  • 组合导航系列文章(十二):滤波器基本原理

    我觉得不错的地方 3 滤波器估计原理 组合导航中 xff0c 先验是imu解算的值 xff0c 观测是gps等传感器给出的值 xff0c 融合的目的是找到概率最大的那个值 上面介绍的三种方法都是对先验和观测的融合 xff0c 由于极大似然要
  • Android 未进行依赖管理导致的问题:IDE 报错 “Unresolved reference: registerForActivityResult“但是能正常编译运行

    前言 谷歌前段时间废弃了 startActicityForResult 取而代之的是 ActicityResultApi xff0c 作为一个紧跟谷歌步伐走的菜鸟开发者 xff0c 当然想着的是第一时间学习并替换项目中的相关代码 但是 xf
  • 基于DataBinding的基类(Activity、Fragment、Adapter)

    基于DataBinding的基类 xff08 Activity Fragment Adapter xff09 1 BaseBindActivity public abstract class BaseBindActivity lt DB e
  • STM32 LwIP单网卡绑定多个IP地址

    STM32 LwIP单网卡绑定多个IP地址 芯片 xff1a STM32F107VC 编译器 xff1a KEIL4 作者 xff1a SY 日期 xff1a 2018 6 28 11 02 53 概述 在只有一个物理网卡的情况下 xff0