Routers operate at the third layer (OSI model layer 3), using IP addresses to determine where to send data. However, to deliver data to a directly connected subnet, it also needs to know the MAC address of the station. Therefore, it maintains an ARP table (Address Resolution Protocol) or, in other words, a translation table for mapping IP addresses to physical addresses. The entries in this table are only stored for a limited time.
We can download this table using SNMP and use it to find the current IP addresses corresponding to MAC addresses. This time, it is not a complicated operation, except that there are several possible OIDs where these values are located.
1. MIB file IP-MIB, OID = 1.3.6.1.2.1.4.22, which is .iso.org.dod.internet.mgmt.mib-2.ip.ipNetToMediaTable
| Name | OID | Description |
|---|---|---|
| ipNetToMediaPhysAddress | .1.3.6.1.2.1.4.22.1.2 | MAC address |
| ipNetToMediaNetAddress | .1.3.6.1.2.1.4.22.1.3 | IP address |
| ipNetToMediaType | .1.3.6.1.2.1.4.22.1.4 | mapping type, 3 - dynamic |
2. MIB file RFC1213-MIB, OID = 1.3.6.1.2.1.3.1, which is .iso.org.dod.internet.mgmt.mib-2.at.atTable
| Name | OID | Description |
|---|---|---|
| atPhysAddress | .1.3.6.1.2.1.3.1.1.2 | MAC address |
| atNetAddress | .1.3.6.1.2.1.3.1.1.3 | IP address |
3. MIB file IP-MIB, OID = 1.3.6.1.2.1.4.35, which is .iso.org.dod.internet.mgmt.mib-2.ip.ipNetToPhysicalTable
| Name | OID | Description |
|---|---|---|
| ipNetToPhysicalNetAddress | .1.3.6.1.2.1.4.35.1.3 | IP address |
| ipNetToPhysicalPhysAddress | .1.3.6.1.2.1.4.35.1.4 | MAC address |
The documentation states that version 1 has been replaced by the more universal version 3 (which, by the way, also contains a number of other values). However, on Catalyst 3750 and 2960 switches, I was only able to get versions 1 and 2 to work.
If we use version 2 (or identically 1), we get the following output:
[at.atTable.atEntry.atPhysAddress.25.1.192.168.100.2] => Hex: 00 1E 49 8F 3C 00
This is a value that contains the MAC address. At the same time, it can be seen that the last four digits of the OID are the IP address to which the given MAC belongs. The same index is used for the value that returns the IP address. I couldn't find a description anywhere, but in practice, it always works this way, so I simplified the code, as shown below.
Implementation in PHP
The following code is just a fragment that builds on the code in the previous parts. The `getARP` function loads only the MAC address values and creates an array where the index is the MAC address and the IP address is taken from the OID index. Instead of a more complex method where an indexed array would be created and each value would contain IP and MAC. Another simplification is in the search.
function getARP(&$arp, $ip, $comm) {
$array = snmprealwalk($ip, $comm, ".1.3.6.1.2.1.4.22.1.2");
foreach($array as $key => $val) {
$ip = ereg_replace('.*\.([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$', "\\1", $key);
$mac = format_snmp_string($val);
$arp[$mac] = $ip;
}
}
We only run the `getARP` function once at the beginning. Probably we have only one router, although it can also be used for multiple ones. Then we go through the individual switches and after loading the MAC addresses, we run the `assignIPtoMAC` function, which goes through all the interfaces and if a MAC address is loaded on one of them, it returns the value from the `$arp` array based on this MAC address.
function assignIPtoMAC(&$interfaces, $name) {
global $arp;
foreach($interfaces as $key => $val)
if(empty($val["MAC"])) $interfaces[$key][$name] = "";
else $interfaces[$key][$name] = $arp[$val["MAC"]];
}
There are no comments yet.