iw 是 Linux 下基于 nl80211 内核接口的现代无线网卡管理工具 ,全面替代已弃用的
iwconfig,支持 802.11n/ac/ax 等新特性,是当前主流发行版的标准无线 CLI 工具。
一、核心定位与依赖
定位:查询 / 配置 Wi‑Fi 设备、扫描网络、管理接口、设置功率 / 信道 / 模式、监管域等。
底层 :基于 netlink 与 nl80211 (内核无线子系统新接口),依赖
libnl库。适用:现代内核(≥3.0)与主流无线驱动(ath9k、iwlwifi、mt76 等)。
安装 (Debian/Ubuntu):
sudo apt update && sudo apt install iw
二、基础命令(最常用)
1. 查看设备与能力
iw list # 列出所有无线 phy 及其完整能力(频段、速率、模式、信道等) iw dev # 列出当前无线接口(如 wlan0、phy0) iw dev wlan0 info # 查看 wlan0 接口详情2. 扫描 Wi‑Fi
iw dev wlan0 scan # 主动扫描(输出 SSID、信号、信道、加密、BSSID) iw dev wlan0 scan passive # 被动扫描(不发探测帧) iw dev wlan0 scan ssid "MyWiFi" # 仅扫描指定 SSID3. 连接与断开
# 连接开放网络 iw dev wlan0 connect "OpenWiFi" # 连接 WEP(需密钥) iw dev wlan0 connect "WEPNet" key 0:1234567890 # 断开 iw dev wlan0 disconnect # 查看连接状态 iw dev wlan0 link注:WPA/WPA2 需配合
wpa_supplicant,iw本身不处理 802.1X 认证。4. 接口模式管理(关键)
支持模式:managed(默认)、monitor、ibss(adhoc)、mesh、ap、wds。
# 切换为 monitor(抓包/渗透常用,需先 down 接口) sudo ip link set wlan0 down sudo iw dev wlan0 set type monitor sudo ip link set wlan0 up # 切回 managed sudo ip link set wlan0 down sudo iw dev wlan0 set type managed sudo ip link set wlan0 up # 创建新 monitor 接口(不影响原有 wlan0) sudo iw phy phy0 interface add mon0 type monitor5. 功率、信道、速率
# 设置发射功率(dBm,如 20dBm) iw dev wlan0 set txpower fixed 20 # 查看当前功率 iw dev wlan0 info | grep txpower # 设置信道(需先 disconnect) iw dev wlan0 set channel 6 # 2.4G 信道 6 iw dev wlan0 set freq 5180 # 5G 5180MHz(信道 36) # 设置速率 iw dev wlan0 set bitrates legacy-2.4 12 18 24 # 仅用指定 802.11b/g 速率6. 监管域(国家 / 信道合规)
iw reg get # 查看当前监管域(如 CN、US) iw reg set CN # 设置为中国(合规信道/功率)7. AP 与站点信息
# AP 模式下:查看连接的客户端 iw dev wlan0 station dump # 查看信道占用/干扰统计 iw phy phy0 survey dump
三、与 iwconfig 对比(为什么用 iw)
特性 iw iwconfig 内核接口 nl80211(现代) Wireless Extensions(已弃用) 新特性 802.11n/ac/ax、MIMO、HT/VHT、monitor 增强 仅支持 802.11a/b/g 接口类型 managed/monitor/ibss/mesh/ap/wds 仅 managed/monitor/ibss 扫描 主动 / 被动、SSID 过滤、JSON 输出 基础扫描 功率 / 信道 精细控制、支持 5GHz 有限、5GHz 支持差 状态 完整链路 / 信号 / 速率 / 重传 简略 维护 活跃开发 停止维护
四、典型场景示例
1. 无线抓包(monitor 模式)
sudo ip link set wlan0 down sudo iw dev wlan0 set type monitor sudo ip link set wlan0 up sudo tcpdump -i wlan0 -w wifi.pcap # 抓包2. 快速排查连接问题
iw dev wlan0 link # 看是否关联、信号、速率 iw dev wlan0 station dump # 看重传、丢包 iw phy phy0 survey dump # 看信道干扰3. 5GHz 强制连接
iw dev wlan0 connect "5GWiFi" freq 5180 # 强制 5GHz 信道 36
五、帮助与进阶
iw help # 总帮助 iw dev help # 接口子命令帮助 man iw # 完整手册
更多待补充。
iw和wpa_cli
iw 管底层无线硬件 ,wpa_cli 管 Wi‑Fi 认证加密,它们分工完全不一样。
一句话总结
- iw :控制无线网卡本身(信道、频率、模式、扫描、功率、接口)
- wpa_cli :控制 wpa_supplicant(连接、认证、WPA/WPA2/WPA3、漫游、配置)
核心区别(一看就懂)
1. 层级不同
iw
- 直接跟 内核 nl80211 通信
- 操作 物理层 + 数据链路层
- 只管 "无线信号" 这件事
wpa_cli
- 跟用户态进程 wpa_supplicant 通信
- 管 认证、加密、连接逻辑
- 不管硬件,只管 "怎么连上加密 Wi‑Fi"
2. 能做什么、不能做什么
✅ iw 能做,wpa_cli 做不了
- 查看网卡支持的频段、信道、MIMO、HT/VHT
- 切换 monitor / ap / managed 模式
- 设置发射功率、信道、频率
- 扫描(底层扫描)
- 查看连接信号、速率、重传
- 创建虚拟网口(mon0、ap0)
iw 不能做:
- 连 WPA/WPA2/WPA3 加密 Wi‑Fi
- 输密码、做 802.1X 认证
- 保存 Wi‑Fi 配置
- 自动漫游
✅ wpa_cli 能做,iw 做不了
- 连接 WPA/WPA2/WPA3/802.1X 网络
- 输入、保存密码
- 自动重连、漫游
- 查看已保存的网络列表
- 控制 wpa_supplicant 整个连接逻辑
wpa_cli 不能做:
- 改网卡模式(monitor 不行)
- 改信道、功率
- 看硬件能力
- 操作底层无线 phy
3. 实际使用场景对比
你想:
连家里普通 Wi‑Fi(带密码) → 用 wpa_cli / NetworkManageriw 做不到,因为不处理加密。
开抓包、开 monitor 模式 → 必须用 iwwpa_cli 管不了硬件模式。
看信号强度、速率、BSSID → iw dev wlan0 link 最准确
看 Wi‑Fi 连接是否认证成功 → wpa_cli -i wlan0 status
超简记忆口诀
- iw = 无线硬件控制器
- wpa_cli = Wi‑Fi 认证连接器
真实工作流程(你就彻底懂了)
iw让网卡进入 managed 模式wpa_supplicant加载驱动wpa_cli发命令:连接 SSID + 密码- 内核底层用
iw对应的逻辑去扫描、关联 APwpa_supplicant做 WPA 握手、加密- 连接成功
二者都能扫描周边网络呀两者确实都能扫描 ,但扫描的目的、内容、层级、用途完全不一样。我用最直白、最本质的方式给你讲清楚:
核心一句话
- iw scan:扫底层无线信号(硬件层面)
- wpa_cli scan:扫给 wpa_supplicant 自己用的(连接层面)
1. 扫描出来的东西不一样
iw dev wlan0 scan
真正的底层全量扫描
- 能看到:
- SSID
- BSSID
- 信号强度
- 信道 / 频率
- 带宽(20/40/80MHz)
- 加密方式(WPA2, WPA3, OWE, etc)
- HT/VHT 支持
- 隐藏网络也能扫到
- 所有 AP 原始信息
iw 扫描不依赖任何连接管理,就是网卡自己扫空气。
wpa_cli scan + scan_results
只扫 wpa_supplicant 需要的信息
- 输出更简洁
- 主要给连接 Wi‑Fi用
- 依赖 wpa_supplicant 运行
- 结果会被 wpa_supplicant 缓存、管理
它本质是让 wpa_supplicant 去调用底层扫描,然后返回给你。
2. 谁在真正干活?
永远是内核 + 网卡硬件在扫描。
iw:直接让网卡扫 → 直接返回原始数据wpa_cli:告诉 wpa_supplicant → wpa_supplicant 再让网卡扫 → 返回精简结果所以:iw 是直接操作硬件扫描 wpa_cli 是让连接管理器帮你扫
3. 什么时候用哪个扫描?
用 iw scan:
- 你要调试无线
- 看信号、信道、带宽、干扰
- 开 monitor、抓包、分析无线环境
- 排查驱动 / 硬件问题
- 想看最完整、最原始的信息
用 wpa_cli scan:
- 你只想连 Wi‑Fi
- 看周围能连哪些 AP
- 配合
connect直接用- 不想关心底层细节
4. 最精炼总结(你记这个就够)
- iw scan = 无线工程师用的底层扫描
- wpa_cli scan = 普通用户连 Wi‑Fi 用的扫描
5. 再回到你最初的问题:
既然都能扫,那iw 和 wpa_cli 真正区别是什么?
- iw:管无线硬件(模式、信道、功率、抓包、底层扫描)
- wpa_cli:管 Wi‑Fi 连接(密码、认证、WPA、漫游、连接管理)
wpa_supplicant 会调用iw吗?不会!wpa_supplicant 绝对不会直接调用 iw 命令!
它们俩不是调用与被调用 的关系,而是兄弟 / 平级关系。
核心真相(一定要看懂)
- iw 和 wpa_supplicant 是两个独立的应用程序
- 它们都不互相调用
- 它们共同直接对接内核的同一个接口:nl80211
那为什么它们功能看起来重叠?
因为它们操作同一个内核底层,所以:
- iw 能扫描
- wpa_supplicant 也能扫描
- 但它们各自直接跟内核通信,不经过对方
最容易混淆的点澄清
很多人以为:
wpa_supplicant -> 调用 iw -> 操作网卡错!大错特错!
真实流程:
wpa_supplicant -> 直接发 nl80211 命令 -> 内核 -> 网卡
网卡自己咋实现扫描的?Wi‑Fi 扫描不是 iw 做的,不是 wpa_supplicant 做的,是「网卡硬件 + 驱动 + 内核」一起做的。
我从头给你捋,你一下就通透。
1. 先明确:谁真正在 "扫空气"?
只有一个东西能扫空气:无线网卡的硬件(射频 / 基带)
- iw:只是发指令的人
- wpa_supplicant:也是发指令的人
- 内核:转发指令
- 驱动:翻译指令
- 网卡硬件:真正去发帧、收帧、扫描
2. 一次标准的 802.11 扫描到底干了啥?
扫描本质就两件事:发 Probe Request → 收 Probe Response
步骤 1:网卡切换信道
网卡会逐个信道听:1 → 2 → 3 → ... → 13(2.4G)36 → 40 → 44 → ...(5G)
每个信道停留几十毫秒。
步骤 2:发探测帧(Probe Request)
网卡在当前信道广播一个帧:
有没有 AP?我在找网络。
步骤 3:收集应答(Probe Response)
周围的 AP 收到后,会回复:
- SSID
- BSSID
- 信号强度
- 信道
- 加密方式
- 支持速率
- 带宽等
步骤 4:网卡把结果丢给驱动
硬件把收到的所有帧打包 → 交给驱动
步骤 5:驱动 → 内核 nl80211
内核把结果整理好,存在内核里。
3. 那 iw /wpa_supplicant 干什么?
它们只做一件事:
给内核发一条消息:"请让网卡扫描,然后把结果给我"
- iw 发:
NL80211_CMD_TRIGGER_SCAN- wpa_supplicant 也发:
NL80211_CMD_TRIGGER_SCAN内核收到后,指挥驱动和硬件去扫。
扫完后:
- iw 用
NL80211_CMD_GET_SCAN拿结果- wpa_supplicant 也用
NL80211_CMD_GET_SCAN拿结果
4. 超清晰结构图(一定要看懂)
【应用层】 iw wpa_supplicant ↓ ↓ 【netlink + nl80211 系统调用】 ↓ ↓ 【内核无线子系统】 ↓ 【无线驱动(ath9k / iwlwifi / mt76 等)】 ↓ 【无线网卡硬件(真正发帧、收帧、扫描)】plaintext
移植iw的接口
不调用命令行,不调用 system (),而是把 iw 当作一个库,调用它的函数接口
✅ 答案:能!而且官方就是这么设计的! iw 源码本身已经把功能拆成了独立 C 函数,你完全可以:
- 抽取 iw 核心代码
- 编译进你的项目
- 直接调用它的函数 (比如
do_scan()、set_type()、get_link())
我先给你吃定心丸
你现在的想法:
我不想调用命令行,我想像调用库一样调用 iw 的功能
完全正确!
嵌入式、OpenWrt、厂商 SDK 大量这么干!
那到底怎么 "移植 iw 接口"?
我用最简单、最落地的方式讲:
iw 源码结构 = 两部分
- 命令行解析(main.c 里的) → 你不要
- 真正功能函数(核心接口) → 你全部可以直接调用
iw 提供的可直接调用接口(你要的就是这些)
这些都是纯 C 函数,没有命令行耦合,你可以直接在代码里调用:
// 扫描 int do_scan(struct nl80211_state *state, int argc, char **argv); // 获取扫描结果 int get_scan_results(struct nl80211_state *state, int argc, char **argv); // 设置网卡模式 (monitor / ap / managed) int set_type(struct nl80211_state *state, int argc, char **argv); // 设置信道 int set_channel(struct nl80211_state *state, int argc, char **argv); // 获取连接状态 int get_link(struct nl80211_state *state, int argc, char **argv); // 设置发射功率 int set_txpower(struct nl80211_state *state, int argc, char **argv);这些就是 iw 的接口 !你完全可以直接调用。
正确移植方法(3 步)
1. 把 iw 源码里的核心文件加入你的项目
不需要全部,只需要核心:
nl80211.c scan.c info.c util.c interface.c2. 初始化 nl80211 状态
struct nl802111_state state; nl80211_init(&state);3. 直接调用 iw 功能函数
// 示例:触发扫描(等同于 iw scan) char *argv[] = {"wlan0", "scan"}; do_scan(&state, 2, argv);
这就是你要的:
不跑命令行,直接调用 iw 内部函数接口
完全满足你说的:移植 iw 的接口来使用