Difference between revisions of "SNMP MIB Implementation"

From OpenCircuits
Jump to navigation Jump to search
Line 26: Line 26:
 
* mib2bin tool is modified from [http://net-snmp.sourceforge.net/ net-snmp] to convert ASN.1 format file to three files, because the microchip '''mib2bib''' converter only supports upto 255 OIDs.
 
* mib2bin tool is modified from [http://net-snmp.sourceforge.net/ net-snmp] to convert ASN.1 format file to three files, because the microchip '''mib2bib''' converter only supports upto 255 OIDs.
 
                                 MIB compiler tools: '''mib2bin'''
 
                                 MIB compiler tools: '''mib2bin'''
   [http://www.modtronix.com/products/sbc44ec/00870a.pdf foo.mib] (ANS.1 format)  -----------------------------------> foo.bin + foo.h + foo_data.h
+
   [http://www.modtronix.com/products/sbc44ec/00870a.pdf foo.mib] (ANS.1 format)  -----------------------------------> foo.bin foo_trap.bin+ foo.h + foo_data.h
  
 
* Syntax to use mib2bin tool:
 
* Syntax to use mib2bin tool:
Line 32: Line 32:
 
* where MIBfile file is ASN.1 format file. MIBfile = <name>.<type>
 
* where MIBfile file is ASN.1 format file. MIBfile = <name>.<type>
 
** '''<name>.bin''' is the binary file storing information of OID tree. This file can be placed on an SD media card to be read by the FAT16 file system.
 
** '''<name>.bin''' is the binary file storing information of OID tree. This file can be placed on an SD media card to be read by the FAT16 file system.
** '''<name>_data.h''' is C header file storing information of OID tree.  This file is generated by converting mchip.bin file to the C header file. It's only used when a system don't have system file and place on program memory.
+
** '''<name>_trap.bin''' is the binary file storing information of TRAP of MIB. This file can be placed on an SD media card to be read by the FAT16 file system.
 +
** '''<name>_data.h''' is C header file storing information of OID tree.  This file is generated by converting mchip.bin file to the C header file.  
 +
It's only used when a system don't have system file and place on program memory.
 
** '''<name>.h''' is C header file storing ID that's reference to function service of OID.
 
** '''<name>.h''' is C header file storing ID that's reference to function service of OID.
 
* Note:  
 
* Note:  
Line 53: Line 55:
 
* The microchip format only supports OIDs upto 255. The following is an workaround to store OID greater than 255.
 
* The microchip format only supports OIDs upto 255. The following is an workaround to store OID greater than 255.
 
* Format of OID:
 
* Format of OID:
   oid_1 <0x10> oid_2 <0x10> ....
+
   An OID is a series of (one or more) octets. Bit 8 of each octet indicates whether it is the last in the series: bit 8 of the last octet is zero;
*if (oid_i < 0xFF): oid_i = BYTE (oid_i)
+
  bit 8 of each preceding octet is one. Bits 7 to 1 of the octets in the series collectively encode the OID. Conceptually, these groups of bits are
*else: oid_i = <0xFF> + BYTE (length) + BYTE (oid_i.B0) + BYTE (oid_i.B1) + ...
+
  concatenated to form an unsigned binary number whose most significant bit is bit 7 of the first octet and whose least significant bit is bit 1 of  
* where
+
  the last octet. The OID shall be encoded in the fewest possible octets, that is, the leading octet of the OID shall not have the value 0x80.
** '''BYTE (x)''' mean the byte representation of x.
+
 
** '''<0x10>''' is the OID separator.
 
** '''<0xFF>''' is used to indicate that the OID is greater than 254.
 
** '''length''' is the number of bytes of oid_i that follows.
 
** '''oid_i.Bj''' is j-th byte of oid_i in hexadecimal representation, j = 0 corresponds to the Least Significant Byte (LSB), i.e. little-endian format.
 
 
* Example:
 
* Example:
     The OID for a node is '''4.1.17095.''' After compiling to binary, the OID is represented as:
+
     The OID               encode of OID in binary file (hex)
       The OID:      <font color=blue>4</font>  .    <font color=blue>1</font>  .              <font color=blue>17095</font>    .
+
       4                         BYTE(0x04)
      The result: <font color=blue>0x04</font> 0x10 <font color=blue>0x10</font> 0x10 <font color=green>0xFF</font> <font color=red>0x02</font> <font color=blue>0xC7 0x42</font> 0x10
+
      1                        BYTE(0x01)
      where:
+
    36061                      BYTE(0x80+ 0x02) BYTE(0x80 + 0x19) BYTE(0x5D)
          <font color=blue>oid_1 = 4 </font> => <font color=blue> BYTE (oid_1) = 0x04</font>
+
     The OID = 36061 is decoded by 0x02*0x80*0x80 + 0x19*0x80 + 0x5D
          <font color=blue>oid_2 = 2 </font> => <font color=blue> BYTE (oid_2) = 0x01</font>
 
          <font color=blue>oid_3 = 17095 = 0x42C7 </font> => <font color=green>0xFF</font> <font color=red>BYTE (length) = 0x02</font> <font color=blue>BYTE (oid_3.B0) BYTE (oid_3.B1) = 0xC7 0x42 (In little-endian format)</font>
 
     Note: When a node have no sibling and only has one child, the node's OID will be merged with its child's OID (reduce data's stored).
 
    For example, in case of '''private (4) -> enterprises (1) -> microchip (17095)''', where '''private''' has no sibling and only has one child,
 
    and '''enterprises''' also has no sibling and only has one child, they can combined to a record has oid field is 4.1.17095.
 
  
 
====<nodeInfo> field====
 
====<nodeInfo> field====
 
* information of node
 
* information of node
 
   bit        when (set = 1)
 
   bit        when (set = 1)
   0          Node is a parent (0: node is a leaf)
+
   0          Node has sibling node
   1          Node is sequence
+
   1          Node has default data
   2          Node is readable
+
   2          Node is sequence
   3          Node is writable
+
   3          Node is readable
   4          Node is able to create
+
   4          Node is a parent
   5          Node has default data
+
   5          Node is writable
   6          (if node is sequence, this is mean implied index node)
+
   6          Node is able to modify
   7          always set 1
+
   7          Node has sibling field (in IndexNodeInfo this bit indicate that Indexes is imply)
  
 
====[id] field====
 
====[id] field====
Line 122: Line 115:
 
* If this record is sequence (an order list of objects),  
 
* If this record is sequence (an order list of objects),  
 
** <IndexNumber> is the number of INDEXes in sequence.
 
** <IndexNumber> is the number of INDEXes in sequence.
** <IndexCount>: is OID of index node in table
+
** <IndexCount>: is id of index node in table
 
** <IndexNodeInfo>: is info of index node
 
** <IndexNodeInfo>: is info of index node
 
** <IndexDataType>: is data type of index node
 
** <IndexDataType>: is data type of index node
Line 130: Line 123:
 
       <IndexNumber> = 0x02
 
       <IndexNumber> = 0x02
 
       with the 1st INDEX:
 
       with the 1st INDEX:
           <IndexCount> = 0x04
+
           <IndexCount> = 0x05
           <IndexNodeInfo> = 0xCC
+
           <IndexNodeInfo> = 0x28
 
           <IndexDataType> = 0x02
 
           <IndexDataType> = 0x02
 
       with the 2nd INDEX:
 
       with the 2nd INDEX:
           <IndexCount> = 0x01
+
           <IndexCount> = 0x08
           <IndexNodeInfo> = 0x80
+
           <IndexNodeInfo> = 0xA4
           <IndexDataType> = 0x03
+
           <IndexDataType> = 0x04
 
   In this example, '''trap''' is a table which has 4 columns:  
 
   In this example, '''trap''' is a table which has 4 columns:  
 
       <font color=blue>trapReceiverNumber (1)</font>, trapEnabled (2), trapReceiverIPAddress (3), <font color=blue>trapCommunity(4)</font>.  
 
       <font color=blue>trapReceiverNumber (1)</font>, trapEnabled (2), trapReceiverIPAddress (3), <font color=blue>trapCommunity(4)</font>.  
Line 145: Line 138:
 
   This example has two INDEXes: the 1st INDEX node is trapCommunity (4) and the 2nd INDEX node trapReceiverNumber (1)  
 
   This example has two INDEXes: the 1st INDEX node is trapCommunity (4) and the 2nd INDEX node trapReceiverNumber (1)  
 
   Each INDEX is a node, so it has OID, info, data type.
 
   Each INDEX is a node, so it has OID, info, data type.
   The 1st INDEX node is trapCommunity, which has OID = 4, info is 0xCC and data type is INTEGER (0x02). so
+
   The 1st INDEX node is trapCommunity, which has id = 5, info is 0x28 and data type is INTEGER (0x02). so
 
           IndexCount = 0x04
 
           IndexCount = 0x04
           IndexNodeInfo = 0xCC
+
           IndexNodeInfo = 0x28
 
           IndexDataType = 0x02
 
           IndexDataType = 0x02
   The 2nd INDEX node is trapReceiverNumber, which has OID = 1, info is 0x80 and data type is DisplayString (0x03). so
+
   The 2nd INDEX node is trapReceiverNumber, which has id = 8, info is 0xA4 and data type is DisplayString (0x04). so
 
           IndexCount = 0x01
 
           IndexCount = 0x01
           IndexNodeInfo = 0x80
+
           IndexNodeInfo = 0xA4
           IndexDataType = 0x03
+
           IndexDataType = 0x04
  
 
===Example===
 
===Example===
Line 176: Line 169:
 
** The dist field points to next sibling record. After parent record is it's children.
 
** The dist field points to next sibling record. After parent record is it's children.
 
[[File:Snmp mib binary detail example.jpg | thumb | center | 900px]]
 
[[File:Snmp mib binary detail example.jpg | thumb | center | 900px]]
 
  
 
==Build SNMP's PDU using BER==
 
==Build SNMP's PDU using BER==

Revision as of 10:40, 27 April 2011

This wiki describe how to generate a MIB (Management Information Base) for SNMP agent.

Steps

  1. Create a ASN.1 MIB script foo.mib (an ASCII text file) for the tree structure.
  2. Convert foo.mib to binary file using mib2bin
  3. Build SNMP's PDU using BER (Base encoding rules) encoder and decoder library to process data that's transfer between NMS and agents.
  4. Build SNMP API use uIP-stack to communicate between NMS and Agents (open two ports: The manager speak to agents on one port, the agent responds manager on the other port).
  5. Build binary MIB file reader library.
  6. Build functions service oid tree.
  7. Merge MIB ANS.1 file to NMS.


Create ASN.1 MIB Script

Abstract Syntax Notation

  • Each MIB variable contains several attributes, such as data type, access type and object identifier.
  • Abstract Syntax Notation version 1 (ASN.1) is a language to define these attributes in SNMP.


Convert MIB to Binary File

  • mib2bin tool is modified from net-snmp to convert ASN.1 format file to three files, because the microchip mib2bib converter only supports upto 255 OIDs.
                                MIB compiler tools: mib2bin
 foo.mib (ANS.1 format)   -----------------------------------> foo.bin foo_trap.bin+ foo.h + foo_data.h
  • Syntax to use mib2bin tool:
  mib2bin <MIBfile>...
  • where MIBfile file is ASN.1 format file. MIBfile = <name>.<type>
    • <name>.bin is the binary file storing information of OID tree. This file can be placed on an SD media card to be read by the FAT16 file system.
    • <name>_trap.bin is the binary file storing information of TRAP of MIB. This file can be placed on an SD media card to be read by the FAT16 file system.
    • <name>_data.h is C header file storing information of OID tree. This file is generated by converting mchip.bin file to the C header file.

It's only used when a system don't have system file and place on program memory.

    • <name>.h is C header file storing ID that's reference to function service of OID.
  • Note:
    • Subfolder mibs containing the basics MIB files (e.g.: RFC1155-SMI, RFC1213-MIB, RFC-1215, SNMPv2-MIB ... for us MIB file), must be present under the directory of execution.
    • If the three files exist, mib2bin tool will overwrite the files.

Binary File Format

  • The binary file is an image of MIB file. It is generated by mib2bin tool. Agents will read binary file to respond NMS request.
  • In the binary file, A parent is stored first, followed by its last-child to first-child. Next, the structure of next this parent is stored. This structure is repeated until the entire tree is stored.
  • A parent or child is a record. Single record of binary file have format:
 <oid>, <nodeInfo>, 
 [id], [siblingOffset]/[distantSiblingOffset], [dataType], [dataLen], [data], 
 [{<IndexNumber>},{<IndexCount>, <IndexNodeInfo>, <IndexDataType>} ...]
  • where:
    • fields indicated by angle brackets (< >) are always present
    • fields in square brackets ([ ]) are optional depending on characteristics of the current node.
    • fields in braces ({ }) are optional but always occur together.

<oid> field

  • The microchip format only supports OIDs upto 255. The following is an workaround to store OID greater than 255.
  • Format of OID:
  An OID is a series of (one or more) octets. Bit 8 of each octet indicates whether it is the last in the series: bit 8 of the last octet is zero;
  bit 8 of each preceding octet is one. Bits 7 to 1 of the octets in the series collectively encode the OID. Conceptually, these groups of bits are
  concatenated to form an unsigned binary number whose most significant bit is bit 7 of the first octet and whose least significant bit is bit 1 of 
  the last octet. The OID shall be encoded in the fewest possible octets, that is, the leading octet of the OID shall not have the value 0x80.
  
  • Example:
   The OID               encode of OID in binary file (hex)
      4                         BYTE(0x04)
      1                         BYTE(0x01)
    36061                      BYTE(0x80+ 0x02) BYTE(0x80 + 0x19) BYTE(0x5D)
   The OID = 36061 is decoded by 0x02*0x80*0x80 + 0x19*0x80 + 0x5D

<nodeInfo> field

  • information of node
  bit        when (set = 1)
  0          Node has sibling node
  1          Node has default data
  2          Node is sequence 
  3          Node is readable
  4          Node is a parent
  5          Node is writable 
  6          Node is able to modify
  7          Node has sibling field (in IndexNodeInfo this bit indicate that Indexes is imply)

[id] field

  • If this record is leaf, id that's reference to function services the record.

[distantSiblingOffset] field

  • If this record is a node [distantSiblingOffset] is enabled. Point to next node sibling.
  • In little-endian format.
  • The last node's distant offset is set to 0x00000000.

[siblingOffset] field

  • If this record is a leaf [siblingOffset] is enabled. Point to next leaf sibling.
  siblingOffset and distantSiblingOffset in this format is same function (point to next node sibling). 
  They're only differences:
     siblingOffset use with leaf node.
     distantSiblingOffset use with node.
  so it's same value.

[dataType], [dataLen], [data] fields

  • If this record is a leaf and has default data
    • [dataType] is type of leaf's data.
    • [dataLen] is length of data.
    • [data] is data on string.
  • The tool supports the following base data types defined in SNMPv1:
    • INTEGER: The integer data type is a signed integer in the range of -2,147,483,648 to 2,147,483,647.
    • OCTETSTRING: Octet strings are ordered sequences of 0 to 65,535 octets.
    • Gauge: Nonnegative integers that can increase or decrease but retain the maximum value reached. The limit of 2^32 -1.
    • TimeTicks: A hundredth of a second since some event. The limit of 2^32 -1.
    • Counter: Nonnegative integers that increase until they reach a maximum value (2^32 -1); then, the integers return to zero.
    • DisplayString: a special case of the octet string type where all the bytes are printable ASCII characters, include formatting characters such as CR and LF, and the C programming language string terminator character zero.
    • IpAddress: A four byte octet string in network order.
    • NetworkAddress: Used to indicate an address choice from one of the possible protocol families. Currently, only IP addresses are supported.
    • Opaque: An arbitrary encoding that is used to pass arbitrary information strings that do not conform to the strict data typing used by the mib.
    • SEQUENCE: An ordered list of objects, somewhat like a struct in the C language. Type of objects in sequence is same type of node.

[{<IndexNumber>}] and [{<IndexCount>, <IndexNodeInfo>, <IndexDataType>}] fields

  • If this record is sequence (an order list of objects),
    • <IndexNumber> is the number of INDEXes in sequence.
    • <IndexCount>: is id of index node in table
    • <IndexNodeInfo>: is info of index node
    • <IndexDataType>: is data type of index node
  • See example of accessing data in a table
  • Example:
    • trap node is a sequence to inform the NMS of a significant event (an extraordinary event has occurred at an agent) asynchronously. This sequence has two INDEXes, so we have:
     <IndexNumber> = 0x02
     with the 1st INDEX:
         <IndexCount> = 0x05
         <IndexNodeInfo> = 0x28
         <IndexDataType> = 0x02
     with the 2nd INDEX:
         <IndexCount> = 0x08
         <IndexNodeInfo> = 0xA4
         <IndexDataType> = 0x04
  In this example, trap is a table which has 4 columns: 
     trapReceiverNumber (1), trapEnabled (2), trapReceiverIPAddress (3), trapCommunity(4). 
     trapReceiverNumber (1), trapEnabled (2), trapReceiverIPAddress (3), trapCommunity(4). 
     trapReceiverNumber (1), trapEnabled (2), trapReceiverIPAddress (3), trapCommunity(4). 
  Each significant event will be a row defined in the trap table. 
  
  This example has two INDEXes: the 1st INDEX node is trapCommunity (4) and the 2nd INDEX node trapReceiverNumber (1) 
  Each INDEX is a node, so it has OID, info, data type.
  The 1st INDEX node is trapCommunity, which has id = 5, info is 0x28 and data type is INTEGER (0x02). so
         IndexCount = 0x04
         IndexNodeInfo = 0x28
         IndexDataType = 0x02
  The 2nd INDEX node is trapReceiverNumber, which has id = 8, info is 0xA4 and data type is DisplayString (0x04). so
         IndexCount = 0x01
         IndexNodeInfo = 0xA4
         IndexDataType = 0x04

Example

OID Tree

  • An example OID tree is given below:
Snmp mib oid tree example.jpg

Binary File

  • The corresponding binary file is mchip.bin and it has data describe in table below:
    • oid is <oid> fields.
    • info is <nodeInfo> fields.
    • dist is [distantSiblingOffset]/[siblingOffset] fields.
    • id is [id] fields.
    • defval is data fields, include [dataType], [dataLen], [data] fields.
    • index is index fields of sequence, include [{index_number} , {<IndexCount>, <IndexNodeInfo>, <indexDataType>, ...}].
Snmp mib binary example.jpg
  • The detail description of mchip.bin is illustrated in the diagram below:
    • The black arrow lines represent the OID tree structure.
    • The red and green lines represent pointers to data.
    • The dist field points to next sibling record. After parent record is it's children.
Snmp mib binary detail example.jpg

Build SNMP's PDU using BER