|
|
| Dokument: |
SNMP-API-Dokumentation |
| Version: |
1.03 |
| Author: |
abk-technology |
| URL: |
Inhalt
| 1. Einleitung |
|
|
|
|
|
|
2.2 SNMP-Agent |
|
|
|
|
|
2.4 MIBs |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dieses Dokument soll dem Benutzer des abk-technology SNMP-Programmier-Frameworks
einen kurzen Einblick in das SNMP-Protokoll bieten sowie ihm den praktischen
Umgang mit der SNMP-API erläutern.
Das bereitgestellte SNMP-Framework wurde entwickelt, um SNMP-Applikationen zu
erstellen, ohne Implementierungsdetails der SNMP-Protokollarchitektur kennen
zu müssen. Dies ermöglicht dem Entwickler eine schnelle und unkomplizierte
Erstellung von eigenen Anwendungen mit SNMP-Unterstützung. Das Framework
wurde in C geschrieben und liegt zur Einbindung in eigene Projekte als Libary-Datei
vor. Diese können unter anderem mit Borland C++ 5 und dem SC12/SC13 der
Firma BECK eingesetzt werden. Weiterhin ist eine Microsoft Windows® Version
verfügbar, die unter Visual C++ eingesetzt werden kann und zu Entwicklungs-
und Debugzwecken portiert wurde. Auf Anfrage ist es selbstverständlich
möglich unsere API auf andere Zielplattformen zu portieren.
Um mit Hilfe der abk-technology SNMP-API Anwendungen entwickeln zu können, sollte der Anwender grundlegendes Wissen über SNMP mitbringen. Diese Einführung kann und will keinen Anspruch auf Vollständigkeit erheben; sie dient lediglich dem Vermitteln von grundlegenden Zusammenhängen im Bezug auf SNMP sowie das in diesem Umfeld verwendete Vokabular. Grundlegendes Wissen im Bereich Netzwerktechnik und Programmierung in C bzw. C++ wird für folgende Ausführungen vorausgesetzt. Um sich tiefer in die Materie einzuarbeiten, sei an dieser Stelle auf einschlägige Literatur im Internet sowie die entsprechende Fachliteratur verwiesen.
Das Simple Network Management Protocol (SNMP) ist ein standardisiertes Internet-Protokoll zum Managen von Geräten welche über ein IP-Netzwerk miteinander verbunden sind. SNMP wurde ursprünglich dazu entwickelt, Netzwerk-Geräte wie Router, Switches, Server und Modems zu überwachen, sie zu konfigurieren und automatisch auf auftretende Hard- oder Softwareprobleme reagieren zu können. Durch die weite Verbreitung von IP-Netzwerken hat die Nachfrage nach netzwerkfähigen Geräten auch außerhalb der typischen Netzwerkanwendungen stark zugenommen. Viele neue Geräte, wie z.B. unterbrechungsfreie Stromversorgungen (USVs), Temperatursenoren, Signalschalter im HF- und NF-Bereich und Vieles mehr werden heute über IP-Netzwerke geteuert und überwacht. Um solche Geräte in vorhandene SNMP-Management-Systeme integrieren zu können, ist es notwendig Geräte zu entwickeln, die SNMP "verstehen und sprechen" können. Um dies zu ermöglichen, muss in der entsprechenden Anwendung ein Dienst bereitgestellt werden, der diesen Anforderungen entspricht. Im Kontext von SNMP spricht man bei einem solchen Dienst von einem SNMP-Agenten.
Wie im vorherigen Kapitel schon angesprochen, ist der SNMP-Agent eine Software, die jegliche Kommunikation zu und von einem SNMP-fähigen Gerät kontrolliert. Er stellt die in einem Gerät definierten Datensätze (MIBs) bereit und sendet bei Bedarf Nachrichten an ein Network Managemet System (NMS) welches auf diese reagieren kann. In SNMPv1 sind die folgenden Anfrage- bzw. Antworttypen spezifiziert:
GET - dient zum Abrufen eines Management Datensatzes aus der MIB.
2.3 SNMP Network Management System (NMS)
Network Management Systeme dienen zum Kommunizieren mit Agenten. Ein NMS ist ein Softwarepaket, welches meist aus verschiedenen Komponenten besteht, um unterschiedliche Anforderungen zu erfüllen. Primär dient jedes NMS dem Abfragen von Informationen, welche von SNMP-Geräten mittels des Agenten bereitgestellt werden. Die ermittelten Daten werden dann meist grafisch dargestellt oder dienen dem automatisierten Reagieren auf Netzwerk- oder andere Fehler. Einige der bekanntesten und auch komplexesten Management Systeme sind u.a. HP OpenView und IBM/ Tivoli Netview.
SNMP Netzwerkmanagement Informationen werden in der MIB (Management Information
Base) abgelegt. Diese Informationen werden hauptsächlich via ASN.1(Abstract
Syntax Notation) deklariert.
Die Informationen
der MIB sind in einer Art Baumstruktur organisiert, deren einzelne
Zweige entweder durch Nummern oder alternativ durch alphanumerische
Bezeichnungen dargestellt werden können. So existiert z.B. in
der von sehr vielen Netzwerkkomponenten unterstützten
"Internet-MIB" (MIB II und Erweiterungen) ein Objekt
iso.org.dod.internet.mgmt.mib-2.system.SysUpTime, das ebenso durch
die Zahlenreihe 1.3.6.1.2.1.1.3 eindeutig bestimmt ist (1 für
"iso", 3 für "org" usw.). Diese aus Punkten
und Zahlen bestehende Zeichenkette nennt man OID (Object IDentifier).
Es existiert in den MIBs ein eigener Zweig, der für Firmen
vorgesehen ist. (iso.org.dod.internet.private.enterprises bzw.
1.3.6.1.4.1). Wie auch bei IP-Adressen vergibt die IANA
(http://www.iana.org/)
Nummernbereiche, so hat z.B. die Firma Cisco den MIB-Zweig
1.3.6.1.4.1.9. Ist einer OID einmal ein Objekt zugeordnet, so darf
sich die Bedeutung dieser OID - sofern vom Gerät (dem
SNMP-Agenten) unterstützt - nicht wieder ändern, es darf
auch keine Überschneidungen geben.
Die in C programmierte SNMP-API besteht aus einer Funktionssammlung zum Erstellen eines MIB-II kompatiblen SNMP-Agenten sowie das Integrieren eigener MIBs durch Hinzufügen von OIDs in den Private Enterprise Zweig. Das Erstellen eigener MOs erfolgt hierbei dynamisch, und die Menge der hinzufügbaren Objekte ist lediglich durch den verfügbaren Speicher der Zielplattform begrenzt. Um den Programmieraufwand für den Benutzer auf ein Minimum zu reduzieren, aber gleichzeitig keine Abstriche bei der Flexibilität machen zu müssen, wurden die API-Funktionen in zwei Gruppen unterteilt.

Abbildung 1 Schematische Darstellung der abk-technology SNMP-API
Die erste Gruppe bilden die Funktionen, die dem Konfigurieren des SNMP-Agenten sowie dem Aufbauen einer benutzerdefinierten Private-Enterprise-MIB dienen. Die zweite Funktionsgruppe bildet das sogenannte Nachrichtensystem der API. Über dieses wird die Applikation über eingehende Nachrichten informiert und deren Inhalt, wie unter anderem Datentyp, Datengröße, Zugriffsrechte, Objekt ID und die eigentlichen Nutzdaten, zur Verfügung gestellt. Desweiteren ermöglicht das Nachrichtensystem ein einfaches Versenden von Traps an ein definiertes NMS.
3.1 Einbindung der SNMP-API in ein neues Projekt
Um die API in ein eigenes Projekt einbinden zu können, wird die SNMP-API-Libary benötigt, welche in der Standard- und der Debug-Version verfügbar ist. Die Debug-Version beinhaltet keine Debug-Informationen im herkömmlichen Sinne. Sie gibt interne Informationen zu eingehenden oder ausgehenden Paketen sowie den Aufbau der erzeugten MIB-Struktur über die Standardausgabe aus. Die Standard-Libary wird mit der Datei ipc_snmp.lib, die Debug-Version als ipc_snmp_d.lib ausgeliefert.
Um die SNMP-Libary in einem eigenen Projekt verwenden zu können, muss dem Linker mitgeteilt werden, wo sich diese befindet. Dies geschieht beispielsweise unter Borland C++ 5 durch Anklicken des ersten Eintrags im Projekt-Fenster mit der rechten Maustaste und dem anschließenden Auswählen von Add Node im Kontextmenü. Nach dem Auswählen der gewünschten SNMP-Libary befindet sich diese im Projekt und wird nun vom Linker berücksichtigt.
Abbildung
2 Eingebundene SNMP-Libary im Projektfenster von Borland C++
5
Weiterhin es notwendig, die zugehörige Header-Datei ipc_snmp.h einzubinden, um dem Compiler Funktionsprototypen und andere Schnittstellen zu beschreiben.
Die API besteht vorwiegend aus einer Sammlung von Funktionen welche folgende Aufgaben erfüllen:
| initSnmpTree |
Initialisierung der SNMP-Datenstruktur |
| addMibII |
Initialisierung der SNMP Datenstruktur und Aufbau der Internet MIB (MIB II) |
| addSnmpNode | Diese Funktion hängt ein neues "Managed Object" (MO ) einem ausgewählten Objekt an. Sie ermöglicht es somit, mehrere Zweige bzw. Blätter (Subnodes) an ein MO des MIB-Baumes anzuhängen |
| selectSnmpNode |
Selektieren eines "Managed Objects" (MO ) über eine gegebene Object-ID |
| setTableRowID |
Handelt es sich bei dem ausgewählten Objekt um eine Sequenz (Tabelle), werden die nachfolgend eingefügten Objekte in die mit setTableRowID(...) festgelegte Zeile eingefügt. |
| getSelectedSnmpNode |
Liefert die Datenstruktur des aktuell ausgewählten MOs |
| getFullOIDString |
Liefert die Objekt-ID eins gemanagten Objektes in der Punkt-Notation (z.B. 1.3.6.1) |
| setSnmpDeviceInfos |
Festlegen der gerätespezifischen SNMP-Daten |
| getSnmpDeviceInfos |
Auslesen der gerätespezifischen SNMP-Daten |
| createSnmpTrap |
Erzeugen eines Trap-Objektes |
| sendSnmpTrap |
Senden eines Trap-Objektes |
| startSnmpAgent |
Starten des SNMP-Agenten (Nur mit gültiger SNMP-Lizenz!) |
3.3 Konfigurieren des SNMP-Agenten
Die SNMP-Programmierschnittstelle bietet prinzipiell zwei Möglichkeiten, einen lauffähigen SNMP-Agenten zu konfigurieren bzw. zu programmieren.
Möglichkeit 1 (Erzeugen aller MIBs):
Möglichkeit 2 (Benutzen der internen MIB-II Struktur):
Initialisieren der SNMP-Datenstruktur und Aufbauen der Internet MIB (MIB-II) durch das Benutzen von addMibII(...)
Da die zweite Möglichkeit zum Erstellen eines Agenten alle benötigten Techniken und Vorgehensweisen beinhaltet, soll diese im Folgenden detaillierter betrachtet werden.
Um einen einfachen SNMP-Agenten erstellen zu können, reichen prinzipiell zwei Funktionsaufrufe der API aus.
...
addMibII();
startSnmpAgent();
...
Nach dem Erzeugen der MIB-II werden verschiedene Objekte des RFC1213-MIB.iso.org.dod.internet.mgmt.mib-2.system Zweiges durch Standardwerte vorbelegt.
|
Name |
Vorbelegung |
|
sysDescr |
Not Configured |
|
sysObjectID |
1.0 |
|
sysContact |
Not Configured |
|
sysName |
Not Configured |
|
sysLocation |
Not Configured |
Diese und weitere systemspezifische Parameter können Softwareseitig initialisiert werden (siehe Schnittstellenbeschreibung).
...
SNMP_DEVICE_INFOS
* pSnmpInfos = getSnmpDeviceInfos();
pSnmpInfos->iSnmpPort =
161;
pSnmpInfos->iTrapPort =
162;
strcpy(pSnmpInfos->szTrapIPAddress,"192.168.0.4");
strcpy(pSnmpInfos->szReadCommunity,"public");
strcpy(pSnmpInfos->szWriteCommunity,"public");
strcpy(pSnmpInfos->szSysContact,"info@abk-technology.de");
...
setSnmpDeviceInfos(pSnmpInfos);
...
getSnmpDeviceInfos() liefert einen Zeiger auf die Struktur SNMP_DEVICE_INFOS, welche zum Speichern aller wichtigen Konfigurationsdaten genutzt wird. Über diesen Zeiger können alle Werte geändert und durch den Aufruf von setSnmpDeviceInfos(...) aktualisiert werden. Durch setSnmpDeviceInfos(...) werden Objekte, die in der MIB-II spezifziert sind, automatisch in einer Datei gespeichert (Das Speichern von Werten aller Managed Objects erfolgt automatisch auch beim Ändern dieser durch das NMS!).
3.4 Erstellen von eigenen MIB-Strukturen
Um eigene Objekte bereitstellen zu können, ist es notwendig, den private.enterprise-Zweig zu erweitern. Dieser Vorgang soll im anschließenden Beispiel verdeutlicht werden:
...
/*
Initialisieren der MIB-II Struktur */
addMibII();
/*
Erstellen eines eigenen "private.enterprise" Knotens
*/
selectSnmpNode("1.3.6.1.4.1");
/* Selektieren des Objektes:
iso(1).org(3).dod(6).internet(1).private(4).enterprises(1)
*/
addSnmpNode(21561,"ABK",ASN1_OBJID); /*
Einfügen der "einzigartigen" Firmen-OID in den
Enterprise-Zweig */
selectSnmpNode("1.3.6.1.4.1.21561");
/* Selektieren der "einzigartigen" Firmen-OID
*/
addSnmpNode(1,"ABK_SNMP_MONITOR",ASN1_OBJID);
/* Einfügen einer gerätespezifischen
OID */
selectSnmpNode("1.3.6.1.4.1.21561.1");
addSnmpNode(1,"INPUT",ASN1_OBJID); /*
Einfügen der INPUT-Gruppe
*/
selectSnmpNode("1.3.6.1.4.1.21561.1.1");
addSnmpNode(1,"port_1",ASN1_INT,SNMP_READ_ONLY,SNMP_MANDATORY,cbAbk16Port1,0,4);
/* Einfügen der Statusvariablen */
addSnmpNode(2,"port_2",ASN1_INT,SNMP_READ_ONLY,SNMP_MANDATORY,cbAbk16Port2,0,4);
...
Durch Selektieren von Objekten und das Einhängen weiterer Unterobjekte lässt sich die Baumstruktur der Internet MIB weiter vergrößern. Nach dem Selektieren eines Objektes durch selectSnmpNode(...) beziehen sich alle Aufrufe von addSnmpNode(..) auf dieses MO. Dabei gibt der erste Parameter die ID des neu zu erzeugenden MOs an. Der zweite Parameter beschreibt das MO in einer verständlichen Form (Human readable form), z.B "internet". Der dritte Parameter gibt den Datentyp der Variable an, die über dieses Objekt gelesen oder beschrieben werden kann. Der vierte Parameter legt die Zugriffsrechte fest. Der fünfte Parameter gibt dem NMS Auskunft über den Status.
Um die Applikation über eingehende Nachrichten informieren zu können, arbeitet das Framework mit einem Nachrichtensystem, welches mit Hilfe von Callback-Funktionen realisiert wurde. Über den sechsten Parameter der addSnmpNode(..)-Funktion wird diese Callback-Funktion an das System übergeben. Diese Funktion muss folgendermaßen aufgebaut sein:
...
unsigned
long port1Val = 0;
void cbAbk16Port1(MANAGED_OBJECT * pMO,bool
set) { if ( !set ) memcpy(pMO->pData,&port1Val,4); }
...
Die letzten beiden Parameter der addSnmpNode(..)-Funktion dienen dem Speichern der Daten des entsprechenden Objektes. Der erste der beiden Parameter dient dabei der Übergabe einer Variablen, wenn diese zur Definitionszeit schon existiert. Der letzte Parameter gibt den zu allokierenden Speicherbedarf an, welcher vom genutzten Datentyp abhängig ist ( siehe: Schnittstellenbeschreibung der API).
3.5 Reagieren auf SET/GET/GET-NEXT - Anfragen vom NMS
Kommt eine Anfrage vom NMS, wird die SNMP-Nachricht zunächst auf richtige
Community-Strings geprüft. Weiterhin wird das angefragte MO auf entsprechende
Schreib-/Leserechte getestet. Bei fehlerhafter Überprüfung wird automatisch
die passende Fehlermeldung an das NMS gesendet. Ist die eingegangene Anfrage
korrekt, wird diese über das Nachrichtensystem an die Applikation weitergeleitet,
wo sie in der Callback-Funktion vom Benutzer weiterverarbeitet werden kann.
Die
Callback-Funktion besitzt zwei Parameter. Ersterer Parameter ist ein
Zeiger auf das MO, welches beschrieben (SET) bzw. ausgelesen (GET
oder GET_NEXT) werden soll. Die Datenstruktur welche ein solches
Objekt beschreibt, ist MANAGED_OBJECT. Diese enthält einen
Zeiger auf den Datenteil des Objektes. Über diesen Zeiger können
die Daten ausgelesen und aktualisiert werden. Der zweiten Parameter
der Callback-Funktion (set) ermöglicht es, zwischen einem
Schreib- und einem Lesezugriff zu unterscheiden. Schreibzugriffe
werden dabei vom System automatisch in der entsprechenden Variablen
abgelegt.
Um Traps versenden zu können, müssen die benötigten Traps zunächst
in Form eines Trap-Objektes generiert werden.
...
char
trapValue[256] = "Mein erster Trap!!";
TRAP_OBJECT Trap
= createSnmpTrap(1,ASN1_OCTSTR,trapValue,255);
...
Die
Funktion creatSnmpTrap(...)
erzeugt einen Trap, ähnlich wie bei der schon beschriebenen
Funktion addSnmpNode(..).
Der erste Parameter gibt hierbei jedoch den Specific-Trap-Type an.
Soll ein Standard Trap versendet werden, steht ein weitere Parameter
zur Verfügung, der es erlaubt, alle 6 Standard Traps zu
definieren.
...
sendSnmpTrap(&Trap);
...
Durch Aufrufen von sendSnmpTrap(...) wird der erzeugte Trap versendet.
4. Schnittstellenbeschreibung der API
Eine detaillierte Beschreibung der Programmierschnittstellen ist hier zu finden.
Um die SNMP-API mit dem IPC@Chip nutzen zu können, benötigen Sie
einen von uns generierten Schlüssel. Diesen generieren wir Ihnen nach Angabe
der IPC@Chip Seriennummer. Nachdem Sie eine SNMP-Lizenz erworben haben, legen
sie die entsprechende Schlüsseldatei in das Stammverzeichnis Ihres Controllers.
Wird dieser nach dem Agent-Start gefunden, meldet sich die Software mit der
folgenden Ausgabe:
valid
abk-technology key file...
abk-technology snmp licence ok...