1

We have hundreds of mostly Cisco switches and I'm trying to track down all the MAC addresses (latest would be good enough) seen by all the switchports. Following the suggestion given here, I've been using this command, which seems to work most of the time:

snmpbulkwalk -v2c -c $community@$vlan -OXsq -m BRIDGE-MIB $switch .1.3.6.1.2.1.17.4.3.1.2

Given a specific switch, switchport, and module, I've previously queried for the VLAN (using OID 1.3.6.1.4.1.9.5.1.9.3.1.3.${module}.${portnum}) and then parse the output to locate the port I'm looking for, which provides the accompanying MAC address; e.g.

...
dot1dTpFdbPort[f0:4d:a2:70:f8:b8] 24
dot1dTpFdbPort[f0:4d:a2:70:fc:d0] 24
dot1dTpFdbPort[f0:4d:a2:70:fe:c8] 24
dot1dTpFdbPort[f8:bc:12:38:55:f0] 3
dot1dTpFdbPort[f8:bc:12:3a:1b:c] 2
dot1dTpFdbPort[f8:bc:12:3f:4b:d0] 4
dot1dTpFdbPort[f8:bc:12:3f:d4:20] 5
dot1dTpFdbPort[f8:bc:12:40:79:30] 6
dot1dTpFdbPort[f8:bc:12:40:83:a0] 1
dot1dTpFdbPort[f8:bc:12:54:25:58] 11
dot1dTpFdbPort[f8:bc:12:54:34:58] 12
dot1dTpFdbPort[f8:bc:12:54:38:b8] 10
dot1dTpFdbPort[f8:bc:12:54:9c:f8] 8
...

Based on spot checking, the switchport is the number on the right, with the attached device MAC address in the square brackets just to the left of this.

Unfortunately I can't seem to find any good documentation on the snmpbulkwalk command, nor is the Cisco description of the OID (dot1dTpFdbPort) particularly illuminating. In particular, is it showing me the last MAC address seen, or what's currently attached?

Now for the real issue. I'm noticing this works when the port module is 1 (e.g. for switchblade7-1/14), but when I give it a switch where the ports are on module 2 (e.g. switchblade6-2/6), the port information returned by the snmpbulkwalk command is spurious; e.g.

dot1dTpFdbPort[0:8:5d:37:6b:d4] 78
dot1dTpFdbPort[0:a:f7:e2:83:f6] 78
dot1dTpFdbPort[0:a:f7:e2:a3:64] 78
dot1dTpFdbPort[0:18:8b:7a:93:2b] 78
dot1dTpFdbPort[0:18:8b:7a:94:fe] 78
dot1dTpFdbPort[0:1c:23:e2:bc:30] 78
dot1dTpFdbPort[0:1d:9:66:3f:11] 78
dot1dTpFdbPort[0:1d:9:66:3f:c0] 78
dot1dTpFdbPort[0:1d:9:66:41:7d] 78
dot1dTpFdbPort[0:1d:9:66:42:bd] 78
...

In this case, the number is always 78, so I have no way of telling which port goes with which MAC address. Presumably there's a way to perform the query specifying a module (a bit unsure about the terminology) for stacked switches, but I can't find anything documenting what this would be.

Any suggestions welcome. For secured ports I'm able to use the OID 1.3.6.1.4.1.9.9.315.1.2.3.1.5.${ifindex} to get a table of attached MAC addresses, but several hundred of our switchports are not secured.

pgoetz
  • 111
  • 2
  • You need to realize that a switch interface may have seen many MAC addresses if it is connected to another switch or a hub, so it is not unusual for a switch interface to be associated with many different MAC addresses (it could even be hundreds or thousands). The number you think is the port number is the interface index, and not the port number, and the interface index on a port can change. You need something like the snmp ifmib ifindex persist switch command (varies by model and software version). – Ron Maupin Jun 28 '22 at 22:43
  • Thanks, Ron. Yes, I'm aware that a switchport can be aware of many MAC addresses (typically when connected to another switch, but the example I provide above shows a single MAC address in brackets, with the interface index repeated as often as necessary (e.g. 24 in the example above). Not sure I understand why there is an additional abstraction layer (i.e. the interface index) between me and the port number I seek. – pgoetz Jun 29 '22 at 15:40

