| SNMPv1 agent for lwIP |
| |
| Author: Christiaan Simons |
| |
| This is a brief introduction how to use and configure the SNMP agent. |
| Note the agent uses the raw-API UDP interface so you may also want to |
| read rawapi.txt to gain a better understanding of the SNMP message handling. |
| |
| 0 Agent Capabilities |
| ==================== |
| |
| SNMPv1 per RFC1157 |
| This is an old(er) standard but is still widely supported. |
| For SNMPv2c and v3 have a greater complexity and need many |
| more lines of code. IMHO this breaks the idea of "lightweight IP". |
| |
| Note the S in SNMP stands for "Simple". Note that "Simple" is |
| relative. SNMP is simple compared to the complex ISO network |
| management protocols CMIP (Common Management Information Protocol) |
| and CMOT (CMip Over Tcp). |
| |
| MIB II per RFC1213 |
| The standard lwIP stack management information base. |
| This is a required MIB, so this is always enabled. |
| When builing lwIP without TCP, the mib-2.tcp group is omitted. |
| The groups EGP, CMOT and transmission are disabled by default. |
| |
| Most mib-2 objects are not writable except: |
| sysName, sysLocation, sysContact, snmpEnableAuthenTraps. |
| Writing to or changing the ARP and IP address and route |
| tables is not possible. |
| |
| Note lwIP has a very limited notion of IP routing. It currently |
| doen't have a route table and doesn't have a notion of the U,G,H flags. |
| Instead lwIP uses the interface list with only one default interface |
| acting as a single gateway interface (G) for the default route. |
| |
| The agent returns a "virtual table" with the default route 0.0.0.0 |
| for the default interface and network routes (no H) for each |
| network interface in the netif_list. |
| All routes are considered to be up (U). |
| |
| Loading additional MIBs |
| MIBs can only be added in compile-time, not in run-time. |
| There is no MIB compiler thus additional MIBs must be hand coded. |
| |
| Large SNMP message support |
| The packet decoding and encoding routines are designed |
| to use pbuf-chains. Larger payloads than the minimum |
| SNMP requirement of 484 octets are supported if the |
| PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your |
| local requirement. |
| |
| 1 Building the Agent |
| ==================== |
| |
| First of all you'll need to add the following define |
| to your local lwipopts.h: |
| |
| #define LWIP_SNMP 1 |
| |
| and add the source files in lwip/src/core/snmp |
| and some snmp headers in lwip/src/include/lwip to your makefile. |
| |
| Note you'll might need to adapt you network driver to update |
| the mib2 variables for your interface. |
| |
| 2 Running the Agent |
| =================== |
| |
| The following function calls must be made in your program to |
| actually get the SNMP agent running. |
| |
| Before starting the agent you should supply pointers |
| to non-volatile memory for sysContact, sysLocation, |
| and snmpEnableAuthenTraps. You can do this by calling |
| |
| snmp_set_syscontact() |
| snmp_set_syslocation() |
| snmp_set_snmpenableauthentraps() |
| |
| Additionally you may want to set |
| |
| snmp_set_sysdescr() |
| snmp_set_sysobjid() (if you have a private MIB) |
| snmp_set_sysname() |
| |
| Also before starting the agent you need to setup |
| one or more trap destinations using these calls: |
| |
| snmp_trap_dst_enable(); |
| snmp_trap_dst_ip_set(); |
| |
| In the lwIP initialisation sequence call snmp_init() just after |
| the call to udp_init(). |
| |
| Exactly every 10 msec the SNMP uptime timestamp must be updated with |
| snmp_inc_sysuptime(). You should call this from a timer interrupt |
| or a timer signal handler depending on your runtime environment. |
| |
| An alternative way to update the SNMP uptime timestamp is to do a call like |
| snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to |
| a lower frequency). Another one is to not call snmp_inc_sysuptime() or |
| snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. |
| This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside |
| snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only |
| when it's queried (any function which need "sysuptime" have to call |
| snmp_get_sysuptime). |
| |
| |
| 3 Private MIBs |
| ============== |
| |
| If want to extend the agent with your own private MIB you'll need to |
| add the following define to your local lwipopts.h: |
| |
| #define SNMP_PRIVATE_MIB 1 |
| |
| You must provide the private_mib.h and associated files yourself. |
| Note we don't have a "MIB compiler" that generates C source from a MIB, |
| so you're required to do some serious coding if you enable this! |
| |
| Note the lwIP enterprise ID (26381) is assigned to the lwIP project, |
| ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP |
| MAINTAINERS! |
| |
| If you need to create your own private MIB you'll need |
| to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html |
| |
| You can set it by passing a struct snmp_obj_id to the agent |
| using snmp_set_sysobjid(&my_object_id), just before snmp_init(). |
| |
| Note the object identifiers for thes MIB-2 and your private MIB |
| tree must be kept in sorted ascending (lexicographical) order. |
| This to ensure correct getnext operation. |
| |
| An example for a private MIB is part of the "minimal Unix" project: |
| contrib/ports/unix/proj/minimal/lwip_prvmib.c |
| |
| The next chapter gives a more detailed description of the |
| MIB-2 tree and the optional private MIB. |
| |
| 4 The Gory Details |
| ================== |
| |
| 4.0 Object identifiers and the MIB tree. |
| |
| We have three distinct parts for all object identifiers: |
| |
| The prefix |
| .iso.org.dod.internet |
| |
| the middle part |
| .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress |
| |
| and the index part |
| .1.192.168.0.1 |
| |
| Objects located above the .internet hierarchy aren't supported. |
| Currently only the .mgmt sub-tree is available and |
| when the SNMP_PRIVATE_MIB is enabled the .private tree |
| becomes available too. |
| |
| Object identifiers from incoming requests are checked |
| for a matching prefix, middle part and index part |
| or are expanded(*) for GetNext requests with short |
| or inexisting names in the request. |
| (* we call this "expansion" but this also |
| resembles the "auto-completion" operation) |
| |
| The middle part is usually located in ROM (const) |
| to preserve precious RAM on small microcontrollers. |
| However RAM location is possible for a dynamically |
| changing private tree. |
| |
| The index part is handled by functions which in |
| turn use dynamically allocated index trees from RAM. |
| These trees are updated by e.g. the etharp code |
| when new entries are made or removed form the ARP cache. |
| |
| /** @todo more gory details */ |