SNMP Mapping Mac Address to Switch Port
I work at a datacenter and I'm in the process of writing a php tool that maps all of our devices and can tell us if what is out there is what is being billed for.
It first pulls a huge list of macs and their ips from both of the cores into a temp table. Then, it loops through all of the racks* and attempts to find which port that mac belongs to. Since there is no golden command (cue lightbulb over your head), I have to:
- Create a multi-array with the port as the key and the ifindex for the value.
- Replace the ifindex with with a bridge ID.
- Replace the bridge ID with the mac hash.
- Repalce the mac hash with the actual mac
Lastly, it takes the mac, ips, and port and populates the master table.
The problem is step one. 1.3.6.1.2.1.31.1.1.1.1 works on most of the switches but a few of the foundrys do not work. 1.3.6.1.4.1.1991.1.1.3.3.1.1.38 kinda comes close to what I'm looking for but im not entirely comfortable it's what I'm looking for. I was able to find the specific device models under foundry > products > registration, but there aren't any MIBs under that folder. So my questions ar开发者_如何学运维e:
- Is there a foundry specific string that returns ports and macs? ifindexes would also work.
- How do I go about using device specific MIBs (enterprises.foundry.products.registration.snFWSXFamily)?
Any direction on this would be great. -Justin
*= rack models: cisco 2900xl, foundry FI4802 + variants
You can do this (tested on HP Procurve) :
From your linux server :
$ snmpwalk -v 1 -c public xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.2 | grep "INTEGER: 11"
(port number 11)
Will return :
SNMPv2-SMI::mib-2.17.4.3.1.2.44.118.138.64.143.95 = INTEGER: 11 SNMPv2-SMI::mib-2.17.4.3.1.2.56.170.60.108.174.57 = INTEGER: 11 SNMPv2-SMI::mib-2.17.4.3.1.2.104.181.153.172.54.237 = INTEGER: 11 SNMPv2-SMI::mib-2.17.4.3.1.2.120.172.192.143.226.236 = INTEGER: 11 SNMPv2-SMI::mib-2.17.4.3.1.2.124.195.161.20.109.76 = INTEGER: 11 SNMPv2-SMI::mib-2.17.4.3.1.2.152.75.225.59.127.180 = INTEGER: 11
Then you can do this to find which Mac Address is connected :
$ snmpwalk -v 1 -c public xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 | grep "152.75.225.59.127.180"
Return mac address :
SNMPv2-SMI::mib-2.17.4.3.1.1.152.75.225.59.127.180 = Hex-STRING: 98 4B E1 3B 7F B4
You can make a script.sh to do this...
when I needed to discover MACs and some other info from my switches, I used 'snmpwalk' and 'snmpbulkwalk' commands to examine their SNMP data contents
for example:
snmpbulkwalk -v2c 192.168.30.40 -c public 1.3.6.1.2.1.31.1.1.1.1
outputs:
IF-MIB::ifName.1 = STRING: Gi0/1
IF-MIB::ifName.2 = STRING: Gi0/2
IF-MIB::ifName.3 = STRING: Gi0/3
IF-MIB::ifName.4 = STRING: Gi0/4
IF-MIB::ifName.5 = STRING: Gi0/5
IF-MIB::ifName.6 = STRING: Gi0/6
IF-MIB::ifName.7 = STRING: Gi0/7
IF-MIB::ifName.8 = STRING: Gi0/8
IF-MIB::ifName.9 = STRING: Gi0/9
IF-MIB::ifName.10 = STRING: Gi0/10
IF-MIB::ifName.11 = STRING: Gi0/11
IF-MIB::ifName.12 = STRING: Gi0/12
IF-MIB::ifName.13 = STRING: Nu0
IF-MIB::ifName.14 = STRING: Vl1
IF-MIB::ifName.15 = STRING: Vl2
IF-MIB::ifName.16 = STRING: Vl416
and
snmpbulkwalk -v2c 192.168.30.40 -c public 1.3.6.1.2
outputs A LOT of info among which you can look for your favorite MACs or anything
If any one you would like to do this programmatically from a Windows Server you can use the SnmpSharpNet library to accomplish the same thing. Here's an example that will create a list of all the MAC Addresses and Ports on a particular Dell Switch using the OID 1.3.6.1.2.1.17.7.1.2.2.1.2.1
using SnmpSharpNet;
List<KeyValuePair<string, string>> portList = new List<KeyValuePair<string, string>>();
IPAddress ip = IPAddress.Parse("192.168.0.2");
SnmpWalk(ip, "snmpcommunity", "1.3.6.1.2.1.17.7.1.2.2.1.2.1", "1");
//SNMPWALK the ports on a switch or stack of switches. Ports will be labeled SwitchNum/Stack Number/Port Numbers.
private void SnmpWalk(IPAddress ip, string snmpCommunity, string oid, string switchNum)
{
UdpTarget target = new UdpTarget(ip);
// SNMP community name
OctetString community = new OctetString(snmpCommunity);
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 1
param.Version = SnmpVersion.Ver1;
// Define Oid that is the root of the MIB tree you wish to retrieve
Oid rootOid = new Oid(oid);
// This Oid represents last Oid returned by the SNMP agent
Oid lastOid = (Oid)rootOid.Clone();
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.GetNext);
// Loop through results
while (lastOid != null)
{
// When Pdu class is first constructed, RequestId is set to a random value
// that needs to be incremented on subsequent requests made using the
// same instance of the Pdu class.
if (pdu.RequestId != 0)
{
pdu.RequestId += 1;
}
// Clear Oids from the Pdu class.
pdu.VbList.Clear();
// Initialize request PDU with the last retrieved Oid
pdu.VbList.Add(lastOid);
// Make SNMP request
SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param);
// You should catch exceptions in the Request if using in real application.
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
Console.WriteLine("Error in SNMP reply. Error {0} index {1}",
result.Pdu.ErrorStatus,
result.Pdu.ErrorIndex);
lastOid = null;
break;
}
else
{
// Walk through returned variable bindings
foreach (Vb v in result.Pdu.VbList)
{
// Check that retrieved Oid is "child" of the root OID
if (rootOid.IsRootOf(v.Oid))
{
//Convert OID to MAC
string[] macs = v.Oid.ToString().Split('.');
string mac = "";
int counter = 0;
foreach (string chunk in macs)
{
if (counter >= macs.Length - 6)
{
mac += string.Format("{0:X2}", int.Parse(chunk));
}
counter += 1;
}
//Assumes a 48 port switch (52 actual). You need to know these values to correctly iterate through a stack of switches.
int dellSwitch = 1 + int.Parse(v.Value.ToString()) / 52;
int port = int.Parse(v.Value.ToString()) - (52 * (dellSwitch - 1));
KeyValuePair<string, string> Port = new KeyValuePair<string, string>(mac, switchNum + "/" + dellSwitch.ToString() + "/" + port.ToString());
portList.Add(Port);
//Exit Loop
lastOid = v.Oid;
}
else
{
//End of the requested MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
else
{
Console.WriteLine("No response received from SNMP agent.");
}
}
target.Close();
}
There is an entire project utilizing this example that resolves this information back to Hostnames here
精彩评论