2 Answers2

2

is it showing me the last MAC address seen, or what's currently attached?

Neither. It's an associative array indexed by MAC address, so it's seeing what port the MAC address is attached to. You might be interested on what is attached to port 3 for management purposes but the primary purpose of the table is knowing where to forward packets for device X. Also, as Ron mentioned, it's a unique index this way round.

this works when the port module is 1 (e.g. for switchblade7-1/14), but when I give it a switch where the ports are on module 2 (e.g. switchblade6-2/6), the port information returned by the snmpbulkwalk command is spurious

SNMP programming is rather like database programming: you often need to construct joins against multiple tables to pull the data you want. dot1dTpFdbPort is an integer, unique for each port as used in spanning tree. If you're lucky, with a fixed port switch they will be something like 1-24. With a modular switch, you'll typically find something like (module number - 1) * 64 + port number.

So what you actually need to do is look up the dot1dBasePort in the dot1dBasePortTable and get to the dot1dBasePortIfIndex. When you have the IfIndex you are laughing because then you can find the ifDescr and good stuff like that.

.1.3.6.1.2.1.17.4.3.1.2.{mac-address} = TpPort
.1.3.6.1.2.1.17.4.4.1.1.{TpPort} = TpPortIfIndex
.1.3.6.1.2.1.2.2.1.2.52.TpPortIfIndex = IfDescr
richardb
  • 1,598
  • 8
  • 10
  • Using CAM (see this answer about that), there is no hash because CAM can return the table result much faster than a hash. Cisco switches use CAM and TCAM. – Ron Maupin Jun 29 '22 at 12:32
  • @RonMaupin Yes, I used slightly sloppy wording. I should have said 'what you might model in software with a hashtable' – richardb Jun 29 '22 at 12:39
  • Reading through this answer it looks like the CAM table contains all the information I need, and further that it's standard across most switches. So then the question becomes how do I retrieve the CAM table. I can parse the information that I need out of it myself if there is a way to retrieve the entire table. – pgoetz Jun 29 '22 at 15:16
  • @pgoetz It's standard across most modern switches but it's an implementation detail, and like most optimizations, not something you can easily get a handle on the details of as an end user (other than through the normal interfaces). – richardb Jul 02 '22 at 12:02
0

After many, many iterations this method appears to consistently work on every switch I've tested it on. Posting an answer in the hopes that no one else has to go through this again.

Assume the host resolvable name of the switch is switch1. I'm looking for MAC addresses seen on module = 1, port = 15 using community string COMMUNITY. string in the following is string output returned that prefaces the values you care about. In every case the output consists of 2 values separated by a single space character.

Step 1: Retrieve string.ifindex + module/fabric/port (e.g. Te1/0/15)

snmpwalk -v2c -c COMMUNITY -Osq switch1 .1.3.6.1.2.1.31.1.1.1.1

Step 2: Use the module/port to identify the corresponding ifindex, IFINDEX.

Step 3: Retrieve the string.bridgeport ifindex to find the bridgeport associated with the ifindex IFINDEX. For this step you will need to run the command for each VLAN recognized by the switch unless you already know the VLAN:

for $vlan in vlans
snmpwalk -v2c -c COMMUNITY@$vlan -Osq switch1 .1.3.6.1.2.1.17.1.4.1.2

Step 4: Having identified the bridgeport, BRIDGEPORT, associated with ifindex IFINDEX, you can now use the bridgeport to find the decimal MAC addresses associated with that bridgeport, as the following command retrieves

string.decimal_mac_address bridgeport

(You should know which vlan to use from the previous command.)

snmpwalk -v2c -c COMMUNITY@$vlan -Osq switch1 .1.3.6.1.2.1.17.4.3.1.2

That's it. Find the bridgeport = BRIDGEPORT and convert the corresponding decimal MAC address to hex format and you're done.

pgoetz
  • 111
  • 2