import sys from pysnmp.hlapi import * import pysnmp.proto.rfc1902 as rfc1902 def snmp_walk(host, oid, format="str", strip_prefix=True, community="zabbix"): res = {} # 使用正确的 nextCmd 函数 for errorIndication, errorStatus, errorIndex, varBinds in nextCmd( SnmpEngine(), CommunityData(community), UdpTransportTarget((host, 161), timeout=4.0, retries=3), ContextData(), ObjectType(ObjectIdentity(oid)), lookupMib=False, lexicographicMode=False, ): if errorIndication: raise ConnectionError( f'SNMP error: "{str(errorIndication)}". Status={str(errorStatus)}' ) elif errorStatus: raise ConnectionError( f'SNMP error: "{str(errorStatus)}" at index {str(errorIndex)}' ) else: for varBind in varBinds: oid_str = str(varBind[0]) value = varBind[1] # 如果指定了去除前缀 if strip_prefix: oid_str = oid_str.replace(oid, "", 1).lstrip(".") # 根据格式处理值 if format == "hex": res[oid_str] = value.asOctets().hex() elif format == "str": res[oid_str] = str(value) else: res[oid_str] = value return res def split_numbers(oid): return [int(x) for x in oid.split(".")] def read_ipv4_from_oid_tail(oid, with_len=True): parts = [int(x) for x in oid.split(".")] if with_len: assert parts[-5] == 4 # number of elements return ".".join([str(x) for x in parts[-4:]]) def read_bid_from_oid_tail(oid, with_len=True): parts = [int(x) for x in oid.split(".")] if with_len: assert parts[-5] == 1 # number of elements return ".".join([str(x) for x in parts[-1:]]) def read_mac_from_oid_tail(oid, with_len=True): parts = [int(x) for x in oid.split(".")] if with_len: assert parts[-5] == 6 # number of elements return ".".join([str(x) for x in parts[-6:]]) def machex(getvar): macs = getvar.split(".") i = 0 ma = [] for x in range(0, 6): maca = macs[i] if len(maca) == 1: a = hex(int(maca)).replace("x", "") else: a = hex(int(maca))[2:] ma.append(a) i = i + 1 return ma[0] + ":" + ma[1] + ":" + ma[2] + ":" + ma[3] + ":" + ma[4] + ":" + ma[5] if __name__ == "__main__": # Read ARP table print(" - Reading device ARP table...", file=sys.stderr) atPhysAddress = snmp_walk( "192.168.0.112", "1.3.6.1.2.1.3.1.1.2", "hex", community="zabbix" ) for oid, mac in atPhysAddress.items(): ip = read_ipv4_from_oid_tail(oid, with_len=False) print(ip) print(mac) # Read dot1dBasePortIfIndex table print(" - Reading device dot1dBasePortIfIndex table...", file=sys.stderr) dot1dBasePortIfIndex = snmp_walk( "192.168.0.112", "1.3.6.1.2.1.17.1.4.1.2", "int", community="zabbix" ) dot1dBasePort = {} for bid, id in dot1dBasePortIfIndex.items(): ip = read_ipv4_from_oid_tail(bid, with_len=False) print("bid=", bid) print("id=", id) dot1dBasePort[bid] = str(id) print(dot1dBasePort) # Read ifDescr table print(" - Reading device ifDescr table...", file=sys.stderr) ifDescr = snmp_walk( "192.168.0.112", "1.3.6.1.2.1.2.2.1.2", "str", community="zabbix" ) Descr = {} for id, desc in ifDescr.items(): ip = read_ipv4_from_oid_tail(id, with_len=False) print("id=", id) print("desc=", desc) Descr[id] = desc print(Descr) dot1dBasePortDescr = {} for key in dot1dBasePort.keys(): dot1dBasePortDescr[key] = Descr[dot1dBasePort[key]] print(dot1dBasePortDescr) # Read dot1qTpFdbPort table print(" - Reading device dot1qTpFdbPort table...", file=sys.stderr) dot1qTpFdbPort = snmp_walk( "192.168.0.112", "1.3.6.1.2.1.17.4.3.1.2", "int", community="zabbix" ) dot1qTpFdb = {} for mac, bid in dot1qTpFdbPort.items(): macdec = read_mac_from_oid_tail(mac, with_len=False) print("machex=", machex(macdec)) print("bid=", bid) dot1qTpFdb[machex(macdec)] = str(bid) print(dot1qTpFdb) dot1qTpFdbDescr = {} for key in dot1qTpFdb.keys(): if dot1qTpFdb[key] in dot1dBasePortDescr.keys(): dot1qTpFdbDescr[key] = dot1dBasePortDescr[dot1qTpFdb[key]] print(dot1qTpFdbDescr)