一个面向 Rust 的网络工具库,主要提供以下能力:
- 枚举本机物理网卡与基础网络状态
- 获取本机 IP、MAC、默认联网网卡等信息
- 监听网卡上下线变化
- 在 Linux 下启用/禁用网卡
- 通过可选
feature提供 Wi-Fi 管理能力 - 在 Linux 下基于
wpa_supplicant管理无线网络
这个项目目前更偏向库(library)而不是独立命令行程序。
默认特性下即可使用:
- 获取网卡列表:
utils::ifaces - 获取原始网卡信息:
utils::get_source_ifaces - 获取本机 IP:
utils::get_local_ip/utils::get_local_ips - 获取 MAC 地址:
utils::get_mac_addr/utils::get_physical_mac - 判断当前是否联网:
utils::check_online/utils::is_online - 获取局域网连接与在线状态:
utils::lan_is_ok - 监听网卡事件:
utils::listen_change - Linux 下启用/禁用网卡:
utils::enable
启用 wifi feature 后可使用统一的 Wi-Fi trait 和数据结构:
wifi::IWifiwifi::ScanResultwifi::NetworkListResultwifi::Status
启用 wpa feature 且运行在 Linux 时,可通过 Unix Domain Socket 与 wpa_supplicant 通信:
- 自动发现无线网卡并初始化:
wifi::linux::WpaSupplicant::auto_setup - 指定网卡初始化:
wifi::linux::WpaSupplicant::new - 扫描附近 Wi-Fi
- 查看已保存网络
- 连接 / 断开 / 重连 Wi-Fi
- 选择指定 network id
- 保存或移除
wpa_supplicant配置
- 通用网卡信息读取依赖
netdev、if-watch,核心逻辑以跨平台接口为主 linux模块仅在target_os = "linux"下编译wpa模块仅在Linux + feature = "wpa"下可用- 当前 Wi-Fi 管理实现实际依赖 Linux 的
wpa_supplicantsocket,Windows 下未实现对应控制逻辑
Cargo.toml 中当前提供两个可选 feature:
[features]
default = []
wifi = ["async-trait"]
wpa = ["libc", "config", "tempfile"]建议按场景启用:
- 只使用基础网络能力:不需要额外 feature
- 只依赖 Wi-Fi trait / DTO:
wifi - 使用 Linux
wpa_supplicant控制能力:wifi,wpa
示例:
cargo add network如果以本地路径依赖:
[dependencies]
network = { path = ".", features = ["wifi", "wpa"] }当你使用 wpa 能力时,需要保证:
- 系统为 Linux
- 已安装并启动
wpa_supplicant - 存在对应网卡的控制 socket,例如
/var/run/wpa_supplicant/wlan0 - 当前进程对该 socket 具有访问权限
项目内部默认会尝试连接类似下面的路径:
/var/run/wpa_supplicant/<iface>
use network::utils;
fn main() {
let ifaces = utils::ifaces();
for iface in ifaces {
println!(
"{} {} wifi={} up={} ipv4={}",
iface.name, iface.friendly_name, iface.is_wifi, iface.is_up, iface.ipv4_addr
);
}
}use network::utils;
fn main() -> anyhow::Result<()> {
let ip = utils::get_local_ip()?;
let mac = utils::get_mac_addr()?;
println!("local ip: {ip}");
println!("mac: {mac}");
Ok(())
}use network::utils;
fn on_change(is_up: bool) {
println!("network changed, is_up={is_up}");
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let _handle = utils::listen_change(on_change)?;
loop {
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
}
}#[cfg(target_os = "linux")]
#[tokio::main]
async fn main() -> anyhow::Result<()> {
network::utils::enable("eth0", true).await?;
Ok(())
}下面示例需要启用 features = ["wifi", "wpa"],并运行在 Linux。
use network::wifi::{IWifi, linux::WpaSupplicant};
fn on_wifi_event(evt: String) {
println!("wifi event: {evt}");
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wifi = WpaSupplicant::auto_setup(Some(on_wifi_event)).await?;
let status = wifi.status().await?;
println!("{status:?}");
Ok(())
}use network::wifi::{IWifi, linux::WpaSupplicant};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wifi = WpaSupplicant::auto_setup(None).await?;
let results = wifi.scan().await?;
for item in results {
println!(
"ssid={} signal={} level={} encrypted={}",
item.ssid_name,
item.signal,
item.to_level(),
item.is_encrypted
);
}
Ok(())
}use network::wifi::{IWifi, linux::WpaSupplicant};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wifi = WpaSupplicant::auto_setup(None).await?;
wifi.connect("MyWiFi".to_string(), "12345678".to_string()).await?;
Ok(())
}开放网络可传空密码:
wifi.connect("OpenWiFi".to_string(), "".to_string()).await?;use network::wifi::{IWifi, linux::WpaSupplicant};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wifi = WpaSupplicant::auto_setup(None).await?;
let networks = wifi.get_networks().await?;
for item in networks {
println!(
"id={} ssid={} connected={} disabled={}",
item.network_id,
item.ssid,
item.is_connected(),
item.is_disable()
);
}
Ok(())
}use network::wifi::{IWifi, linux::WpaSupplicant};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wifi = WpaSupplicant::auto_setup(None).await?;
let _ = wifi.select_id(0).await?;
wifi.disconnect().await?;
wifi.reconnect().await?;
wifi.remove(0).await?;
Ok(())
}表示网卡的基础信息:
index: 网卡索引name: 系统网卡名,如eth0、wlan0friendly_name: 友好名称is_wifi: 是否为无线网卡mac_addr: MAC 地址ipv4_addr: IPv4 地址ipv6_addr: IPv6 地址has_dns: 是否存在 DNS 配置cur_used: 是否为当前默认使用网卡is_up: 是否启用
ifaces: 网卡列表connected: 是否已连接网络
bissid_mac: AP 的 BSSID / MACfrequency: 频段频率signal: 信号强度(dBm)flags: 扫描标志is_encrypted: 是否加密ssid_name: Wi-Fi 名称
network_id:wpa_supplicant中的网络 IDssid: Wi-Fi 名称flags: 状态标记bssid: 关联 BSSID
- 底层网卡枚举基于
netdev - 网络变化监听基于
if-watch - 异步运行时基于
tokio - Wi-Fi 控制通过异步 channel +
wpa_supplicantsocket 完成 - 扫描结果和事件结果会经过简单封装,便于上层业务直接使用
utils::check_online()当前通过 UDP 连接114.114.114.114:53判断外网连通性,这更像“是否可以访问外部网络”的近似判断utils::ifaces()会过滤回环网卡、Docker 网卡、p2p0以及非物理网卡WpaSupplicant::auto_setup()会选择扫描到的第一个无线网卡- 使用
wpa能力时,运行权限、socket 权限和系统网络配置都会影响结果 - README 中的示例基于当前代码接口编写,如后续 API 调整请同步更新
cargo check
cargo check --features wifi
cargo check --features "wifi wpa"本项目基于 MIT License 发布。