lwIP更新记03:IPv6

news2024/11/27 6:14:15

从 lwIP-2.0.0 开始,lwIP 终于有可用的 IPv6 协议栈了!IPv6 支持 双栈(IPv4 和 IPv6 同时使用) 或 IPv4/IPv6 二选一 模式。

lwIP-1.4.1 版本也有 IPv6,但那是实验性质的(见…\lwip-1.4.1\src\core\ipv6目录下的README文件),并不能在实际项目中使用的。

ipv6目录下的README文件内容:

IPv6 support in lwIP is very experimental.
lwIP 对 IPv6 的支持是非常实验性质的.

在 2011 年 5 月,开发者Ivan Delamer编写了可以同时运行 IPv4 和 IPv6 的双栈版本,这也是 lwIP 的第一个可以工作的 IPv6 版本。现在我们在…\lwip-2.1.3\src\core\ipv6 目录下看到的文件,也是在这个时候成型的。但这个版本仍很初级,并需要大量测试。

所以 2012 年 12 月发布的 lwIP-1.4.1 正式版中并不包括 Ivan Delamer 编写的 IPv6 模块。

时间来到了 2016 年 8 月 3 日。这天,开发者goldsimon删除了 ipv6 目录下的 README 文件,并在提交日志中写下了 IPv6 再也不是实验性质的了 😃:

IPv6 is NOT experimental any more 😃

此时距离第一个可以工作的 IPv6 版本,已经过去了 5 年多,有关 IPv6 的修改提交多达 350+ 次。

改善 IPv4/v6 的地址处理

2011 年 5 月,lwIP-1.4.0 版本,IP 地址使用类型ip_addr_t表示。

#define IP_PCB \
  /* ip addresses in network byte order */ \
  ip_addr_t local_ip; \
  ip_addr_t remote_ip; \
   /* Socket options */  \
  u8_t so_options;      \
   /* Type Of Service */ \
  u8_t tos;              \
  /* Time To Live */     \
  u8_t ttl               \
  /* link layer address resolution hint */ \
  IP_PCB_ADDRHINT

2011 年 5 月 18,lwIP 终于有了第一个可以同时运行 IPv4 和 IPv6 的双栈版本。随之而来的是,ip.h 文件中宏 IP_PCB 的定义也发生了变化,变量 local_ipremote_ip 需要兼容 ipv6,所以 IP 地址使用了联合体表示:

#define IP_PCB \
  IP_PCB_ISIPV6 \
  /* ip addresses in network byte order */ \
  union { \					/*<--这里*/
    ip_addr_t ip4; \
    IP_PCB_IP6 \
  } local_ip; \
  union { \					/*<--这里*/
    ip_addr_t ip4; \
    IP_PCB_IP6 \
  } remote_ip; \
   /* Socket options */  \
  u8_t so_options;      \
   /* Type Of Service */ \
  u8_t tos;              \
  /* Time To Live */     \
  u8_t ttl               \
  /* link layer address resolution hint */ \
  IP_PCB_ADDRHINT

为了使代码更具可读性,也为了尽可能的合并 IPv4 和 IPv6 代码,2011 年 5 月 26 日,宏 IP_PCB 有了新的变化:

#define IP_PCB \
  IP_PCB_ISIPV6_MEMBER \
  /* ip addresses in network byte order */ \
  ipX_addr_t local_ip; \		/*<--这里*/
  ipX_addr_t remote_ip; \		/*<--这里*/
   /* Socket options */  \
  u8_t so_options;      \
   /* Type Of Service */ \
  u8_t tos;              \
  /* Time To Live */     \
  u8_t ttl               \
  /* link layer address resolution hint */ \
  IP_PCB_ADDRHINT

这次变化很小,只是定义了一个新的IP地址类型 ipX_addr_t,用来代替上个版本的联合体:

#if LWIP_IPV6
/* A union struct for both IP version's addresses. */
typedef union {
  ip_addr_t ip4;
  ip6_addr_t ip6;
} ipX_addr_t;

#else /* LWIP_IPV6 */
typedef ip_addr_t ipX_addr_t;

#endif /* LWIP_IPV6 */

不知道你们是如何看待新的类型 ipX_addr_t ,我第一次看到它,虽然我还不怎么明白这个类型的含义,就觉得它不应该出现在源码中。

新的类型 ipX_addr_t 与 lwIP 代码风格很不搭,也容易让人疑惑,大写的 X 到底代表什么意思。

