全部例程

使用DHCP获取动态IPv6地址

W6300

更新于 2026年10月15日

本篇总结

在 W6300 上实现 DHCPv6 客户端,通过 DAD(重复地址检测)生成 Link-local 地址,再向 DHCPv6 服务器申请 Global 地址与 DNS。

🔑 MH2457 + QSPI、UART 调试、硬件 TOE 引擎、DHCPv6、IPv6、DAD

硬件平台:本例程基于 W6300-EVB-M4 开发板运行。

采购推荐:点击前往 WIZnet 官方淘宝店铺 选购 W6300-EVB-M4 开发板

本示例演示如何在 W6300 上通过 DHCPv6 协议获取动态 IPv6 地址。W6300 原生支持 IPv4/IPv6 双协议栈,本例程先通过 DAD 生成 Link-local 地址,再向路由器(DHCPv6 服务器)申请 Global 地址、网关和 DNS。

前置工具准备

开始本例程前,请确认以下工具已安装:

DHCPv6 协议简介

DHCPv6(Dynamic Host Configuration Protocol for IPv6)是 IPv6 网络中用于自动分配地址和配置信息的协议。与 IPv4 的 DHCP 类似,DHCPv6 允许设备从服务器动态获取 IPv6 地址、DNS 服务器地址、网关等信息,无需手动配置。DHCPv6 使用 UDP 协议,客户端通过 546 端口、服务器通过 547 端口通信。

IPv6 地址获取通常分两步:

  • Link-local 地址:设备根据 MAC 地址自动生成 Link-local 地址(FE80::/10 前缀),并通过 DAD(重复地址检测)确认该地址在链路上唯一。
  • Global 地址:设备通过 DHCPv6 向服务器申请全局可路由地址(GUA),以及 DNS、网关等信息。

DAD 重复地址检测

DAD(Duplicate Address Detection)是 IPv6 中确认地址唯一性的机制。设备生成 Link-local 地址后,会发送邻居请求(NS)报文,若没有其他设备响应,则说明该地址可用。本例程中 DAD 由 W6300 硬件协议栈自动完成,串口会打印 DAD 检测结果。


硬件连接与拓扑

请注意:

测试需要 PC 端和 W6300 处于同一网段,且路由器需支持并开启 DHCPv6 服务。部分路由器默认只开启 IPv4 DHCP,需在路由器管理界面中确认 IPv6 / DHCPv6 已启用。

  1. Micro USB 线连接 DEBUG USB 口到 PC(供电 + 调试串口)
  2. 网线连接开发板 RJ45 网口 到路由器 LAN 口
┌─────────────────────────────────┐
│ 路由器(DHCPv6 Server) │
│ 192.168.1.1 │
└────┬──────────────────┬───────────┘
│ │
┌────┴──────┐ ┌────┴──────┐
│ W6300 │ │ PC │
│ DHCPv6 Clt│ │ IPv6 │
│ LLA + GUA │ │ │
└────┬──────┘ └───────────┘
│ QSPI ↑
┌────┴──────┐ DEBUG USB
│ MH2457 │─────────→ WIZ UartTool
│ MCU │
└───────────┘
网络拓扑:MH2457 通过 QSPI 驱动 W6300,W6300 作为 DHCPv6 客户端向路由器申请 IPv6 地址

工程结构

工程核心文件如下:

DHCPv6/
├── main.c                    ← 系统入口:串口、GPIO、QSPI 初始化 + user_run()
└── USER/
    ├── user_main.c           ← MAC 定义 + do_dhcpv6() 调用
    ├── do_dhcpv6.c/h         ← DHCPv6 客户端流程封装
    ├── ipv6_common.c/h       ← IPv6 地址准备与打印
    ├── wiz_platform.c/h      ← 平台适配:debug_usart_init、wizchip_gpio_init、hspi_init
    └── wiz_interface.c/h     ← W6300 驱动接口:wizchip_initialize、network_init、PHY 检测、软件定时器

步骤1:准备 IPv6 网络参数并执行 DAD

文件:USER/do_dhcpv6.c — ipv6_prepare_network() 根据 MAC 生成 Link-local 地址,Duplicate_Address_Detection() 执行 DAD 确认地址唯一后写入网络信息。

static int dhcpv6_prepare_link_local(wiz_NetInfo *net_info)
{
    if (Duplicate_Address_Detection(net_info) != SUCCESS)
    {
        return -1;
    }

    wizchip_setnetinfo(net_info);
    return 0;
}

if (ipv6_prepare_network(&net_info, mac, NETINFO_DHCP_V6, NETINFO_DHCP) < 0)
{
    printf("DHCPv6 fail!\r\n");
    return -1;
}

if (dhcpv6_prepare_link_local(&net_info) < 0)
{
    printf("DHCPv6 fail!\r\n");
    return -1;
}

Link-local 地址以 FE80::/10 为前缀,后 64 位由 MAC 地址转换而来。DAD 检测通过后,W6300 就拥有了一个链路内可用的 IPv6 地址。

步骤2:启动 DHCPv6 客户端获取 Global 地址

