Router pracuje na třetí vrstvě (laye3 OSI model), kdy pro určení, kam odeslat data používá IP adresy. Pro doručení dat do přímo připojeného subnetu však potřebuje znát i MAC adresu stanice. Proto si udržuje ARP tabulku (Address Resolution Protocol) nebo jinak řečeno překladovou tabulku pro mapování IP adres na fyzické adresy. Záznamy v této tabulce se uchovávají jen omezenou dobu.
Tuto tabulku můžeme pomocí SNMP stáhnout a použít k nalezení aktuálních IP adres k MAC adresám. Tentokrát se navíc nejedná o žádnou komplikovanou operaci, až na to, že existuje několik možných OID, kde se tyto hodnoty nachází.
1. MIB soubor IP-MIB, OID = 1.3.6.1.2.1.4.22, což je .iso.org.dod.internet.mgmt.mib-2.ip.ipNetToMediaTable
jméno | OID | popis |
---|---|---|
ipNetToMediaPhysAddress | .1.3.6.1.2.1.4.22.1.2 | MAC adresa |
ipNetToMediaNetAddress | .1.3.6.1.2.1.4.22.1.3 | IP adresa |
ipNetToMediaType | .1.3.6.1.2.1.4.22.1.4 | typ mapování, 3 – dynamická |
2. MIB soubor RFC1213-MIB, OID = 1.3.6.1.2.1.3.1, což je .iso.org.dod.internet.mgmt.mib-2.at.atTable
jméno | OID | popis |
---|---|---|
atPhysAddress | .1.3.6.1.2.1.3.1.1.2 | MAC adresa |
atNetAddress | .1.3.6.1.2.1.3.1.1.3 | IP adresa |
3. MIB soubor IP-MIB, OID = 1.3.6.1.2.1.4.35, což je .iso.org.dod.internet.mgmt.mib-2.ip.ipNetToPhysicalTable
jméno | OID | popis |
---|---|---|
ipNetToPhysicalNetAddress | .1.3.6.1.2.1.4.35.1.3 | IP adresa |
ipNetToPhysicalPhysAddress | .1.3.6.1.2.1.4.35.1.4 | MAC adresa |
V dokumentaci se uvádí, že varianta 1 byla nahrazena univerzálnější variantou 3 (která mimochodem obsahuje i řadu dalších hodnot). Na switchích Catalyst 3750 a 2960 se mi však podařilo rozchodit pouze varianty 1 a 2.
Pokud použijeme variantu 2 (nebo identicky 1), tak dostaneme takovýto výstup
[at.atTable.atEntry.atPhysAddress.25.1.192.168.100.2] => Hex: 00 1E 49 8F 3C 00
Jedná se o hodnotu, která obsahuje MAC adresu. Zároveň je zde vidět, že poslední čtyři číslice z OID jsou IP adresou, ke které patří daná MAC. Stejný index se používá i pro hodnotu, která vrací IP adresu. Nikde se mi nepodařilo najít popis, ale v praxi to vždy takto vychází, takže jsem si zjednodušil kód, viz. dále.
Realizace v PHP
Následující kód je pouze fragment, který navazuje na kód v předchozích dílech. Funkce getARP
načítá pouze hodnoty MAC adres a vytvoří pole, kde indexem je MAC adresa a IP adrese se vezme z indexu OID. Místo složitějšího způsobu, kdy by se vytvářelo indexované pole a pro každou hodnotu by obsahovalo IP a MAC. Další zjednodušení je při vyhledávání.
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; } }
Funkci getARP
spustíme pouze jednou na začátku. Pravděpodobně máme jen jeden router, i když se dá použít i pro více. Potom procházíme jednotlivé switche a po načtení MAC adres spustíme funkci assignIPtoMAC
, která projde všechny interfacy a pokud je na něm načtena MAC adresa, tak vrátí hodnotu z pole arp podle této MAC adresy.
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"]]; }
Komentáře
Zatím tento záznam nikdo nekomentoval.