两年后,2013 年 6 月。Simon Goldschmidt表示对目前的 IPv6,有一件事情仍然不满意,那就是 ipX_addr_t 的实现。有几点原因:

  1. 不够不清晰。虽然类型 ipX_addr_t 同时涵盖 IPv4 和 IPv6 地址,但是一旦独立于 PCB(ip_pcb)使用,仍无法分辨类型 ipX_addr_t 定义的变量是 IPv4 还是 IPv6 地址。

  2. 不易使用。引入 ipX_addr_t(或者是说联合体)是为了节省空间,但是 Simon Goldschmidt 深思之后,认为这不值得。能用 IPv6 的应用,不会计较以字节为单位的内存得失。应该把关注点放到如何更容易使用 IPv6 模块上。

  3. 编译出错。使能 IPv6 之后,下面的 smtp 示例代码无法编译:

    char* ipa = ip_ntoa(&pcb->local_ip);
    

最终,在 2015 年 3 月,为了代码整洁清晰,也为了应用程序的兼容性,Simon Goldschmidt 决定删除所有 ipX_addr_t

  • ip_addr_t 应为通用地址类型,对 API 可见。将 ipX_addr_t 重命名为 ip_addr_t
  • IPv4 地址类型从 ip_addr_t 重命名为 ip4_addr_t
  • IPv6 地址类型保持不变,仍为 ip6_addr_t
  • ip4_addr_tip6_addr_t 仅用于协议栈内部,或者调用与版本相关的函数时使用。

这是一项大工程,涉及的文件达到了 74 个,其中新类型 ip_addr_t 定义为:

#if LWIP_IPV4 && LWIP_IPV6
/**
 * @ingroup ipaddr
 * A union struct for both IP version's addresses.
 * ATTENTION: watch out for its size when adding IPv6 address scope!
 */
typedef struct ip_addr {
  union {
    ip6_addr_t ip6;
    ip4_addr_t ip4;
  } u_addr;
  /** @ref lwip_ip_addr_type */
  u8_t type;
} ip_addr_t;

#else /* LWIP_IPV4 && LWIP_IPV6 */

#if LWIP_IPV4
typedef ip4_addr_t ip_addr_t;

#else /* LWIP_IPV4 */
typedef ip6_addr_t ip_addr_t;
#endif /* LWIP_IPV4 */
#endif /* LWIP_IPV4 && LWIP_IPV6 */

在升级到 lwIP-2.0.0 以及后续版本后,IP 地址的定义需要修改以适应新的版本。
对于 lwIP-1.4.1 以及更老版本,定义 IP 地址方式如下:

struct ip_addr app_ip;

而对于 lwIP-2.0.0 以及后续版本,定义 IP 地址要改成:

ip_addr_t app_ip;

此外,如果你从 lwIP-1.4.1 以及更老版本升级到 lwIP-2.0.0 以及后续版本,在编译时通常会遇到以下错误:

../main/source/upgrade_udp.c(37): error: incomplete definition of type 'struct ip_addr'

这是因为应用程序还在使用旧的 IP 地址定义方式,将 struct ip_addr 改为 ip_addr_t 即可解决。






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

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

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

相关文章

linux专题:嵌入式linux系统启动流程基础分析

目录 第一&#xff1a;linux内核源码基本简介 第二&#xff1a;uboot启动分析 第三&#xff1a;内核源码分析 第一&#xff1a;linux内核源码基本简介 下载 Linux 内核网址&#xff1a; https://www.kernel.org/ 最新 Linux 内核是 5.15 版本。现在常用 Linux 内核源码为4…

八大排序-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序、基数排序

目录 前言 直接插入排序&#xff08;Insertion Sort&#xff09; 一、概念及其介绍 二、过程图示 三、代码 四、复杂度 希尔排序&#xff08;Shell Sort&#xff09; 一、概念 二、实现思路 三、图示过程 四、代码 4.1代码 4.2运行结果 4.3解释 五、复杂度 堆排…

路径规划算法:基于蝙蝠算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于蝙蝠的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于蝙蝠的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法蝙蝠算法来进…

Swift 如何闪电般异步读取大文件?

功能需求 Apple 系统中&#xff08;iOS、MacOS、WatchOS等等&#xff09;读取文件是一个平常的不能再平常的需求&#xff0c;不过当文件很大时&#xff0c;同步读取文件会导致 UI 的挂起&#xff0c;这是不能让用户接受的。 所以&#xff0c;要想读取文件内容的同时保持界面操…

KMP算法及其改进图文详解

文章目录 KMP算法详解什么是KMP算法KMP算法的应用场景KMP算法和暴力求解的比较字符串的前缀、后缀和最长相等前后缀KMP算法实现字符串匹配的具体过程&#xff08;图解&#xff09;从串与主串的下标变化j回退的位置(从串的下标变化)主串的下标变化 Next数组如何运用代码逻辑计算…

