Linux之virt_wifi驱动
Linux之virt_wifi驱动
简介
A fake implementation of cfg80211_ops that can be tacked on to an ethernet net_device to make it appear as a wireless connection.
一种可附加到以太网网络设备上的虚假的 cfg80211_ops 实现,使其看起来像无线连接。
该模块通过实现 cfg80211
接口和网络设备操作,模拟了一个完整的无线网络接口,使其对上层表现为真实的 WiFi 设备,支持扫描、连接、数据传输等操作。
主要功能
其主要功能是:
- 模拟无线硬件: 在无需物理无线设备的情况下,提供虚拟的无线接口,在纯软件环境中模拟无线网络行为。
- 支持测试和容器化: 允许在虚拟环境中测试无线功能,或为容器提供隔离的无线网络接口。
- 协议栈兼容性: 通过
mac80211
框架提供标准的无线设备接口,支持标准工具(如iw
、wpa_supplicant
)操作。
典型应用场景
- 开发与测试
- 驱动开发:在无物理硬件时模拟无线设备,测试 mac80211 驱动逻辑。
- 协议测试:验证无线协议(如 802.11 协议)的实现。
- 容器化网络
- Docker/Kubernetes:为容器分配独立的虚拟无线接口,实现网络隔离。
- 虚拟化环境:在虚拟机中提供无线功能,无需物理硬件。
- 网络监控
- 虚拟监控接口:创建 mon0 接口用于无线流量捕获(如 Wireshark 分析)。
主要代码
它依赖于 mac80211
子系统。
代码目录:drivers/net/wireless/virt_wifi.c
比较新的内核已经将virt_wifi驱动移到了virtual
目录,和mac80211_hwsim
驱动放在了一起。drivers/net/wireless/virtual/virt_wifi.c
扩展:mac80211_hwsim驱动
以前记录的mac80211_hwsim
驱动简单介绍:
https://z-dd.online/2024/11/12/Linux%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9FWLAN%E6%8E%A5%E5%8F%A3%E5%B9%B6%E6%B5%8B%E8%AF%95/
代码详细分析
以下是DeepSeek
对 virt_wifi.c
代码的详细分析,涵盖其核心功能、实现逻辑和关键模块:
1. 模块概述
- 目的:在以太网设备上模拟无线网络接口(如
wlan0
),使其对上层表现为真实的 WiFi 设备,支持扫描、连接、数据传输等操作。 - 适用场景:测试网络协议栈、容器/虚拟机网络隔离、无物理 WiFi 硬件的开发环境。
2. 核心数据结构
(1) virt_wifi_wiphy_priv
- 作用:存储与
wiphy
(无线硬件抽象)相关的私有数据。 - 成员:
scan_request
:当前扫描请求。scan_result
:延迟任务,模拟扫描结果。being_deleted
:标记wiphy
是否正在被销毁。
(2) virt_wifi_netdev_priv
- 作用:存储与虚拟网络设备相关的状态。
- 成员:
lowerdev
:底层以太网设备(真实数据传输的载体)。upperdev
:虚拟无线设备(如wlan0
)。is_connected
:标记是否连接到虚拟 AP。tx_packets
/tx_failed
:统计发送数据包数量。
3. 关键功能实现
(1) 模拟无线频段与速率
- 定义频段:
- 2.4GHz 和 5GHz 频段(
band_2ghz
和band_5ghz
)。 - 支持 HT(802.11n)和 VHT(802.11ac)能力,包含 MCS 索引和信道宽度。
- 2.4GHz 和 5GHz 频段(
- 虚拟 BSS:通过
virt_wifi_inform_bss
生成固定 BSS(SSIDVirtWifi
,BSSIDfake_router_bssid
)。
(2) 扫描流程
- 触发扫描:用户空间发起扫描请求(如
iw dev wlan0 scan
)。 - 模拟扫描结果:
- 延迟 2 秒后调用
virt_wifi_scan_result
。 - 通过
cfg80211_inform_bss
上报虚拟 BSS。 - 调用
cfg80211_scan_done
通知扫描完成。
- 延迟 2 秒后调用
(3) 连接流程
- 发起连接:用户空间指定 SSID 和 BSSID(需匹配
VIRT_WIFI_SSID
和fake_router_bssid
)。 - 延迟连接完成:2 秒后调用
virt_wifi_connect_complete
。- 验证 SSID/BSSID 匹配性。
- 通过
cfg80211_connect_result
上报连接结果。 - 设置
netif_carrier_on
激活接口。
(4) 数据传输
- 发送路径(
virt_wifi_start_xmit
):- 若未连接,丢弃数据包并统计失败。
- 若已连接,将数据包转发到底层以太网设备(
lowerdev
)。
- 接收路径(
virt_wifi_rx_handler
):- 拦截底层设备的数据包。
- 若已连接,修改
skb->dev
为虚拟设备,模拟无线接收。
4. 内核接口与交互
(1) cfg80211_ops
实现
- 核心操作:
scan
:处理扫描请求。connect
/disconnect
:处理连接与断开。get_station
/dump_station
:返回模拟的站点统计信息(如信号强度、速率)。
(2) 网络设备操作
- **
virt_wifi_ops
**:定义虚拟设备的ndo_start_xmit
(发送)、ndo_open
(打开)、ndo_stop
(关闭)等方法。 - **
rtnl_link_ops
**:注册虚拟网络设备的创建(newlink
)和销毁(dellink
)逻辑。
5. 模块初始化与清理
- 初始化(
virt_wifi_init_module
):- 生成随机 MAC 地址作为虚拟 AP 的 BSSID。
- 注册网络设备通知器(
virt_wifi_notifier
)。 - 创建公共
wiphy
设备并注册rtnl_link_ops
。
- 清理(
virt_wifi_cleanup_module
):- 注销网络设备链接和
wiphy
设备。 - 取消所有未完成的扫描和连接任务。
- 注销网络设备链接和
6. 关键代码片段解析
(1) 虚拟 BSS 上报
static void virt_wifi_inform_bss(struct wiphy *wiphy) {
// 生成固定 BSS 信息(SSID: VirtWifi,信号强度 -50dBm)
cfg80211_inform_bss(wiphy, &channel_5ghz, CFG80211_BSS_FTYPE_PRESP,
fake_router_bssid, tsf, WLAN_CAPABILITY_ESS, 0,
(void *)&ssid, sizeof(ssid), DBM_TO_MBM(-50), GFP_KERNEL);
}
(2) 连接结果验证
static void virt_wifi_connect_complete(struct work_struct *work) {
// 检查 SSID 和 BSSID 是否匹配预设值
bool right_ssid = (priv->connect_requested_ssid_len == VIRT_WIFI_SSID_LEN) &&
!memcmp(priv->connect_requested_ssid, VIRT_WIFI_SSID,
priv->connect_requested_ssid_len);
bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid);
if (!right_ssid || !right_addr)
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
else
priv->is_connected = true;
}
(3) 数据包接收处理
static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb) {
// 仅当连接成功时,将数据包传递给虚拟接口
if (!priv->is_connected)
return RX_HANDLER_PASS;
skb->dev = priv->upperdev;
return RX_HANDLER_ANOTHER;
}
7. 潜在限制与改进方向
(1) 限制
- 固定 SSID/BSSID:只能连接到预设的
VirtWifi
网络。 - 信号模拟简单:信号强度和速率固定,无法动态调整。
- 依赖底层设备:实际数据传输依赖以太网设备(
lowerdev
)。
(2) 改进方向
- 动态配置:允许用户空间设置 SSID/BSSID 和信号参数。
- 多虚拟 AP 支持:扩展以支持多个虚拟 AP 的扫描和连接。
- 增强加密支持:模拟 WPA2/WPA3 握手流程。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DD'Notes!
评论