You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					182 lines
				
				6.2 KiB
			
		
		
			
		
	
	
					182 lines
				
				6.2 KiB
			| 
											2 weeks ago
										 | 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 */ |