使用wpa工具配网、udhcpc分配IP的过程分析

本篇来介绍使用wpa工具给嵌入式Linux开发板配网、再使用udhcp工具分配IP。

1 wpa_supplication配网

wpa_supplicant 是 Linux 下标准的 Wi-Fi 认证管理工具,负责处理 Wi-Fi 连接、加密认证(WPA/WPA2/WPA3)、漫游等核心逻辑,以守护进程(后台服务) 形式运行。

1.1 创建wpa的配置文件

1.1.1 基础配置示例

创建配置文件(示例 wpa_test.conf

sh 复制代码
cat > wpa_test.conf << EOF
ctrl_interface=/var/run/wpa_supplicant
network={
    ssid="hello"
    psk="87654321"    
}
EOF

解释:

  • ctrl_interface:指定 wpa_supplicant 守护进程与客户端工具(如 wpa_cli)之间的通信接口路径,本质是通过 Unix 域套接字(Unix Domain Socket)实现进程间通信(IPC)
  • network:要连接的wifi信息:
    • ssid:wifi的名称
    • psk:wifi的密码

wpa_supplicant 运行后,普通用户或其他程序(如网络管理工具 NetworkManager)无法直接操作其内部状态,需要通过一个 "通信接口" 与其交互 ------ctrl_interface

  • wpa_supplicant 启动时,会在 /var/run/wpa_supplicant 目录下创建Unix 域套接字文件 (如 wlan0,对应无线网卡名称);
  • 客户端工具(wpa_cli、NetworkManager 等)通过访问该套接字文件,向 wpa_supplicant 发送指令(如连接 Wi-Fi、断开连接、查询状态),或接收其反馈(如连接成功 / 失败、信号强度)

上述示例的基础的配置选项,对于测试基础的网络连接就够了:

可以再了解下全部的配置选项。

1.1.2 全局配置项

wpa_supplicant.conf 的配置分为全局配置 (作用于整个 wpa_supplicant 进程)和network 块配置 (仅作用于单个 Wi-Fi 网络,可配置多个 network={} 块)

配置项 必选 / 可选 默认值 作用与解释 示例
ctrl_interface 推荐(非强制) 定义 wpa_supplicant 与客户端工具(wpa_cli/NetworkManager)的通信接口路径(Unix 域套接字目录),详见上一轮解释 ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group 可选 指定可访问 ctrl_interface 的用户组(如 0 代表 root 组,netdev 代表网络设备组),解决普通用户操作权限问题 ctrl_interface_group=0
**update_config** 可选 0(禁用) 允许通过 wpa_cli 动态修改配置并保存到 wpa_supplicant.conf(如添加 / 删除 Wi-Fi),1 启用,0 禁用 update_config=1
ap_scan 可选 1 扫描 AP 的模式:- 0:仅使用驱动提供的扫描结果(适合企业级 / 隐藏 SSID);- 1wpa_supplicant 主动扫描(默认,适合普通场景);- 2:仅连接已配置的 BSSID(精准定位某台路由器) ap_scan=1
fast_reauth 可选 1 快速重认证:1 启用(漫游 / 重连时跳过部分认证步骤,加快连接速度),0 禁用 fast_reauth=1
background_scan_period 可选 30(秒) 后台扫描周期:未连接时,wpa_supplicant 主动扫描附近 Wi-Fi 的间隔(单位:秒),0 禁用后台扫描 background_scan_period=60
eapol_version 可选 1 EAPOL(以太网认证协议)版本:- 1:兼容 WPA/WPA2;- 2:仅 WPA2/WPA3;- 3:仅 WPA3 eapol_version=2
country 可选 指定国家码(如 CN 中国、US 美国),用于适配当地 Wi-Fi 频段 / 功率限制(合规性,避免驱动限制频段) country=CN
freq_list 可选 指定仅扫描特定频段(单位:MHz),减少扫描耗时(适合嵌入式 / 低功耗场景) freq_list=2412 2437 5180 5240(2.4G+5G 常用频段)
logger_syslog 可选 1 是否将日志输出到系统日志(syslog):1 启用,0 禁用 logger_syslog=1
logger_level 可选 2 日志级别:- 0:调试(最详细);- 1:信息;- 2:警告;- 3:错误;- 4:致命错误 logger_level=1
p2p_disabled 可选 0 禁用 Wi-Fi P2P(点对点,如 Wi-Fi 直连):1 禁用,0 启用

1.1.3 network 块配置项

network={} 块可配置多个(对应多个 Wi-Fi),wpa_supplicant 会按 priority 优先级自动连接

配置项 必选 / 可选 默认值 作用与解释 示例
ssid 必选 Wi-Fi 名称(SSID),字符串需用双引号包裹;隐藏 SSID 也需填写(需配合 scan_ssid=1 ssid="hello"
psk 可选(与 wep_key0/eap 二选一) WPA-PSK/WPA2-PSK/WPA3-SAE 的密码:- 可直接填明文(如 "87654321"),wpa_supplicant 会自动转为哈希;- 也可填预计算的 PSK 哈希(更安全,避免明文存储) psk="87654321"psk=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
key_mgmt 可选(推荐显式指定) 自动探测 密钥管理 / 认证方式(核心!决定加密类型),可选值:- NONE:无加密(开放 Wi-Fi);- WEP:WEP 加密(老旧 / 不安全);- WPA-PSK:WPA-PSK(TKIP);- WPA2-PSK:WPA2-PSK(AES);- WPA-PSK WPA2-PSK:兼容 WPA/WPA2;- WPA3-SAE:WPA3 加密;- EAP:企业级认证(802.1X,如 PEAP/TLS) key_mgmt=WPA2-PSK
priority 可选 0 连接优先级(整数,数值越大优先级越高),多 Wi-Fi 时优先连接高优先级的 priority=10(比默认 0 优先)
scan_ssid 可选 0 针对隐藏 SSID(不广播名称的 Wi-Fi):- 0:不主动扫描隐藏 SSID;- 1:强制扫描并连接隐藏 SSID scan_ssid=1
bssid 可选 指定路由器的 MAC 地址(精准连接某台路由器,避免同 SSID 多路由器时连错) bssid=AA:BB:CC:DD:EE:FF
proto 可选 自动适配 指定 WPA 协议版本,可选值:- WPA:仅 WPA;- RSN:仅 WPA2(RSN=Robust Security Network);- WPA RSN:兼容 WPA/WPA2 proto=RSN
pairwise 可选 自动适配 成对加密算法(单播数据加密),可选值:- TKIP:WPA 常用(不安全);- CCMP:WPA2/WPA3 常用(AES-CCMP,安全);- GCMP:WPA3 可选(更高效) pairwise=CCMP
group 可选 自动适配 组加密算法(广播 / 组播数据加密),可选值同 pairwise group=CCMP
wep_key0 可选(WEP 加密时必选) WEP 加密的密钥(第 0 个密钥),老旧加密方式,不推荐使用 wep_key0="1234567890"
wep_tx_keyidx 可选(WEP 时用) 0 WEP 发送数据使用的密钥索引(0-3) wep_tx_keyidx=0
eap 可选(企业级 Wi-Fi 必选) 企业级 802.1X 认证方式,可选值:- PEAP:最常见(如校园网 / 企业网);- TLS:证书认证;- TTLS:隧道 TLS;- PWD:WPA3 企业级 eap=PEAP
identity 可选(EAP 认证时必选) 企业级 Wi-Fi 的认证账号(如校园网学号 / 企业工号) identity="student123"
password 可选(EAP-PEAP/TTLS 时必选) 企业级 Wi-Fi 的认证密码 password="12345678"
ca_cert 可选(EAP-TLS 时必选) 企业级 Wi-Fi 的 CA 证书路径(验证服务器身份) ca_cert="/etc/certs/ca.pem"
client_cert 可选(EAP-TLS 时必选) 客户端证书路径(TLS 双向认证) client_cert="/etc/certs/client.pem"
private_key 可选(EAP-TLS 时必选) 客户端私钥路径 private_key="/etc/certs/client.key"
phase2 可选(EAP-PEAP/TTLS 时用) PEAP/TTLS 第二阶段认证方式,如 auth=MSCHAPV2(Windows 域认证) phase2="auth=MSCHAPV2"
disabled 可选 0 禁用该网络配置:1 禁用(保留配置但不连接 ),0 启用 disabled=1
bgscan 可选 后台扫描(漫游时用),格式:simple:<间隔>:<信号阈值>(信号低于阈值时触发扫描) bgscan="simple:30:-70"(30 秒扫一次,信号 < -70dBm 触发扫描)
pmf 可选 0 保护管理帧(PMF,WPA2/WPA3 安全特性):- 0:禁用;- 1:可选(支持但不强制);- 2:强制(必须支持 PMF 才能连接) pmf=2(WPA3 推荐)
sae_password 可选(WPA3-SAE 时用) WPA3-SAE 加密的密码(替代 psk,更安全) sae_password="87654321"
ip_addr 可选 静态 IP 地址(需配合 proto=static,但 wpa_supplicant 不负责 IP 分配,建议用 dhcpcd/networkd 配置) ip_addr=192.168.1.100/24
gateway 可选 静态网关(同上,不推荐在 wpa_supplicant 中配置) gateway=192.168.1.1
dns 可选 静态 DNS 服务器(同上) dns=8.8.8.8 8.8.4.4
timeout 可选 连接超时时间(单位:秒),超时后放弃连接并尝试下一个 Wi-Fi timeout=10
fail_retry 可选 3 连接失败后重试次数,0 表示无限重试

1.1.4 较完整的配置示例

针对普通家庭 WPA2-PSK Wi-Fi,推荐补充核心参数,确保稳定 + 安全:

sh 复制代码
# 全局配置
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0  # 允许 root 组访问
update_config=1         # 允许动态修改并保存配置
country=CN              # 适配中国频段
fast_reauth=1           # 快速重连

# 网络配置
network={
    ssid="hello"
    psk="87654321"
    key_mgmt=WPA2-PSK    # 显式指定加密类型,避免自动探测失败
    proto=RSN            # 仅 WPA2(拒绝老旧 WPA)
    pairwise=CCMP        # 强制 AES 加密(拒绝不安全的 TKIP)
    group=CCMP
    priority=5           # 优先级高于默认 0 的 Wi-Fi
    scan_ssid=0          # 非隐藏 SSID,无需强制扫描
}

1.2 创建wpa的接口目录

上面提到,/var/run/wpa_supplicantwpa_supplicant与客户端工具(如 wpa_cli)之间的进程间通信(IPC)接口目录,所以需要确保该目录的存在,可以手动创建该目录,并赋予权限:

c 复制代码
mkdir -p /var/run/wpa_supplicant
chmod 777 /var/run/wpa_supplicant

1.3 启动wpa_supplicant

sh 复制代码
wpa_supplicant -B -i mlan0 -c wpa_test.conf
  • -B:后台运行
  • -i mlan0:指定无线网卡(嵌入式常见 wlan0,需根据实际调整,这里使用的mlan0)
  • -c test_wpa.conf:指定配置文件路径

在运行之前,可以先看下mlan0的情况:

1.3.1 ifconfig对mlan0的输出

先解释一下ifconfig对mlan0的输出:

第一行 网卡设备名、链路封装类型、MAC 地址

mlan0 Link encap:Ethernet HWaddr E8:FB:1C:66:AF:DF

字段 含义解释 嵌入式场景补充
mlan0 网卡设备名:嵌入式系统中,无线网卡常用 mlan0(而非通用 Linux 的 wlan0 若有双频 Wi-Fi,可能还会有 mlan1(5G 频段),mlan0 通常为 2.4G 频段
Link encap:Ethernet 链路封装类型:表示该网卡使用以太网封装协议(即使是无线网卡,逻辑上仍兼容以太网帧格式) 区别于 PPP(拨号)、Loopback(回环)等封装类型,无线网卡核心仍遵循以太网规范
HWaddr E8:FB:1C:66:AF:DF 硬件地址(MAC 地址):- 无线网卡的唯一物理标识,由厂商烧录(E8:FB:1C 段属于瑞芯微 / 合作厂商) 嵌入式场景中,可通过 ifconfig mlan0 hw ether xx:xx:xx:xx:xx:xx 临时修改(重启失效),用于适配特定 AP 的 MAC 白名单
第二行 广播/组播模式、最大传输单元、路由度量值

BROADCAST MULTICAST MTU:1500 Metric:1

字段 含义解释 嵌入式场景补充
BROADCAST 网卡启用广播模式:支持接收 / 发送广播包(如 ARP 广播、DHCP 发现包);无线网卡必须开启此模式,才能发现周边 AP(广播扫描) 若缺失此标识,说明网卡被禁用广播,会导致无法扫描 Wi-Fi、获取 DHCP 地址
MULTICAST 网卡启用组播模式:支持接收 / 发送组播包(如 IGMP、Wi-Fi 组播数据) 嵌入式低功耗场景中,可关闭组播减少功耗,但会影响组播相关功能
MTU:1500 最大传输单元:网卡单次可传输的最大数据包长度(字节);1500 是以太网标准 MTU,无线网卡默认沿用 嵌入式场景中,若需适配特殊网络(如 VPN、低带宽链路),可通过 ifconfig mlan0 mtu 1480 修改,防止数据包分片丢失
Metric:1 路由度量值:系统选择路由时的优先级(数值越小优先级越高);仅当存在多网卡(如 mlan0 + eth0)时生效,决定数据包走哪张网卡 嵌入式设备若同时连有线(eth0)和无线(mlan0),可通过调整 Metric 控制默认路由(如 Metric:0 优先无线)
第三行 接收方向的数据包统计

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

字段 含义解释 嵌入式场景补充
RX packets:0 累计接收的数据包总数:0 表示该网卡自启动后未收到任何数据包 连接 Wi-Fi 成功后,该数值会随接收数据(如 ping 包、上网数据)增长
errors:0 接收错误包数:0 表示无接收错误(如 CRC 校验失败、帧格式错误) 嵌入式设备若在强干扰环境(如工业场景),此值易增加,需优化 Wi-Fi 频段 / 天线
dropped:0 接收丢弃包数:0 表示内核 / 驱动未丢弃接收包;非 0 原因:内存不足、缓冲区满、策略过滤(如 iptables 规则) 嵌入式系统内存有限,高流量下易出现丢弃,需调整网卡接收缓冲区
overruns:0 接收缓冲区溢出数:0 表示接收缓冲区未溢出;非 0 是驱动处理速度跟不上数据包接收速度,导致数据丢失 嵌入式无线驱动(如 mlan)可通过模块参数调整缓冲区大小(如 echo 4096 > /proc/sys/net/core/rmem_default
frame:0 接收帧错误数:0 表示无帧格式错误(如帧长度异常、校验位错误);无线场景中,帧错误多由信号弱、干扰导致。 可通过 iwconfig mlan0 查看信号强度(Link Quality),判断是否因信号问题导致帧错误。
第四行 发送方向的数据包统计

TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

字段 含义解释 嵌入式场景补充
TX packets:0 累计发送的数据包总数:0 表示网卡未发送任何数据包 执行 wpa_supplicant 连接 Wi-Fi 后,发送认证包、DHCP 请求包,此值会立即增加。
errors:0 发送错误包数:0 表示无发送错误(如驱动发送失败、硬件故障);非 0 可能是网卡未启动、驱动加载异常 嵌入式设备需确认无线驱动已加载(lsmodgrep mlan),否则会出现发送错误。
dropped:0 发送丢弃包数:0 表示内核 / 驱动未丢弃发送包;非 0 原因:路由未配置、目标不可达、策略限制 嵌入式设备若未配置网关,发送外网数据包时会被丢弃,此值增加
overruns:0 发送缓冲区溢出数:0 表示发送缓冲区未溢出;非 0 是驱动发送速度跟不上应用层发包速度(如高并发数据传输) 嵌入式低主频设备(RK3568 主频 2GHz 左右),高带宽发送时需控制发包速率
carrier:0 载波检测错误数:0 表示载波检测正常;原本是有线网卡的指标(检测物理链路是否连通),无线网卡复用该字段,无实际意义 无线网卡无需关注此值,核心看信号强度和关联状态
第五行 数据包碰撞数/发送队列长度

collisions:0 txqueuelen:1000

字段 含义解释 嵌入式场景补充
collisions:0 数据包碰撞数:0 表示无碰撞(多个设备同时发包导致冲突);有线以太网(共享链路)常见,无线网卡基于 CSMA/CA 协议避免碰撞,此值几乎恒为 0 嵌入式无线场景中,该字段无参考价值,无需关注
txqueuelen:1000 发送队列长度:内核为该网卡分配的发送队列大小(最多缓存 1000 个待发送包);队列满后,新包会被丢弃 可减小队列长度(ifconfig mlan0 txqueuelen 500)降低内存占用;高流量场景可增大(如 2000)
第六行 累计接收/发送字节数

RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

字段 含义解释 嵌入式场景补充
RX bytes:0 (0.0 B) 累计接收字节数:0 表示未接收任何数据(对应 RX packets:0) 连接 Wi-Fi 并 ping 网关后,该值会立即增加(如 ping 一次发送 32 字节,接收 32 字节)
TX bytes:0 (0.0 B) 累计发送字节数:0 表示未发送任何数据(对应 TX packets:0);是数据包长度的总和(含帧头、有效数据) 嵌入式设备调试时,可通过此值判断是否有数据传输(如 ping 192.168.1.1 后,TX/RX bytes 应大于 0)

总上, mlan0 网卡当前状态:

  • 已加载驱动、硬件正常(能识别 MAC 地址)
  • 未关联任何 Wi-Fi AP(无 IP、无数据收发,RX/TX 均为 0)
  • 无任何错误 / 丢包(基础状态正常,仅未配置连接)

1.3.2 运行wpa_supplicant的结果

实际运行结果如下:

分析:

Successfully initialized wpa_supplicant
  • 含义:wpa_supplicant 进程初始化成功,已读取配置文件 wpa_test.conf,并绑定到 mlan0 网卡
  • 关键:仅表示进程启动成功,不代表已连接 Wi-Fi(后续需完成 "扫描→认证→关联" 三步)
  • 内核日志(时间戳 137.484288 是系统启动后的秒数)
  • ADDRCONF(NETDEV_UP):内核检测到 mlan0 网卡被 "启用(UP)",但链路层未就绪
  • link is not readymlan0 尚未与 Wi-Fi AP 完成 "关联(Association)",链路层不通(此时无法收发数据)
  • 原因:wpa_supplicant 刚启动,正在扫描 AP、协商认证参数(WPA-PSK 握手),链路还未建立
  • 内核日志(间隔约 3.5 秒后)
  • ADDRCONF(NETDEV_CHANGE):内核检测到 mlan0 网卡状态变化
  • link becomes readymlan0 已与 Wi-Fi AP 完成关联 + 认证,链路层就绪(物理 / 数据链路层打通)
  • 关键:这是 Wi-Fi 连接成功的核心标志(链路层通了,接下来可获取 IP 地址)

再来看此时ifconfig的结果:

第一行:mlan0 Link encap:Ethernet HWaddr E8:FB:1C:66:AF:DF

  • 无变化:网卡名、封装类型、MAC 地址(E8:FB:1C:66:AF:DF)仍为硬件固有属性。

第二行inet6 addr: fe80::eafb:1cff:fe66:afdf/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

新增 / 变化字段 含义解释 嵌入式场景补充
inet6 addr: fe80::eafb:1cff:fe66:afdf/64 自动生成的 IPv6 链路本地地址fe80:: 是 IPv6 链路本地地址段(仅在当前 Wi-Fi 局域网内有效);由 MAC 地址(E8:FB:1C:66:AF:DF)通过 EUI-64 规则生成(eafb:1cff:fe66:afdf 对应 MAC 转换);Scope:Link:地址作用域为 "链路本地",无法路由到外网 嵌入式 Linux 默认开启 IPv6 自动配置,链路就绪后会生成此地址(无需 DHCPv6);此时未看到 IPv4 地址,说明还没获取 DHCPv4
UP 网卡已被启用(对应 ip link set mlan0 up),之前的状态虽有 BROADCAST MULTICAST 但无 UP,现在链路就绪后内核自动标记 UP 嵌入式网卡默认可能是 DOWN 状态,wpa_supplicant 启动时会自动将网卡设为 UP
RUNNING 网卡 "运行中":链路层已建立(对应 link becomes ready),是区别于之前状态的核心标志 RUNNING 表示链路未通,有则说明 Wi-Fi 关联成功

第三行RX packets:2 errors:0 dropped:0 overruns:0 frame:0

  • RX packets:2累计接收 2 个数据包(对比之前的 0)
  • 来源:这 2 个包是 Wi-Fi 关联过程中接收的 AP 响应包(如认证成功帧、Beacon 帧)
  • 无错误 / 丢包:链路通信正常,无信号干扰或驱动问题

第四行TX packets:9 errors:0 dropped:0 overruns:0 carrier:0

  • TX packets:9累计发送 9 个数据包(对比之前的 0)
  • 来源:这 9 个包是 wpa_supplicant 发送的认证包(如 WPA-PSK 四次握手包、关联请求包)
  • 无错误 / 丢包:网卡发送功能正常,AP 已收到并响应认证请求

第五行:collisions:0 txqueuelen:1000

  • 无变化:无线网卡基于 CSMA/CA 协议避免碰撞,此值恒为 0;发送队列长度仍为默认 1000

第六行RX bytes:254 (254.0 B) TX bytes:834 (834.0 B)

  • RX bytes:254:接收总字节数(2 个包的总长度,含帧头)
  • TX bytes:834:发送总字节数(9 个包的总长度,WPA 握手包比响应包长,所以字节数更多)
  • 验证:字节数非 0 证明链路已通,数据能正常收发

综上:

  • wpa_supplicant 启动成功,mlan0 已与 Wi-Fi AP 完成关联 + 认证(链路层就绪)
  • 缺少 IPv4 地址(ifconfiginet addr 字段),无法访问外网 / 局域网 IPv4 设备
  • IPv6 链路本地地址自动生成,但无实际路由价值(嵌入式场景主要用 IPv4)

1.4 查看 wpa_supplicant的帮助信息

wpa_supplicant的使用完毕,可以再来看下它的帮助信息:

sh 复制代码
[root@ok3568:/]# wpa_supplicant -h
wpa_supplicant v2.6
Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)

usage:
  wpa_supplicant [-BddhKLqqtvW] [-P<pid file>] [-g<global ctrl>] \
        [-G<group>] \
        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
        [-b<br_ifname>] [-e<entropy file>] [-f<debug file>] \
        [-o<override driver>] [-O<override ctrl>] \
        [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
        [-m<P2P Device config file>] \
        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] ...]

drivers:
  nl80211 = Linux nl80211/cfg80211
  wext = Linux wireless extensions (generic)
  wired = Wired Ethernet driver
options:
  -b = optional bridge interface name
  -B = run daemon in the background
  -c = Configuration file
  -C = ctrl_interface parameter (only used if -c is not)
  -d = increase debugging verbosity (-dd even more)
  -D = driver name (can be multiple drivers: nl80211,wext)
  -e = entropy file
  -f = log output to debug file instead of stdout
  -g = global ctrl_interface
  -G = global ctrl_interface group
  -h = show this help text
  -i = interface name
  -I = additional configuration file
  -K = include keys (passwords, etc.) in debug output
  -L = show license (BSD)
  -m = Configuration file for the P2P Device interface
  -M = start describing new matching interface
  -N = start describing new interface
  -o = override driver parameter for new interfaces
  -O = override ctrl_interface parameter for new interfaces
  -p = driver parameters
  -P = PID file
  -q = decrease debugging verbosity (-qq even less)
  -t = include timestamp in debug messages
  -v = show version
  -W = wait for a control interface monitor before starting
example:
  wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf
[root@ok3568:/]#

1.4.1 必选参数(连接 Wi-Fi 必须指定)

参数 作用 示例
-i <ifname> 指定 Wi-Fi 网卡名 (OK3568 默认是mlan0,而非通用的wlan0 -i mlan0
-c <config> 指定 Wi-Fi 配置文件路径(包含 SSID、密码、加密方式等) -c /etc/wpa_supplicant.conf
-D <driver> 指定 Wi-Fi 驱动类型(嵌入式 Linux 首选nl80211,兼容wext -D nl80211-D nl80211,wext(多驱动兼容)

1.4.2 调试 / 日志参数(排查连接问题)

参数 作用 示例
-d 增加调试日志详细度(-dd更详细,能看到认证 / 握手过程) -d(前台运行时看完整日志)
-f <file> 将调试日志写入文件(避免刷屏,便于后续分析) -f /tmp/wpa_debug.log
-t 日志中包含时间戳(定位问题发生时间) -t
-K 日志中显示密钥(密码)(调试时用,注意安全) -K
-q 降低日志详细度(-qq几乎无日志,后台运行用) -q

1.4.3 后台 / 进程管理参数(开机自启 / 常驻运行)

参数 作用 示例
-B 后台运行(daemon 模式,不占用终端) -B(推荐开机自启时用)
-P <pid> 指定 PID 文件(记录进程号,便于后续停止 / 重启) -P /var/run/wpa_supplicant.pid
-g <ctrl> 指定全局控制接口(用于wpa_cli交互管理) -g /var/run/wpa_supplicant/global

1.4.4 其他实用参数

参数 作用 示例
-N 同时配置多个 Wi-Fi 接口(极少用,单网卡无需) -N -i mlan1 -c /etc/wpa2.conf
-I <config> 加载额外配置文件(补充主配置的参数) -I /etc/wpa_extra.conf
-W 等待控制接口监视器启动后再运行(确保wpa_cli能连接) -W
-v 查看版本(确认是否是 v2.6,匹配你的环境) -v

2 wpa_cli查看状态

在上述分析中,此时mlan0已经连接到wifi了。

也可以通过wpa_cli来进一步验证。

wpa_supplicant是服务端,wpa_cli属于客户端,可以查询wpa_supplicant服务端的状态。

2.1 启动wpa_cli

sh 复制代码
wpa_cli -i mlan0

2.2 扫描wifi

sh 复制代码
scan

可以用来扫描当前环境中的所有wifi,执行成功会返回OK

2.3 查看扫描结果

sh 复制代码
scan_result

查看扫描到结果:

分析:

  • wap_cli:

    • wpa_cli v2.6wpa_cli 工具版本为 2.6(嵌入式 Linux 常用版本,适配老旧驱动 / 硬件)
    • Interactive mode:进入交互式模式(可输入指令如 scan/scan_result/status 等操作 Wi-Fi)
  • 执行 scan 指令:

    • <3>CTRL-EVENT-SCAN-STARTED:扫描开始事件(<3> 是日志级别:警告级)
    • <3>CTRL-EVENT-REGDOM-CHANGE init=BEACON_HINT type=UNKNOWN:区域码(国家码)变更事件:
      • init=BEACON_HINT:从 AP 的 Beacon 帧中检测到区域码提示
      • type=UNKNOWN:无法识别具体国家码,使用默认配置
    • <3>CTRL-EVENT-SCAN-RESULTS:扫描完成事件,可执行 scan_result 查看结果
  • scan_result 扫描结果:

    • scan_result 输出格式:bssid / frequency / signal level / flags / ssid
    列名 含义 单位 / 取值说明
    bssid AP 的 MAC 地址(路由器无线网卡物理地址) 十六进制 MAC 格式(如 92:97:c7:2d:c6:13
    frequency 无线频段(信道对应的频率) MHz(24xx 为 2.4G 频段,5xxx 为 5G 频段)
    signal level 信号强度(RSSI) dBm(数值越大信号越强,-22 > -44 > -88)
    flags 加密 / 认证特性 [WPA2-PSK-CCMP] 表示 WPA2-PSK 加密,CCMP 算法
    ssid Wi-Fi 名称 字符串(如 hello 是你要连接的目标 Wi-Fi)
  • xx:xx:c7:2d:c6:13 2437 -22 [WPA2-PSK-CCMP][ESS] hello

    • 2.4G 频段(信道 6)
    • 信号 -22dBm(极强,距离 AP 极近)
    • 加密:仅 WPA2-PSK,CCMP 算法(无 WPA 兼容,更安全)
    • WPS,仅密码认证
  • xx:xx:b8:fb:2d:a7 5765 -88 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] CMCC-mRmT-5G

    • 5G 频段(5765MHz = 信道 153)
    • 信号 -88dBm(极弱)
    • 移动 5G Wi-Fi

2.4 查看连接状态

sh 复制代码
status

分析:

  • bssid=92:97:c7:2d:c6:13:AP 的 MAC 地址,与 scan_resulthello 的 BSSID 完全一致,确认连接的是目标路由器
  • freq=2437:2437 MHz,对应 2.4G 频段的信道 6(2437=2400+37,每信道间隔 5MHz)
  • ssid=hello:目标 Wi-Fi 名称,确认连接的 SSID 正确
  • id=0:网络配置 ID,对应 add_network 时返回的 ID=0(实际是conf文件中只配置了一个)
  • mode=station:工作模式:站点(客户端),station= 客户端模式(连接 AP),区别于 AP(热点模式)
  • pairwise_cipher=CCMP:单播加密算法:CCMP,与 hello 的加密配置(WPA2-PSK+CCMP)匹配,安全无兼容问题
  • group_cipher=CCMP:组播加密算法:CCMP,广播 / 组播数据加密算法,与 AP 协商一
  • key_mgmt=WPA2-PSK:密钥管理方式:WPA2-PSK,与 hello 的加密类型完全匹配,认证
  • wpa_state=COMPLETED: WPA 认证状态:完成
    • COMPLETED = 认证 + 关联全成功
    • ASSOCIATING= 关联中
    • 4WAY_HANDSHAK= 握手中
  • p2p_device_address=e8:fb:1c:66:af:df: P2P 设备 MAC,嵌入式网卡的 Wi-Fi 直连(P2P)物理地址(与网卡 MAC 一致)
  • address=e8:fb:1c:66:af:df:网卡 MAC 地址,mlan0 的硬件 MAC,与 ifconfig 输出一致
  • uuid=dbddbcf1-3fcd-54be-b9aa-57858a84189f:设备唯一标识,wpa_supplicant 生成的 UUID,无实际业务影响

综上:

  • mlan0hello AP 完成「扫描→认证→关联→四次握手」全流程
  • 加密算法、密钥管理等参数与 AP 完全匹配,无兼容性问题
  • 物理层 / 数据链路层已打通,仅缺 IPv4 地址(网络层)即可访问网络

2.5 退出wap_cli

退出wap_cli的命令行交互环境:

quit 复制代码
quit

3 udhcpc分配IP

wpa_supplicant只是与wifi建立了连接,但没有给设备分配IP,如果要分配IP,就需要使用udhcpc。

为 mlan0 启动 DHCP 客户端,向 AP 申请 IPv4 地址

sh 复制代码
udhcpc -i mlan0

分析:

  • udhcpc -i mlan0:首次发送 3 次 discover 未响应(可能是 DHCP 服务器初始化延迟),二次执行成功获取 IP(10.32.158.243),租期 3599 秒(约 1 小时)
  • ifconfig mlan0:Wi-Fi 网卡(mlan0)状态正常:IP / 子网掩码 / 网关 / DNS 配置完整,收发数据包无错误(RX/TX errors=0)
  • ping qq.com: 域名解析成功(解析到 113.108.81.189),网络连通性正常(延迟~40ms,无丢包)

至此,wifi连接成功,IP地址获取到了,ping外网成功。

3.1 查看udhcpc的帮助信息

下面再来研究一下udhcpc,可以先看下它的帮助信息:

sh 复制代码
[root@ok3568:/etc]# udhcpc -h
udhcpc: option requires an argument -- 'h'
BusyBox v1.27.2 (2022-08-22 07:17:23 UTC) multi-call binary.

Usage: udhcpc [-fbqRB] [-a[MSEC]] [-t N] [-T SEC] [-A SEC/-n]
        [-i IFACE] [-s PROG] [-p PIDFILE]
        [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]...

        -i,--interface IFACE    Interface to use (default eth0)
        -s,--script PROG        Run PROG at DHCP events (default /usr/share/udhcpc/default.script)
        -p,--pidfile FILE       Create pidfile
        -B,--broadcast          Request broadcast replies
        -t,--retries N          Send up to N discover packets (default 3)
        -T,--timeout SEC        Pause between packets (default 3)
        -A,--tryagain SEC       Wait if lease is not obtained (default 20)
        -n,--now                Exit if lease is not obtained
        -q,--quit               Exit after obtaining lease
        -R,--release            Release IP on exit
        -f,--foreground         Run in foreground
        -b,--background         Background if lease is not obtained
        -S,--syslog             Log to syslog too
        -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping
        -r,--request IP         Request this IP address
        -o,--no-default-options Don't request any options (unless -O is given)
        -O,--request-option OPT Request option OPT from server (cumulative)
        -x OPT:VAL              Include option OPT in sent packets (cumulative)
                                Examples of string, numeric, and hex byte opts:
                                -x hostname:bbox - option 12
                                -x lease:3600 - option 51 (lease time)
                                -x 0x3d:0100BEEFC0FFEE - option 61 (client id)
        -F,--fqdn NAME          Ask server to update DNS mapping for NAME
        -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')
        -C,--clientid-none      Don't send MAC as client identifier
Signals:
        USR1    Renew lease
        USR2    Release lease

来介绍下这些参数

3.1.1 基础必选参数(最常用)

参数 作用 示例
-i, --interface IFACE 指定要获取 IP 的网卡(默认 eth0,Wi-Fi 用 mlan0) udhcpc -i mlan0
-q, --quit 获取到 IP 后立即退出(后台不驻留,适合脚本 / 开机自启) udhcpc -i mlan0 -q
-f, --foreground 前台运行(不后台,便于看日志 / 调试) udhcpc -i mlan0 -f
-b, --background 未获取到 IP 时后台运行(默认行为) udhcpc -i mlan0 -b

3.1.2 DHCP 交互控制参数(调优 IP 获取逻辑)

参数 作用 示例
-t, --retries N 发送 discover 包的最大次数(默认 3 次,你首次执行时就是发了 3 次) udhcpc -i mlan0 -t 5(发 5 次)
-T, --timeout SEC 每次 discover 包之间的间隔(默认 3 秒) udhcpc -i mlan0 -T 5(间隔 5 秒)
-A, --tryagain SEC 获取 IP 失败后等待重试的时间(默认 20 秒) udhcpc -i mlan0 -A 10(等待 10 秒)
-n, --now 获取不到 IP 直接退出(不等待,适合脚本判断) udhcpc -i mlan0 -n
-R, --release 退出时释放获取到的 IP(避免 IP 占用) udhcpc -i mlan0 -R

3.1.3 自定义 IP / 选项参数(高级场景)

参数 作用 示例
-r, --request IP 主动请求指定 IP(需 DHCP 服务器支持) udhcpc -i mlan0 -r 10.32.158.243
-O, --request-option OPT 向 DHCP 服务器请求指定选项(如 DNS、网关) udhcpc -i mlan0 -O dns -O router
-x OPT:VAL 自定义发送给 DHCP 服务器的选项(如主机名、租期) udhcpc -i mlan0 -x hostname:ok3568(设置主机名)
-F, --fqdn NAME 让 DHCP 服务器更新 DNS 映射(绑定主机名和 IP) udhcpc -i mlan0 -F ok3568

3.1.4 调试 / 日志参数(排查问题)

参数 作用 示例
-S, --syslog 将日志输出到系统日志(/var/log/messages) udhcpc -i mlan0 -S
-a[MSEC], --arping 获取 IP 前用 ARP ping 验证 IP 是否被占用(避免冲突) udhcpc -i mlan0 -a 1000(等待 1 秒)

3.2 默认脚本default.script

通常路径为 /usr/share/udhcpc/default.script,核心作用是在 DHCP 不同阶段(获取 IP、释放 IP、续租 IP 等)自动配置网卡 IP、网关、DNS 等网络参数。

sh 复制代码
[root@ok3568:/etc]# cd /usr/share/udhcpc/
[root@ok3568:/usr/share/udhcpc]# ls
default.script  default.script.d

udhcpc 默认会调用 /usr/share/udhcpc/default.script 处理 IP 获取后的配置(如设置 DNS、网关),这也是前面测试时能自动获分配IP的原因;如果需要自定义配置(比如修改 DNS 为 114.114.114.114),可以写自己的脚本,用 -s 参数指定。

来分析下这个default.script:

sh 复制代码
#!/bin/sh

# udhcpc script edited by Tim Riker <Tim@Rikers.org>

# 判断$1是否为空(即脚本未被udhcpc调用,而是手动执行)
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

# 定义 DNS 配置文件路径:/etc/resolv.conf 是 Linux 系统的 DNS 解析配置文件(存放 nameserver、search 等)
RESOLV_CONF="/etc/resolv.conf"
[ -e $RESOLV_CONF ] || touch $RESOLV_CONF # 检查文件是否存在,不存在则创建(避免后续写入失败)
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" # 广播地址
[ -n "$subnet" ] && NETMASK="netmask $subnet" # 子网掩码

case "$1" in
		# 释放 IP(如 udhcpc 退出、手动释放)
        deconfig)
                /sbin/ifconfig $interface up # 确保网卡处于启用状态(避免操作失败)
                /sbin/ifconfig $interface 0.0.0.0 # 清空网卡的 IP 地址(释放 IP 核心操作)

                # drop info from this interface
                # resolv.conf may be a symlink to /tmp/, so take care
                TMPFILE=$(mktemp) # 创建临时文件(避免直接修改resolv.conf导致文件损坏)
                grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE # 过滤掉resolv.conf中以# mlan0结尾的行
                cat $TMPFILE > $RESOLV_CONF # 把过滤后的内容写回resolv.conf
                rm -f $TMPFILE # 删除临时文件

                if [ -x /usr/sbin/avahi-autoipd ]; then # 检查avahi-autoipd是否存在且可执行
                        /usr/sbin/avahi-autoipd -k $interface # 终止该网卡的 Avahi 服务(释放 IP 后无需零配置 IP)
                fi
                ;;

		# 获取 IP 失败(DHCP 服务器拒绝 / 无响应)
        leasefail|nak)
                if [ -x /usr/sbin/avahi-autoipd ]; then
                		# -wD:后台运行(-D)并等待(-w)获取零配置 IP(169.254.x.x),保证网卡至少有一个可用 IP
                		# --no-chroot:不使用 chroot 环境(简化权限,嵌入式系统常用)
                        /usr/sbin/avahi-autoipd -wD $interface --no-chroot
                fi
                ;;

        # 续租 IP / 首次成功获取 IP
        renew|bound)
                if [ -x /usr/sbin/avahi-autoipd ]; then
                		# 成功获取 IP 后,关闭 Avahi 自动 IP(优先使用 DHCP 分配的 IP,而非零配置 IP
                        /usr/sbin/avahi-autoipd -k $interface
                fi
                # 配置网卡 IP:拼接广播地址、子网掩码,完成 IP 配置
                /sbin/ifconfig $interface $ip $BROADCAST $NETMASK

				# 清理旧网关
                if [ -n "$router" ] ; then # DHCP 服务器分配的网关(如10.32.158.1)
                        echo "deleting routers"
                        # 循环删除该网卡的所有默认网关(避免网关冲突)
                        while route del default gw 0.0.0.0 dev $interface 2> /dev/null; do
                        		# 空命令(while 循环体无需操作,仅执行删除动作)
                                :
                        done

						# 添加新网关
                        for i in $router ; do
                        		# 遍历$router(可能有多个网关),为网卡添加默认网关(这是能 ping 通外网的核心)
                                route add default gw $i dev $interface
                        done
                fi

                # drop info from this interface
                # resolv.conf may be a symlink to /tmp/, so take care
                # 清理该网卡旧的 DNS 配置(同deconfig阶段,避免 DNS 残留)
                TMPFILE=$(mktemp)
                grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE
                cat $TMPFILE > $RESOLV_CONF
                rm -f $TMPFILE

                # prefer rfc3359 domain search list (option 119) if available
                # 配置域名搜索列表
                if [ -n "$search" ]; then # DHCP 服务器的 RFC3359 域名搜索列表(优先)
                        search_list=$search
                elif [ -n "$domain" ]; then # DHCP 服务器的域名(备选)
                        search_list=$domain
                fi

				# 写入域名搜索列表到resolv.conf,并标注网卡名
                [ -n "$search_list" ] &&
                        echo "search $search_list # $interface" >> $RESOLV_CONF

				# 写入 DNS 服务器地址
                for i in $dns ; do
                        echo adding dns $i
                        echo "nameserver $i # $interface" >> $RESOLV_CONF
                done
                ;;
esac

# 钩子脚本扩展(可选)
HOOK_DIR="$0.d" # 脚本所在目录下的.d子目录(如default.script.d)

# 遍历该目录下所有可执行文件,传递当前脚本的参数(事件、网卡、IP 等)执行,用于扩展自定义逻辑
for hook in "${HOOK_DIR}/"*; do
    [ -f "${hook}" -a -x "${hook}" ] || continue
    "${hook}" "${@}"
done

exit 0

钩子脚本目录目前没有内容:

sh 复制代码
[root@ok3568:/usr/share/udhcpc/default.script.d]# ls
[root@ok3568:/usr/share/udhcpc/default.script.d]#

3.3 resolv.conf

最后来看下/etc/resolv.conf

4 配网最小化流程梳理

  • 配置wpa_test.conf,例如:
sh 复制代码
ctrl_interface=/var/run/wpa_supplicant
network={
    ssid="hello"
    psk="87654321"    
}
  • 使用wap_supplicant配网:
sh 复制代码
wpa_supplicant -B -i mlan0 -c wpa_test.conf
  • 使用udhcpc分配IP:
sh 复制代码
udhcpc -i mlan0

5 总结

本篇介绍了使用wpa_supplicant工具的命令行方式,给嵌入式Linux开发板连接wifi,然后使用wpa_cli工具来查看连接状态,最后使用udhcpc工具给设备分配IP地址。

相关推荐
北京盛世宏博2 小时前
边缘计算赋能!机房机柜微环境温湿度快速响应控制方案
运维·服务器·网络
老蒋新思维3 小时前
创客匠人深度洞察:创始人 IP 打造的非线性增长模型 —— 知识变现的下一个十年红利
大数据·网络·人工智能·tcp/ip·重构·数据挖掘·创客匠人
北京耐用通信3 小时前
协议转换的‘魔法转换器’!耐达讯自动化Ethernet/IP转Devicenet如何让工业机器人‘听懂’不同咒语?”
网络·人工智能·科技·网络协议·机器人·自动化·信息与通信
日更嵌入式的打工仔3 小时前
EtherCAT 主站2
网络·ethercat
飞Link3 小时前
【轻量拓展区】网络 QoS 与带宽、延迟、抖动:AI 推理的性能瓶颈
开发语言·网络·人工智能
真正的醒悟3 小时前
图解网络22
服务器·网络·php
zhouyunjian4 小时前
11、一文详解CompletableFuture:来源、定义、方法、与场景使用分析
java·网络·spring boot
2501_941982054 小时前
系统集成与生态建设:将企业微信 RPA 自动化能力融入现有平台
大数据·网络
CAir25 小时前
一问读懂并了解HTTP代理的基本原理
网络·网络协议·http·代理