Tuesday, October 19, 2021

IOS - retrieve interface name from cmnHistMacChangedMsg SNMP notification

TL;DR: How do I extract interface name from a cmnHistMacChangedMsg (mac change) message?

Hello,

I am trying to write a script for my switchs (mostly 2960s / 3560s) that would catch MAC learning events (sent through SNMP notifications), for audit purposes. It is mostly going well, switch is sending the SNMP notification when a new MAC is learnt, my script catches it successfully and extracts the payload. One thing I am having trouble with is deducing the switch interface from that data. Based on CISCO-MAC-NOTIFICATION-MIB ( ftp://ftp.cisco.com/pub/mibs/v2/CISCO-MAC-NOTIFICATION-MIB.my ) and relevant object (cmnHistMacChangedMsg), payload is in the form of: operation,VLAN,MAC,dot1dBasePort. I had assumed that dot1dBasePort was referring to an entry in the BRIDGE-MIB, where I could look up dot1dBasePortIfIndex to get the corresponding IfIndex and from there get the ifDescr (ie human-readable name of the interface).

However, the SNMP notification (or corresponding SNMP-get on the same OID) doesn't seem to follow that logic regarding the dot1dBasePort field. For example :

# snmpwalk -v 2c -c public MySwitch 1.3.6.1.4.1.9.9.215.1.1.8.1.2 SNMPv2-SMI::enterprises.9.9.215.1.1.8.1.2.1 = Hex-STRING: 01 00 0A AA BB CC DD EE FF 00 18 00 

So 0018 is the port (don't know why the trailing 00 byte btw), which in decimal is 24, and it turns out that the relevant interface is actually Fa0/24 (I have tried with other interfaces, got same pattern). On the other hand if I try to follow what's written in the MIB, there is no element 24 in dot1dBasePortIfIndex, actually there are not a lot of elements in there, not even one per UP interface (10 interfaces were UP at the time of this request):

# snmpwalk -v 2c -c public MySwitch 1.3.6.1.2.1.17.1.4.1.2 SNMPv2-SMI::mib-2.17.1.4.1.2.1 = INTEGER: 10001 SNMPv2-SMI::mib-2.17.1.4.1.2.22 = INTEGER: 10022 SNMPv2-SMI::mib-2.17.1.4.1.2.25 = INTEGER: 10101 SNMPv2-SMI::mib-2.17.1.4.1.2.26 = INTEGER: 10102 

compared to an ifDescr lookup, which yields the expected data:

# snmpwalk -v 2c -c public MySwitch 1.3.6.1.2.1.2.2.1.2 IF-MIB::ifDescr.1 = STRING: Vlan1 IF-MIB::ifDescr.10 = STRING: Vlan10 IF-MIB::ifDescr.10001 = STRING: FastEthernet0/1 IF-MIB::ifDescr.10002 = STRING: FastEthernet0/2 IF-MIB::ifDescr.10003 = STRING: FastEthernet0/3 IF-MIB::ifDescr.10004 = STRING: FastEthernet0/4 IF-MIB::ifDescr.10005 = STRING: FastEthernet0/5 IF-MIB::ifDescr.10006 = STRING: FastEthernet0/6 IF-MIB::ifDescr.10007 = STRING: FastEthernet0/7 IF-MIB::ifDescr.10008 = STRING: FastEthernet0/8 IF-MIB::ifDescr.10009 = STRING: FastEthernet0/9 IF-MIB::ifDescr.10010 = STRING: FastEthernet0/10 IF-MIB::ifDescr.10011 = STRING: FastEthernet0/11 IF-MIB::ifDescr.10012 = STRING: FastEthernet0/12 IF-MIB::ifDescr.10013 = STRING: FastEthernet0/13 IF-MIB::ifDescr.10014 = STRING: FastEthernet0/14 IF-MIB::ifDescr.10015 = STRING: FastEthernet0/15 IF-MIB::ifDescr.10016 = STRING: FastEthernet0/16 IF-MIB::ifDescr.10017 = STRING: FastEthernet0/17 IF-MIB::ifDescr.10018 = STRING: FastEthernet0/18 IF-MIB::ifDescr.10019 = STRING: FastEthernet0/19 IF-MIB::ifDescr.10020 = STRING: FastEthernet0/20 IF-MIB::ifDescr.10021 = STRING: FastEthernet0/21 IF-MIB::ifDescr.10022 = STRING: FastEthernet0/22 IF-MIB::ifDescr.10023 = STRING: FastEthernet0/23 IF-MIB::ifDescr.10024 = STRING: FastEthernet0/24 IF-MIB::ifDescr.10101 = STRING: GigabitEthernet0/1 IF-MIB::ifDescr.10102 = STRING: GigabitEthernet0/2 IF-MIB::ifDescr.10501 = STRING: Null0 

So either the MIB is wrong, the switch is not behaving as it should, or I am missing something. Now as this alleged dot1dBasePort field seems to be in fact almost the interface name I guess I could take that for granted and go this route, but as I have about 100 switches in various models, IOS versions and configurations, I would like to take a deterministic approach and understand what I am doing.

Any ideas?



No comments:

Post a Comment