====== Erstellung einer eigenen MIB für den Contiki 2.5 SNMP Agent ====== Um eine eigene MIB auf dem Agent zu erstellen, kann als Vorlage die Datei //mib-init.c// verwendet werden, diese befindet sich, insofern die Installationsanleitung unter [[contiki:snmp_contiki_25_install|SNMP auf Contiki 2.5 Installation]] durchgeführt wurde unter //\cygwin\home\Administrator\C25-SNMP\contiki-2.5\apps\snmpd//. Die Datei //mib-init.c// enthält bereits einige Standard MIB Objekte wie System Description, System Time usw… Diese können entweder gelöscht werden oder auch weiterhin verwendet werden. ===== OID erstellen ===== Um nun ein neues Objekt hinzuzufügen muss zuerst eine gültige OID erstellt werden. Ein OID stellt einen Knoten in einem hierarchisch zugewiesenen Namensraum dar, der durch den ASN.1-Standard definiert ist. Jeder Knoten ist durch eine Folge von Nummern eindeutig gekennzeichnet, die seine Position beginnend an der Wurzel des Baumes angibt. Also z.B. 1.3.6.1.4.1 entspricht iso.org.dod.internet.private.enterprise. Da SNMP plattformunabhängig und unter unterschiedlichsten Netzstrukturen funktionsfähig sein muss, wurde für die Kodierung dieser OIDs ein einheitliches Format laut ASN.1 – Standard gewählt. Zur Kodierung werden die BER (Basic Encoding Rules) verwendet. Der ASN.1-Standard beschreibt Speicherung der Daten im Format Typ Identifier, Length Descriptor und Daten Element. (siehe http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf) Jedoch wurde für die Codierung von OIDs ein spezielles Verfahren festgelegt (ITU-T, X.690/8.19), so werden Typ Identifier und Length Descriptor nicht verwendet. Die ersten beiden Dezimalzahlen werden über die Formel (X*40) + Y, also bei dem vorherigen Beispiel 1.3.6.1.4.1 entspricht X=1 und Y=3 entsteht so die Dezimalzahl 43, in hex 0x2B. Für die folgenden Dezimalzahlen ist festgelegt, dass pro Byte 7 Bit verwendet werden können, wobei das 7.Bit das MSB und das 1.Bit das LSB repräsentiert. Das 8. Bit gibt jeweils an ob das darauffolgende Byte zur derzeitigen Zahl gehört. (8.Bit =1, weitere Bytes folgen, 8.Bit = 0, keine weiteren Bytes folgen) Zur Erzeugung einer eigenen OID kann der Quelltext unter \cygwin\home\Administrator\C25-SNMP\Source\ber-encoder verwendet werden. (oder [[contiki:snmp_ber_encoder_source|]]) In diesem Beispiel soll ein Pin des Raven Boards angesteuert werden und die OID der Beuth Hochschule 1.3.6.1.4.1.22109 verwendet werden. (http://www.iana.org/assignments/enterprise-numbers/ unter TFH Berlin) Hierzu wird nun die OID mit mithilfe des BER Encoders codiert, verwendet wird als Unterstruktur 100.1, also 1.3.6.1.4.1.22109.100.1. Als Ergebnis lierfert der BER Encoder {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xac, 0x5d, 0x64, 0x01}; zurück. ===== OID in die MIB einfügen ===== Diese OID kann nun in einem Array vom Datentyp u8t abgespeichert werden. Um Datenspeicher zu sparen kann beim Raven Board anschließend mit PROGMEM festgelegt werden, dass diese im Programmspeicher abgelegt wird. static u8t ber_oid_beuth_int[] PROGMEM = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xac, 0x5d, 0x64, 0x01}; Anschließend muss mithilfe des Datentyps ptr_t, welcher eine Struktur aus Pointer sowie einem unsigned Short darstellt, die Adresse sowie die Array Länge abgespeichert. static ptr_t oid_beuth_int PROGMEM = {ber_oid_beuth_int, 10}; ===== Definieren der Get und Set Funktionen ===== Damit der SNMP Agent weiß, welche get bzw. set Funktion beim Erhalt eines solchen Befehls aufrufen muss, müssen diese festgelegt werden. Bsp. für das Setzen eines Pins am Raven Board (Quelle der get und set Funktionen Frank Schwarze - frank.schwarze@gmx.net) s8t getBeuthState(mib_object_t* object, u8t* oid, u8t len) { object->varbind.value.i_value = ((PORTD >> PIN7) & 1); printf("Get Pin State ausgeführt, Ergebnis %d\n",object->varbind.value.i_value); return 0; } s8t setBeuthState(mib_object_t* object, u8t* oid, u8t len, varbind_value_t value) { DDRD |= (1 << PIN7); //PIN7 als Ausgang setzen if (value.i_value == 1) { PORTD |= (1 << PIN7); printf("Set Pin ausgeführt (if==1-Zweig), Ergebnis %d\n",value.i_value); } else { PORTD &= ~(1 << PIN7); printf("Set Pin ausgeführt (else Zweig), Ergebnis %d\n",value.i_value); } object->varbind.value.i_value = (PORTD & (1 << PIN7)); printf("Set Pin: Pin7 hat nun den Zustand:%d\n",object->varbind.value.i_value); return 0; } Wobei die //printf()//-Ausgaben ausschließlich für Debugging vorgesehen sind. Um nun das neue MIB-Objekt zu initialisieren, muss dies noch in der Funktion //mib_init()// aufgerufen werden. Hierzu wird bei einzelnen OIDs die Funktion s8t add_scalar(ptr_t* oid, u8t flags, u8t value_type, const void* const value, get_value_t gfp, set_value_t svfp); verwendet. Wobei als erstes die Adresse der zuvor erstellten //ptr_t//-Struktur übergeben wird. Danach können Flags definiert werden. Das dritte Argument ist der Datentyp des Objects, hier Integer. Als viertes Argument folgt der Initialisierungszustand und als fünftes und sechstes müssen Pointer auf die //get()// und //set()// Funktion übergeben werden. if (add_scalar(&oid_beuth_int, 0, BER_TYPE_INTEGER, 0, &getBeuthState, &setBeuthState) == -1) { return -1; } War der Funktionsaufruf nicht erfolgreich, so liefert //add_scalar()// -1 als Rückgabewert. Damit wurde ein neues Objekt in die MIB eingefügt. Bsp. MIB unter [[contiki:snmp_beuth_mib_source|]] Nun wird die neue MIB unter neuem Namen gespeichert, z.B. //mib-init-beuth.c//. ===== Kompilierung mit neuer MIB ===== Damit nun bei der Kompilierung die neue MIB genutzt wird, muss das //Makefile// angepasst werden. Dazu das //Makefile// unter //\cygwin\home\Administrator\C25-SNMP\contiki-2.5\examples\snmp// die Datei //Makefile// editieren. Durch hinzufügen von: raven-beuth: make TARGET=avr-raven MIB_INIT=mib-init-beuth.c $(PROJECT).elf avr-objcopy -O ihex -R .eeprom -R .fuse -R .signature $(PROJECT).elf $(PROJECT).hex avr-size -C --mcu=atmega1284p $(PROJECT).elf rm -rf obj_native Und die anschließende Kompilierung mit make raven-beuth wird die neue MIB genutzt. Bsp. Makefile [[contiki:snmp_beuth_mib_makefile_source|]] Es kann nun wieder mit dem MIBBrowser ein Walk durchgeführt werden und anschließend mit Set bzw. Get Befehlen der Ausgangspin 7 siehe Abbildung gesetzt bzw. rückgesetzt werden. {{:contiki:mib1.png?direct&600|}}