CZ 
14.09.2024 Radka VÍTEJTE V MÉM SVĚTĚ

Informace o portech switche pomocí SNMP a PHP

| Petr Bouška - Samuraj |
V článku se snažím přiblížit možnosti praktického využití SNMP ve spojení s programovacím jazykem PHP. Příklad, který jsem zvolil je získání informací o portech/interfacech switche. Nejsou potřeba hluboké znalosti ani SNMP ani PHP k tomu abychom dosáhli zajímavé funkčnosti. Myslím, že hlavní je nápad (nebo informace) co vše můžeme dokázat.
zobrazeno: 22 043x | Komentáře [1]

Popisovaný příklad vychází z praktické situace, kterou řeším. Využívám description portu, kam zapisuji co je do daného portu zapojeno - označení zásuvky (když je připojena zásuvka) nebo jméno počítače (pokud je přímo připojen do portu). Potom je jednoduché zjistit, kam port vede (například, když sleduji nějakou podezřelou MAC adresu v síti), aniž bych musel procházet kabely. Občas, ale potřebuji opačnou věc, pro určitou zásuvku nalézt switch a port, kam je zapojena. Proto potřebuji seznam všech portů a switchů, který se však ručně složitě udržuje. A tady nastupuje myšlenka získávat tyto informace dynamicky pomocí SNMP, na což mě přivedlo Cacti, kde v podstatě tato možnost již je.

PHP a podpora SNMP

Pozn.: Používám PHP (a Apache) pod Windows, takže můj popis tomu odpovídá. Pod Linuxem jsou některé věci odlišné.

V programovacím jazyce PHP máme k dispozici extension php_snmp, které nabízí základní SNMP komunikační příkazy jako snmpget, snmpset a snmpwalk. Některé další příkazy jsou dostupné až od verze PHP 5. Podrobný popis naleznete v dokumentaci http://www.php.net/manual/en/ref.snmp.php .

Omezením je, že tyto příkazy používají pouze SNMP verze 1. Našel jsem různé odkazy na nedokumentované funkce snmp2_get, snmp3_get, apod., které by měly používat SNMPv2c a SNMPv3. Ale tyto funkce v mé verzi PHP nefungují.

PHP má ve svém adresáři podadresář mibs, který obsahuje běžné MIB tabulky. Může však nastat problém, že PHP tento adresář nenajde a při použití SNMP vypisuje varování (a samozřejmě pak MIB databázi nevyužívá). Řešením je vytvořit systémovou proměnnou (Control Panel - System - Advanced - Environment Variables - System variables) se jménem MIBDIRS a hodnotou je cesta k adresáři s MIB soubory.

Pozn.: Například v EasyPHP není adresář s MIB soubory obsažen, a proto je třeba jej vykopírovat z běžné instalace PHP.

Výhodou, když používáme MIB tabulky je, že návratové hodnoty jsou podle nich upraveny a například výčtový typ má doplněno jméno (to je například u typu interfacu).

V PHP pro SNMP existuje také řada funkcí, které nastavují chování hodnot, například, že se OID zobrazují číselně nebo výsledná hodnota neobsahuje doplňující informace (jako třeba typ - Gauge32: 100). Bohužel ne vše vždy správně funguje.

Druhou možností pro použití SNMP je mít nainstalováno Net-SNMP a volat jeho příkazy z PHP pomocí funkce exec a přebírat výstup. V tomto případě můžeme využít všechny verze SNMP a nemáme problém s verzemi PHP (které obsahují pouze některé funkce).

SNMP pro interfacy

SNMP hodnoty pro interfacy jsou součástí standardní MIB tabulky IF-MIB. Strom hodnot začíná na OID = 1.3.6.1.2.1.2, zápis pomocí jmen uzlů je iso.org.dod.internet.mgmt.mib-2.interfaces. První hodnotou je počet interfaců.

jméno OID popis
ifNumber .1.3.6.1.2.1.2.1.0 počet interfaců daného zařízení

Dále je tabulka, která obsahuje určité vlastnosti pro každý interface. Zajímavé jsou například

jméno OID popis
ifIndex .1.3.6.1.2.1.2.2.1.1 indexové číslo interfacu
ifDescr .1.3.6.1.2.1.2.2.1.2 pojmenování portu
ifType .1.3.6.1.2.1.2.2.1.3 typ portu
ifSpeed .1.3.6.1.2.1.2.2.1.5 rychlost portu
ifOperStatus .1.3.6.1.2.1.2.2.1.8 stav portu (up, down, ...)
ifInUcastPkts .1.3.6.1.2.1.2.2.1.11 příchozí unikástové pakety

Některé další hodnoty nalezneme na trochu jiném místě, pod OID = 1.3.6.1.2.1.31, iso.org.dod.internet.mgmt.mib-2.ifMIB

jméno OID popis
ifName .1.3.6.1.2.1.31.1.1.1.1 zkrácené jméno portu
ifAlias .1.3.6.1.2.1.31.1.1.1.18 popis (alias) portu

Informace o IP adresách (ty mohou být přiřazeny samozřejmě jen někde, např. pro VLANy) jsou pod OID = 1.3.6.1.2.1.4, iso.org.dod.internet.mgmt.mib-2.ip

