Whosthere 局域网发现工具技术分析
一、概述
1. 项目简介
Whosthere 是一个用 Go 语言编写的现代化局域网发现工具,提供友好的终端用户界面(TUI)。它帮助网络管理员直观地发现、探索和理解局域网中的设备,回答那个经典问题:我的网络上有哪些设备?
2. 核心特性
- 无需特权权限:完全在用户空间运行,不需要 root 或管理员权限
- 并发快速扫描:同时使用多种发现方法
- 现代化 TUI:直观的设备浏览和探索界面
- 设备信息增强:通过 OUI 查询显示设备制造商
- 集成端口扫描:可选的服务发现功能
- 守护进程模式:支持后台运行和 HTTP API
二、技术架构
1. 发现方法
Whosthere 采用多层次的网络发现策略,每种方法针对不同的设备类型和网络场景。
graph TB
A[Whosthere 扫描器] --> B[mDNS 扫描器]
A --> C[SSDP 扫描器]
A --> D[ARP 缓存扫描器]
B --> E[发现支持 mDNS 的设备<br/>如 Apple 设备、打印机]
C --> F[发现支持 SSDP 的设备<br/>如 Windows 设备、IoT 设备]
D --> G[子网扫描 + ARP 缓存读取<br/>发现所有响应的设备]
E --> H[设备列表合并]
F --> H
G --> H
H --> I[OUI 查询增强]
I --> J[显示设备制造商信息]2. 工作原理
A. mDNS 扫描器
mDNS(Multicast DNS)是局域网设备发现的重要协议。支持 mDNS 的设备会在本地网络广播服务信息。
工作原理:
- 向 224.0.0.251:5353 发送 mDNS 查询请求
- 监听响应并解析设备信息
- 常见支持设备:Apple 设备、Linux 服务器、网络打印机、智能家居设备
B. SSDP 扫描器
SSDP(Simple Service Discovery Protocol)是即插即用设备的核心协议。
工作原理:
- 向 239.255.255.250:1900 发播 M-SEARCH 消息
- 解析响应中的设备信息和服务列表
- 常见支持设备:Windows 设备、NAS、UPnP/DLNA 设备
C. ARP 缓存扫描器
这是 Whosthere 的核心技术亮点,通过巧妙的方法填充 ARP 缓存,无需特权权限。
工作原理:
sequenceDiagram
participant W as Whosthere
participant N as 网络栈
participant L as 局域网
W->>N: 遍历子网 IP 范围
loop 每个 IP 地址
W->>N: 尝试 TCP/UDP 连接
N->>L: 发送 ARP 请求
L-->>N: 返回 ARP 响应
N->>W: 连接失败(设备离线或拒绝)
end
W->>N: 读取 ARP 缓存
N-->>W: 返回所有在线设备技术亮点:
- 不需要原始套接字或 ARP 请求权限
- 通过常规网络操作触发 ARP 解析
- 操作系统自动维护 ARP 表,应用程序只需读取
- 跨平台兼容(Linux、macOS、Windows)
D. OUI 查询增强
OUI(Organizationally Unique Identifier)是 MAC 地址的前 24 位,标识设备制造商。
实现方式:
- 解析设备的 MAC 地址
- 提取前 3 字节(OUI)
- 查询 OUI 数据库获取厂商信息
- 在 TUI 中显示设备制造商
三、系统设计
1. 架构设计
graph TB
subgraph 用户界面层
TUI[Terminal User Interface]
API[HTTP API]
end
subgraph 核心引擎
Scanner[扫描管理器]
Cache[设备缓存]
Enricher[信息增强器]
end
subgraph 扫描器层
MDNS[mDNS Scanner]
SSDP[SSDP Scanner]
ARP[ARP Scanner]
end
subgraph 数据层
OUIDB[(OUI 数据库)]
Config[配置文件]
Log[日志]
end
TUI --> Scanner
API --> Scanner
Scanner --> MDNS
Scanner --> SSDP
Scanner --> ARP
MDNS --> Cache
SSDP --> Cache
ARP --> Cache
Cache --> Enricher
Enricher --> OUIDB
Scanner --> Config
Scanner --> Log2. 并发模型
Whosthere 使用 Go 的 goroutine 实现高效的并发扫描。
graph LR
A[主协程] --> B[扫描协调器]
B --> C[mDNS 协程]
B --> D[SSDP 协程]
B --> E[ARP 扫描协程池]
E --> F[Worker 1]
E --> G[Worker 2]
E --> H[Worker N]
C --> I[结果通道]
D --> I
F --> I
G --> I
H --> I
I --> J[设备聚合器]
J --> K[设备缓存]并发优势:
- 多种扫描方法并行执行
- ARP 扫描使用协程池提高效率
- 通过通道安全传递结果
- 避免竞态条件和资源冲突
四、功能详解
1. TUI 界面
A. 主界面功能
- 设备列表:显示所有发现的设备
- 实时更新:定时扫描更新设备状态
- 搜索过滤:支持正则表达式搜索
- 快速导航:vim 风格的键绑定
B. 设备详情视图
按回车键查看设备详细信息,包括:
- IP 地址和 MAC 地址
- 设备制造商(OUI 查询)
- 发现方法(mDNS/SSDP/ARP)
- 开放端口列表(可选端口扫描)
- 最后发现时间
C. 快捷键
| 快捷键 | 功能 |
|---|---|
/ | 开始正则搜索 |
k/j | 上下移动 |
g/G | 跳转到顶部/底部 |
y | 复制选中设备的 IP |
Enter | 查看设备详情 |
p | 对设备进行端口扫描 |
CTRL+t | 切换主题 |
CTRL+c | 退出程序 |
ESC | 清除搜索/返回 |
2. 守护进程模式
A. 启动守护进程
whosthere daemon --port 8080B. HTTP API
端点列表:
| 方法 | 端点 | 描述 |
|---|---|---|
| GET | /devices | 获取所有发现的设备 |
| GET | /device/{ip} | 获取特定设备的详细信息 |
| GET | /health | 健康检查 |
示例响应:
GET /devices
{
"devices": [
{
"ip": "192.168.1.100",
"mac": "00:11:22:33:44:55",
"manufacturer": "Apple, Inc.",
"last_seen": "2025-01-24T20:00:00Z",
"discovery_method": "mdns"
}
]
}3. 配置系统
A. 配置文件位置
Whosthere 按以下顺序查找配置文件:
WHOSTHERE_CONFIG环境变量指定的路径$XDG_CONFIG_HOME/whosthere/config.yaml~/.config/whosthere/config.yaml
B. 配置选项
扫描配置:
# 扫描间隔
scan_interval: 20s
# 单次扫描最大持续时间
scan_duration: 10s
# 启动画面
splash:
enabled: true
delay: 1s扫描器开关:
scanners:
mdns:
enabled: true
ssdp:
enabled: true
arp:
enabled: true端口扫描配置:
port_scanner:
timeout: 5s
tcp: [21, 22, 23, 25, 80, 443, 3389, 5432, 8080]主题配置:
theme:
name: default
# 或设置为 "custom" 使用自定义颜色
# primitive_background_color: "#000a1a"
# border_color: "#0088ff"4. 主题系统
Whosthere 内置多个主题,支持运行时切换和自定义。
内置主题:
- default:默认蓝色主题
- dracula:Dracula 配色
- gruvbox:Gruvbox 暗色主题
- monokai:Monokai 配色
- nord:Nord 冷色调主题
自定义主题:
theme:
name: custom
primitive_background_color: "#000a1a"
contrast_background_color: "#001a33"
border_color: "#0088ff"
title_color: "#00ffff"
primary_text_color: "#cceeff"
secondary_text_color: "#6699ff"五、技术实现
1. Go 语言特性应用
A. 并发控制
使用 sync.WaitGroup 管理扫描协程:
var wg sync.WaitGroup
for _, scanner := range scanners {
wg.Add(1)
go func(s Scanner) {
defer wg.Done()
s.Scan(results)
}(scanner)
}
wg.Wait()B. 通道通信
使用缓冲通道收集扫描结果:
results := make(chan Device, 100)
go func() {
for device := range results {
cache.Add(device)
}
}()C. 接口设计
扫描器接口抽象:
type Scanner interface {
Scan(ctx context.Context) ([]Device, error)
Name() string
}2. 网络编程技巧
A. mDNS 实现
conn, _ := net.ListenPacket("udp4", ":0")
dst, _ := net.ResolveUDPAddr("udp4", "224.0.0.251:5353")
conn.WriteTo(query, dst)B. ARP 缓存读取
Linux:/proc/net/arp
macOS:sysctl net.arp
Windows:GetIpNetTable API
3. 跨平台兼容性
graph TB
A[Whosthere 代码] --> B{平台检测}
B -->|Linux| C[Linux 实现]
B -->|macOS| D[macOS 实现]
B -->|Windows| E[Windows 实现]
C --> F[/proc/net/arp]
D --> G[sysctl net.arp]
E --> H[GetIpNetTable API]
F --> I[统一 ARP 接口]
G --> I
H --> I六、使用场景
1. 网络管理
- 快速发现局域网中的所有设备
- 识别未授权的设备接入
- 网络设备清单管理
2. 安全审计
- 检测网络中的异常设备
- 扫描开放端口识别潜在风险
- 定期网络设备清点
3. 开发调试
- 测试设备发现功能
- 模拟 IoT 设备扫描
- 集成到自动化工具链(通过 HTTP API)
4. 家庭网络
- 查看智能家居设备
- 识别占用带宽的设备
- 网络故障排查
七、安装与使用
1. 安装方法
A. Homebrew(macOS/Linux)
brew tap ramonvermeulen/whosthere
brew install whosthereB. Go 安装
go install github.com/ramonvermeulen/whosthere@latestC. 从源码构建
git clone https://github.com/ramonvermeulen/whosthere.git
cd whosthere
make build2. 基本使用
A. 交互式扫描
whosthereB. 守护进程模式
whosthere daemon --port 8080C. 指定网络接口
# config.yaml
network_interface: eth03. 环境变量
| 变量 | 描述 |
|---|---|
WHOSTHERE_CONFIG | 配置文件路径 |
WHOSTHERE_LOG | 日志级别(debug/info/warn/error) |
八、技术亮点
1. 无特权扫描
通过 ARP 缓存技巧实现无需 root 权限的网络发现,这是该项目最大的技术创新。
2. 多协议融合
整合 mDNS、SSDP、ARP 三种发现机制,覆盖几乎所有常见网络设备。
3. 现代化 TUI
提供流畅的终端用户界面,支持主题切换、搜索过滤、快捷键操作。
4. API 集成
守护进程模式提供 HTTP API,方便集成到其他工具和自动化流程。
5. Go 语言优势
利用 Go 的并发特性、跨平台编译能力和简洁语法,构建高性能网络工具。
九、局限性
1. 平台支持
目前主要支持 Linux 和 macOS,Windows 支持尚不完善。
2. 网络限制
- 只能发现本地子网的设备
- 无法跨越路由器
- 某些设备可能不响应任何发现协议
3. 端口扫描权限
虽然基础扫描无需特权,但端口扫描功能在某些系统可能需要特殊权限。
4. 粘贴板功能
Linux Wayland 环境下粘贴板功能需要 XWayland 支持。
十、总结
Whosthere 是一个设计精良的局域网发现工具,通过创新的 ARP 缓存扫描技术实现了无特权的设备发现。其多协议融合、现代化 TUI、守护进程模式等特性,使其成为网络管理员的得力助手。该项目充分展示了 Go 语言在系统工具开发中的优势,以及通过巧妙设计解决技术难题的能力。
对于需要在局域网中快速发现和管理设备的场景,Whosthere 提供了一个优雅、高效、跨平台的解决方案。
参考资料
- Whosthere GitHub 仓库 - 官方项目