Články
Zjištění MAC adresy zařízení na portu switche pomocí SNMP a PHP
Podobně jako určení zařazení portu do VLANy, ani nalezení MAC adresy na portu není úplně jednoduché. Princip práce switche je takový, že si vytváří tabulku přiřazení portu a MAC adresy a podle ní pak posílá data na druhé vrstvě (layer 2 OSI model). Navíc si tyto tabulky udržuje nezávisle pro každou VLANu. Z toho plyne, že my potřebujeme stáhnout ze switche tuto tabulku. Ta se označuje jako CAM tabulka (Content Addressable Memory) nebo jednoduše mac address table.
Obecný postup vypadá takto:
- vytvoříme seznam portů se základními údaji
- k portům přiřadíme, zda jsou v trunk módu či ne
- vytvoříme seznam VLAN
- projdeme VLANy a pro každou vytvoříme tabulku MAC adres a portů
- projdeme tabulky MAC adres a podle portu doplníme seznam portů o MAC adresu tam, kde port není trunk
Pozn.: V příkladu vycházím z toho, že mám do portu zapojeno pouze koncové zařízení, takže se pro port nalezne maximálně jedna adresa. Nebo že port je trunk, který ho spojuje s jiným switchem, a pak mne MAC adresy nezajímají. Pokud by někde byl připojen switch/hub nebo například IP telefon, do kterého je připojeno PC, tak dostanu pro jeden port více MAC adres a musel bych vytvářet pole.
Vytvoření seznamu portů/interfaců
Tento bod byl vyřešen v článku Informace o portech switche pomocí SNMP a PHP.
Určení trunk portů
Tento bod byl řešen v článku Informace o zařazení portu do VLANy u Cisco Switchů pomocí SNMP a PHP.
Seznam VLAN
Tento bod byl řešen v článku Informace o zařazení portu do VLANy u Cisco Switchů pomocí SNMP a PHP.
Procházení VLAN a načtení CAM tabulek
Pro stažení tabulky MAC adres a portů využijeme MIB soubor BRIDGE-MIB. V něm se nachází .iso.org.dod.internet.mgmt.mib-2.dot1dBridge.dot1dTp.dot1dTpFdbTable s OID = 1.3.6.1.2.1.17.4.3 a zajímat nás budou tato OID:
| jméno | OID | popis |
|---|---|---|
| dot1dTpFdbAddress | .1.3.6.1.2.1.17.4.3.1.1 | seznam MAC adres, pro které má switch forward informace |
| dot1dTpFdbPort | .1.3.6.1.2.1.17.4.3.1.2 | číslo portu, na kterém byla naučena daná MAC adresa |
| dot1dTpFdbStatus | .1.3.6.1.2.1.17.4.3.1.3 | stav záznamu, nás zajímá 3 = learned |
Pro přístup k těmto hodnotám se opět využívá hybridní community string (Cisco tuto metodu nazývá community string indexing), protože v MIB existuje pouze jedna instance a my potřebujeme získat hodnoty pro každou VLANu. Za community string doplníme @VLAN, takže například public@30 pro načtení hodnot z VLAN 30. Pokud nepoužijeme toto rozšíření, tak se vrací hodnoty z VLAN 1.
Pomocí snmpwalk projdeme OID pro dot1dTpFdbAddress, tím získáme seznam MAC adres. OID je za svým číslem doplněno několika číselným indexem. Jeden vrácený záznam může vypadat třeba takto:
[17.4.3.1.1.0.11.205.197.114.60] => Hex: 00 0B CD C5 72 3C
Stejným způsobem projdeme dot1dTpFdbStatus a určíme, zda tuto MAC adresu počítat.
[17.4.3.1.1.0.11.205.197.114.60] => 3
A pomocí dot1dTpFdbPort dostaneme patřičná čísla portu.
[17.4.3.1.1.0.11.205.197.114.60] => 54
Tím, že složíme hodnoty se stejným indexem, v tomto případě 0.11.205.197.114.60, tak dostaneme, že na portu 54 je MAC adresa 00:0B:CD:C5:72:3C. My však pracujeme s indexy portů (IfIndex), takže ještě nalezneme přiřazení indexu k číslu portu (toto OID jsme již použili u VLAN).
| jméno | OID | popis |
|---|---|---|
| dot1dBasePortIfIndex | .1.3.6.1.2.1.17.1.4.1.2 | pro číslo portu vrátí index interfacu |
Zde je index dán poslední hodnotou a to je naše číslo portu, pro které hledáme ifIndex.
[17.1.4.1.2.54] => 10202
Realizace v PHP
Následující kód obsahuje pouze funkci pro získání MAC adres a navazuje na kód v předchozích dílech.
// načte všechny hodnoty pod OID a vrátí je jako pole, index – poslední číslo OID function getInterPart2(&$interfaces, $ip, $comm, $oid) { $array = snmprealwalk($ip, $comm, $oid); foreach($array as $key => $val) { $index = ereg_replace('.*\.([0-9]+)$', "\\1", $key); $val = format_snmp_string($val); $interfaces[$index] = $val; } } // načte všechny hodnoty pod OID a vrátí je jako pole, index – složený z několika posledních čísel OID function getInterPart3(&$interfaces, $ip, $comm, $oid) { $array = snmprealwalk($ip, $comm, $oid); $oidl = strlen($oid) - 12; foreach($array as $key => $val) { $index = substr($key, $oidl); $val = format_snmp_string($val); $interfaces[$index] = $val; } } // pole portů doplní o MAC adresu function getMACs(&$interfaces, $ip, $comm) { $vlans = array(); getInterPart($vlans, $ip, $comm, ".1.3.6.1.4.1.9.9.46.1.3.1.1.18", "Index"); // VLAN ifIndex getInterPart($vlans, $ip, $comm, ".1.3.6.1.4.1.9.9.46.1.3.1.1.3", "Type"); // VLAN type, 1 - OK foreach($vlans as $vlan_id => $vlan) if($vlan["Type"] == 1) { $macs = array(); getInterPart3($macs, $ip, $comm."@".$vlan_id, ".1.3.6.1.2.1.17.4.3.1.1"); // seznam MAC adres pro danou VLAN $bridge = array(); getInterPart3($bridge, $ip, $comm."@".$vlan_id, ".1.3.6.1.2.1.17.4.3.1.2"); // urceni, kteremu bridge portu MAC adresa patri $ifI = array(); getInterPart2($ifI, $ip, $comm."@".$vlan_id, ".1.3.6.1.2.1.17.1.4.1.2"); // k bridge portu urci jeho interface index foreach($macs as $id => $mac) { // projdeme seznam MAC adres $ifIndex = $ifI[$bridge[$id]]; // ifIndex dostaneme z indexu záznamu, převedený na číslo portu a pak na ifIndex if($interfaces[$ifIndex]["Trunk"] == 2) $interfaces[$ifIndex]["MAC"] = $mac; else $interfaces[$ifIndex]["MAC"] = ""; } } }
Související články:
SNMP
- SNMP - Simple Network Management Protocol [20.12.2006 15:09]
- CACTI – SNMP monitoring a grafy [07.01.2007 12:51]
- Informace o portech switche pomocí SNMP a PHP [17.03.2007 19:37]
- Informace o zařazení portu do VLANy u Cisco Switchů pomocí SNMP a PHP [25.03.2007 19:02]
- Zjištění MAC adresy zařízení na portu switche pomocí SNMP a PHP [20.03.2008 11:21] právě čtete
- Stažení ARP tabulky z routeru (switche) pomocí SNMP a PHP [26.03.2008 18:33]
linkuj.cz | zalinkuj.cz | jagg.cz | vybrali.sme.sk | del.icio.us.
Pokud se chcete vyjádřit k tomuto článku, využijte komentáře níže. Pokud chcete poradit s nějakým problémem či diskutovat na nějaké téma, tak použijte fórum.

Komentáře
Zatím tento záznam nikdo nekomentoval.