jméno OID popis
ipAdEntAddr .1.3.6.1.2.1.4.20.1.2 IP adresy
ipAdEntIfIndex .1.3.6.1.2.1.4.20.1.1 indexy interfaců pro IP adresy

Pro switch jsou také zajímavé globální informace jako jméno a umístění. To jsou hodnoty, které můžeme zadat téměř pro každé SNMP zařízení při instalaci (nebo v nastavení). OID = .1.3.6.1.2.1.1, iso.org.dod.internet.mgmt.mib-2.system

jméno OID popis
sysName .1.3.6.1.2.1.1.5.0 jméno zařízení
sysLocation .1.3.6.1.2.1.1.6.0 umístění

Některé údaje, jako třeba počet interfaců nebo jméno zařízení jsou reprezentovány jednou hodnotou a můžeme proto využít funkci snmpget. Ostatní hodnoty, které jsou specifické pro každý interface, jsou uloženy tak, že za dané OID je připojen index interfacu a teprve zde je uložena hodnota. Protože tyto interfacy většinou a neznáme a také proto, že je to efektivnější, můžeme využít funkci snmpwalk, která projde všechny hodnoty pod zadaným OID a vrátí nám pole hodnot. Vhodnější je ještě funkce snmprealwalk, která vrací také OID pro danou hodnotu.

Můžeme také využít funkci snmpwalk tak, že ji zavoláme na OID pro interface a získáme všechny hodnoty pro všechny interfacy.

Ralizace v PHP

// funkce, která naplní pole $interfaces hodnotami ze zařízení s adresou $ip a pro přístup se použije community string $comm
function getInterface(&$interfaces, $ip, $comm) {
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.1", "Index");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.8", "Status"); 
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.2", "Port_name");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.31.1.1.1.18", "Descr");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.3", "Type");
  $name = format_snmp_string(snmpget($ip, $comm, ".1.3.6.1.2.1.1.5.0"));
  addInterSwitcheVal($interfaces, "Switch", $name);
}
// do pole přidá položku, která je stejná pro všechny indexy
function addInterSwitcheVal(&$interfaces, $valname, $value) {
  foreach($interfaces as $val)
    $interfaces[$val["Index"]][$valname] = $value;
}
// načte jednu vlastnost pro všechny interfacy
function getInterPart(&$interfaces, $ip, $comm, $oid, $name) {
  $array = snmprealwalk($ip, $comm, $oid);
  foreach($array as $key => $val) {
    $index = ereg_replace('.*\.([0-9]+)$', "\\1", $key);  //index je posledni cislo z OID
    $val = format_snmp_string($val);
    $interfaces[$index][$name] = $val;
  }
}
// vytiskne pole interfaců jako tabulku
function printInterfaces($interfaces) {
  echo "<table>";
  echo "<tr><th>Switch</th><th>Index</th><th>Status</th><th>Port_name</th><th>descr</th><th>Type</th> tr>";
  foreach($interfaces as $val) {
    echo "<tr>";
    echo "<td>".$val["Switch"]."</td>";
    echo "<td>".$val["Index"]."</td>";
    echo "<td>".$val["Status"]."</td>";
    echo "<td>".$val["Port_name"]."</td>";
    echo "<td>".$val["Descr"]."</td>";
    echo "<td>".$val["Type"]."</td>";
    echo "</tr>";
  }
  echo "</table>";
}
// proměnná kam se ukládají výsledné hodnoty, jendá se o dvourozměrné pole - všechny interfacy (podle indexu) a načtené hodnoty (podle jména)
$interfaces = array();
$ip = "10.0.0.1"; $co = "public";
// IP adresa zařízení, community string 
getInterface($interfaces, $ip, $co);
printInterface($interfaces);

Uvedený příklad je pouze nástin řešení. Je třeba jej obalit do HTML tagů, aby se mohl použít jako webová stránka. Také by si zasloužil řadu vylepšení nebo se dá řešit úplně jiným způsobem. Výsledné hodnoty můžeme například ukládat do databáze, což stačí jednou za delší dobu, protože asi nedochází k tolik častým změnám. Standardně jsou návratové hodnoty obaleny do řady zbytečných informaci (číselné hodnoty, MAC adresa ..), takže je vhodné je odstranit. Například Cisco switche vrací 3 typy interfaců - vlastní porty, VLANy a null interface. Takže zobrazovat třeba chceme pouze porty, což můžeme filtrovat podle ifType.

Můj příklad sloužil hlavně k tomu uvědomit si, jaké jsou možnosti a ukázat jak je jednoduché využívat SNMP z PHP.

Související články:

SNMP

Protokol SNMP (Simple Network Management Protocol) je velice užitečný pro správu počítačové sítě.

Pokud se chcete vyjádřit k tomuto článku, využijte komentáře níže.

Komentáře
  1. [1] jakub

    diky moc ;-)

    Úterý, 08.05.2007 23:54 | odpovědět
Přidat komentář

Vložit tag: strong em link

Vložit smajlík: :-) ;-) :-( :-O

Nápověda:
  • maximální délka komentáře je 2000 znaků
  • HTML tagy nejsou povoleny (budou odstraněny), použít se mohou pouze speciální tagy (jsou uvedeny nad vstupním polem)
  • nový řádek (ENTER) ukončí odstavec a začne nový
  • pokud odpovídáte na jiný komentář, vložte na začátek odstavce (řádku) číslo komentáře v hranatých závorkách