文件:USER/do_dhcpv6.c — 注册 1 秒软件定时器,初始化 DHCPv6 客户端并进入主循环轮询。收到 DHCP6_IP_LEASED 且 Global 地址非零时,写入网络信息并打印。

memset(s_dhcpv6_buffer, 0, sizeof(s_dhcpv6_buffer));
wiz_add_timer(DHCP6_time_handler, 1000U);
DHCP6_init(DHCPV6_SOCKET, s_dhcpv6_buffer);
printf("DHCPv6 running\r\n");

while (1)
{
    result = DHCP6_run(&net_info);

    if (result == DHCP6_IP_LEASED)
    {
        if (!ipv6_address_is_zero(net_info.gua))
        {
            wizchip_setnetinfo(&net_info);
            status = 0;
        }
        break;
    }

    if ((result == DHCP6_FAILED) || (result == DHCP6_STOPPED))
    {
        break;
    }
}

DHCP6_stop();
wiz_delete_timer(DHCP6_time_handler);

软件定时器

W6300 的 DHCPv6 时基通过 wiz_add_timer(DHCP6_time_handler, 1000) 注册到软件定时器链表,由 1ms 中断调用 wiz_timer_handler() 驱动,累积 1000 次触发一次 DHCP6 超时处理。获取完成后调用 wiz_delete_timer() 删除定时器。

运行验证

打开 WIZ UartTool V1.0,连接 DEBUG USB 对应 COM 口(115200 / 8N1)。烧录例程运行后,首先进行 PHY 链路检测,然后等待 DAD 检测完成,接着启动 DHCPv6 客户端申请地址。预期串口输出如下:

MH2457 W6300 QSPI example start
W6300 DHCPv6 example
PHY link
The current Mbtis speed : 100Mbps
The current Duplex Mode : Full-Duplex
Wait RQIR.....


Timeout !!! DAD SUCCESSED

flags = 0x80
DHCPv6 running
DHCPv6 success!
Link-local address: FE80:0000:0000:0000:0208:DCFF:FE12:3456
Global address: 240E:033D:945A:A301:0000:0000:0000:05EC
IPv6 DNS: 240E:033D:945A:A301:0000:0000:0000:0001

串口输出依次显示 DAD 检测成功、DHCPv6 运行、DHCPv6 成功,最后打印获取到的 Link-local 地址、Global 地址和 IPv6 DNS。Global 地址由路由器(DHCPv6 服务器)分配,可用于外部网络访问。

WIZ UartTool 串口输出 — DAD 检测成功 + DHCPv6 获取 Link-local / Global 地址与 IPv6 DNS

常见问题

Q: 为什么 DHCPv6 之前要先做 DAD

IPv6 设备在链路上通信前,必须先拥有一个唯一的 Link-local 地址。DAD(重复地址检测)通过发送邻居请求确认该地址没有被其他设备占用,确保地址唯一后才能继续申请 Global 地址。如果 DAD 失败,说明地址冲突,需要重新生成。

Q: DHCPv6 获取不到地址怎么办

请检查:1) 路由器是否支持并开启了 DHCPv6 服务(部分路由器默认只开 IPv4 DHCP,需在管理界面中手动开启 IPv6);2) PC 和 W6300 是否在同一网段;3) 网线连接是否正常。可在路由器管理界面查看 DHCPv6 客户端列表确认设备是否已申请。

Q: Link-local 地址和 Global 地址有什么区别

Link-local 地址(FE80::/10)只在本地链路有效,不能跨路由器转发,用于同一网段内的通信;Global 地址(GUA)是全局可路由地址,可用于外部网络访问。设备通常同时拥有两者,具体通信使用哪个地址取决于目的地址类型。

Q: DHCPv6 的软件定时器有什么作用

W6300 的 DHCPv6 时基通过 wiz_add_timer(DHCP6_time_handler, 1000) 注册到软件定时器链表,由 1ms 中断调用 wiz_timer_handler() 驱动,累积 1000 次触发一次 DHCP6 超时处理。获取完成后调用 wiz_delete_timer() 删除定时器,避免资源占用。

Q: 为什么串口打印 Wait RQIR 和 Timeout

Wait RQIR 是 W6300 在执行 DAD 时等待路由器请求(Router Solicitation)的状态提示,Timeout 表示等待超时后 DAD 仍然成功(没有其他设备占用该地址)。这是正常的 DAD 流程,不影响后续 DHCPv6 申请。

总结

  • 双协议栈:W6300 原生支持 IPv4/IPv6 双协议栈,本例程演示 IPv6 地址获取
  • 地址获取流程:先通过 DAD 生成 Link-local 地址,再通过 DHCPv6 申请 Global 地址、DNS
  • DAD 机制:通过邻居请求确认 Link-local 地址唯一,串口打印 DAD SUCCESSED 表示可用
  • 软件定时器:DHCPv6 时基通过 wiz_add_timer 注册到软件定时器链表,由 1ms 中断驱动
  • 获取结果:串口打印 Link-local 地址、Global 地址和 IPv6 DNS,可用于后续 IPv6 通信

下载本章例程

我们提供完整的工程文件以及配套开发板,方便你随时测试,快速完成产品开发:

开发环境: Keil MDK5

Andy

W5500 技术支持专家