[CTF/网络安全] 攻防世界 xff_referer 解题详析

[CTF/网络安全] 攻防世界 xff_referer 解题详析 XFF及refererXFF格式referer格式姿势总结 题目描述&#xff1a;X老师告诉小宁其实xff和referer是可以伪造的。 XFF及referer X-Forwarded-For&#xff08;简称 XFF&#xff09;是一个 HTTP 请求头部字段&#xff0c;它用于表示 …

深入理解计算机系统第七章知识点总结

文章目录 详解ELF文件-> main.o前十六个字节的含义推测elf的大小查看节头部表推断每个section在elf中的具体位置查看.text的内容查看.data的内容关于.bss查看.rodata的内容关于其他的节表示的信息 详解符号表符号编译器如何解析多重定义的全局符号静态库与静态链接构造和使用…

seata的部署和集成

seata的部署和集成 一、部署Seata的tc-server 1.下载 首先我们要下载seata-server包&#xff0c;地址在http://seata.io/zh-cn/blog/download.html 2.解压 在非中文目录解压缩这个zip包&#xff0c;其目录结构如下&#xff1a; 3.修改配置 修改conf目录下的registry.conf文…

开源大模型资料总结

基本只关注开源大模型资料&#xff0c;非开源就不关注了&#xff0c;意义也不大。 基座大模型&#xff1a; LLaMA&#xff1a;7/13/33/65B&#xff0c;1.4T token LLaMA及其子孙模型概述 - 知乎 GLM&#xff1a;6/130B&#xff0c; ChatGLM基座&#xff1a;GLM&#xff08…

【网络】- TCP/IP四层(五层)协议 - 网际层(网络层) - 网际协议IP

目录 一、概述 二、初步了解网际协议 IP  &#x1f449;2.1 与数据链路层的区别  &#x1f449;2.2 网际协议 IP 概览  &#x1f449;2.3 分层的意义 三、IP协议基础知识  &#x1f449;3.1 IP地址属于网络层地址  &#x1f449;3.2 路由控制  &#x1f449;3.3 IP分包与…

solr快速上手:核心概念及solr-admin界面介绍(二)

0. 引言 上一节&#xff0c;我们简单介绍了solr并演示了单节点solr的安装流程&#xff0c;本章&#xff0c;我们继续讲解solr的核心概念 solr快速上手&#xff1a;solr简介及安装&#xff08;一&#xff09; 1. 核心概念 核心&#xff08;索引/表&#xff09; 在es中有索引…

【软件测试】5年测试老鸟总结,自动化测试成功实施,你应该知道的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 自动化测试 Pytho…

基于html+css的图展示82

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

chatgpt赋能Python-pythonage

Pythonage - 一款优秀的Python SEO工具 无论是个人博客还是商业网站&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;都是最重要的。Pythonage是一款优秀的Python SEO工具&#xff0c;可以帮助你优化你的网站并提高搜索引擎排名。在这篇文章中&#xff0c;我们将详细介绍…

ChatGPT 使用 拓展资料:开始构建你的优质Prompt

ChatGPT 使用 拓展资料:开始构建你的优质Prompt

【JavaEE】阻塞队列、定时器和线程池

目录 1、阻塞队列 1.1、概念 1.2、生产者消费者模型 1.3、阻塞队列的模拟实现 2、定时器 2.1、使用标准库中的定时器 2.2、模拟实现定时器 3、线程池 3.1、标准库中的线程池 3.1.1、ThreadPoolExecutor类的构造方法 3.1.2、Java标准库的4种拒绝策略【经典面试题】…

Canal内存队列的设计

1、背景 笔者的公司内部使用了开源的Canal数据库中间件来接受binlog数据&#xff0c;并基于此进行数据的订阅和同步到各种同构和异构的数据源上&#xff0c;本文将对Canal内部使用的store模块进行分析。 2、Store模块概览 Canal的store模块用于存储binlog中的每一个event&am…

MySQL- 多表查询(上)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️树高千尺&#xff0c;落叶归根人生不易&…

安卓基础巩固(一):布局、组件、动画、Activity、Fragment

文章目录 布局LinearLayoutRelativeLayoutTableLayoutFrameLayoutConstraintLayoutListView基于ArrayAdapter自定义Adaper提升ListView的运行效率 RecyclerView基本属性使用案例布局&#xff08;显示方式&#xff09;监听事件利用View.onClickListener 和 onLongClickListener …

日志收集机制和日志处理流程规范

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/130792958 一、日志收集与处理流程 云原生平台中对日志提取收集以及分析处理的流程与传统日志处理模式大致是一样的&#xff0c;包括收集、ETL、索引、存储、检索、关联、可视化、分析、报告这9个步骤…