如何获取网络设备层级结构?含无IP非管理型交换机
解决网络设备拓扑识别与非管理型交换机探测的痛点
我完全懂你遇到的这种困惑——自己写的扫描工具能轻松遍历IP、抓取MAC和主机名,但就是摸不到设备的连接层级(比如某台设备是连在有线路由器还是Wi-Fi上),连那些无IP的非管理型交换机也完全识别不出来。本来以为tracert这条路走死了,但Windows自带的Network Complete Map居然能做到,这反差确实让人挠头!
先搞懂核心差异:为什么tracert不行,而Windows的工具可以?
tracert的局限性太明显了:
- 它依赖ICMP包和TTL跳数机制,只能追踪有IP的路由设备,非管理型交换机没有IP,也不会响应ICMP,直接就被当成透明的“网线”忽略了。
- 它只能展示到单个目标的路径,没法全局识别整个局域网的设备连接关系。
而Windows的Network Complete Map是个“多面手”,它同时用了好几种底层技术:
- LLDP(链路层发现协议):现在很多非管理型交换机(尤其是新机型)都会主动发送LLDP广播帧,里面包含设备型号、端口信息;Windows会监听这些帧,直接拿到设备的连接线索。
- Windows原生网络API/WMI:通过系统接口获取本地适配器的连接细节——比如是Wi-Fi连接的哪个SSID,有线连接的端口对应的上游设备。
- ARP缓存+主动探测:结合本地ARP表获取局域网MAC,再主动发送链路层探测包(比如LLDP请求),挖出来那些没IP的设备。
给你几个可行的实现方向
1. 监听/发送LLDP帧,抓取无IP设备
用scapy这类库就能轻松实现LLDP的监听和探测,非管理型交换机只要支持LLDP,就会回应包含自身信息的帧。举个简单的Python示例:
from scapy.all import sniff, LLDPDU def process_lldp_packet(packet): if LLDPDU in packet: lldp_data = packet[LLDPDU] chassis_id = lldp_data.chassis_id.val.decode() port_id = lldp_data.port_id.val.decode() print(f"发现设备: {chassis_id} | 连接端口: {port_id}") # 替换成你的网卡名称,比如"以太网"或"WLAN" sniff(iface="你的网卡名称", prn=process_lldp_packet, filter="ether proto 0x88cc")
2. 调用Windows API获取连接层级
用pywin32库调用WMI或者MSFT_NetConnectionProfile接口,能直接拿到本地设备的连接类型(有线/Wi-Fi)、上游设备的信息。比如通过PowerShell命令(可以在代码里调用)快速获取:
Get-NetConnectionProfile | Select-Object Name, InterfaceAlias, NetworkCategory
把这些信息和你扫描到的IP/MAC关联起来,就能梳理出设备的连接层级。
3. ARP扫描+拓扑推断(针对不支持LLDP的老交换机)
如果遇到完全不发LLDP的老款非管理型交换机,只能靠间接推断:
- 先做全局域网ARP扫描,拿到所有活跃MAC。
- 分析MAC的OUI段(前3字节),判断设备类型(比如交换机厂商的OUI)。
- 然后通过“端口排查”:断开某个物理端口,看哪些设备的MAC从ARP表消失,就能推断这个端口连接了交换机,进而梳理拓扑。不过这种方式比较侵入性,适合测试环境。
最后提个关键注意点
不管用哪种方式,你的工具都需要管理员权限——监听链路层帧、调用WMI接口都需要系统级权限,不然会被系统拦截。
内容的提问来源于stack exchange,提问作者SammuelMiranda
相关产品推荐
相关产品推荐

