基于Raspbian的树莓派:Python获取交换机IP及VLAN信息可行性问询
嘿,作为Python新手能写出获取自身IP的代码已经很棒啦!不过要获取交换机的IP和VLAN信息,可不是靠普通的socket就能搞定的——这得用到交换机的网络管理协议,比如LLDP或者SNMP。下面我给你详细讲讲可行的方法,都是适合新手上手的:
先明确核心逻辑:为什么你的现有代码做不到?
你当前的代码是通过UDP连接外部IP,获取树莓派自身的网卡IP,这和交换机的信息完全不相关。交换机的管理信息(比如自身IP、端口VLAN)不会主动通过普通IP数据包发送,得用专门的协议去主动捕获或查询。
方法1:用LLDP捕获交换机信息(推荐新手先试这个)
LLDP(链路层发现协议)是大多数交换机默认开启的协议,会定期向局域网发送包含自身身份、管理IP、端口关联VLAN等信息的数据包。我们可以用Python的scapy库捕获并解析这些包。
步骤1:安装依赖
sudo pip3 install scapy
步骤2:示例代码
from scapy.all import sniff, LLDP def analyze_lldp_packet(packet): if packet.haslayer(LLDP): lldp = packet[LLDP] # 提取交换机名称 switch_name = lldp.chassis_id.id.decode('utf-8') # 提取交换机管理IP switch_ip = lldp.mgmt_addr.addr.decode('utf-8') if hasattr(lldp, 'mgmt_addr') else "未获取到管理IP" # 提取端口VLAN(部分交换机在LLDP的扩展TLV里包含VLAN) port_vlan = "未获取到VLAN信息" for tlv in lldp.tlvs: if hasattr(tlv, 'vlan_id'): port_vlan = f"VLAN ID: {tlv.vlan_id}" print("=== 交换机信息 ===") print(f"名称: {switch_name}") print(f"管理IP: {switch_ip}") print(f"当前端口VLAN: {port_vlan}") # 监听网卡上的LLDP数据包(协议号0x88cc),捕获1个就停止 sniff(prn=analyze_lldp_packet, filter="ether proto 0x88cc", store=0, count=1)
注意事项
- 运行代码需要root权限,所以执行时要加
sudo(比如sudo python3 lldp_scan.py) - 如果交换机没开启LLDP,需要登录交换机后台手动开启(一般叫“LLDP enable”)
方法2:用SNMP查询交换机详细信息(适合需要精准数据的场景)
SNMP(简单网络管理协议)是专门用于查询网络设备状态的协议,只要交换机开启了SNMP,就能查询到几乎所有管理信息(包括端口VLAN、交换机IP、端口流量等)。
步骤1:安装依赖
sudo pip3 install pysnmp
步骤2:示例代码
from pysnmp.hlapi import * # 先填交换机的管理IP(可以通过LLDP先获取到) switch_mgmt_ip = "192.168.1.254" # 交换机的SNMP社区字符串(需要在交换机后台配置,默认可能是public) snmp_community = "public" # 1. 查询交换机系统名称 errorIndication, errorStatus, errorIndex, varBinds = next( getCmd(SnmpEngine(), CommunityData(snmp_community), UdpTransportTarget((switch_mgmt_ip, 161)), ContextData(), ObjectType(ObjectIdentity('1.3.6.1.2.1.1.5.0'))) ) if not errorIndication and not errorStatus: print(f"交换机名称: {varBinds[0][1].prettyPrint()}") # 2. 查询指定端口的VLAN(这里假设端口索引是1,需要根据实际端口调整) target_port_index = 1 errorIndication, errorStatus, errorIndex, varBinds = next( getCmd(SnmpEngine(), CommunityData(snmp_community), UdpTransportTarget((switch_mgmt_ip, 161)), ContextData(), ObjectType(ObjectIdentity(f'1.3.6.1.2.1.17.7.1.4.2.1.2.{target_port_index}'))) ) if not errorIndication and not errorStatus: print(f"端口{target_port_index}所属VLAN: {varBinds[0][1].prettyPrint()}")
注意事项
- 必须在交换机后台开启SNMP服务,并配置允许树莓派IP访问,以及正确的社区字符串
- 不同厂商的交换机SNMP OID(查询路径)可能略有不同,如果上面的VLAN OID无效,可以查对应厂商的MIB文档调整
内容的提问来源于stack exchange,提问作者lee-ds




