|
NetBurner 3.5.7
PDF Version |
Simple Network Management Protocol (SNMP) is an Internet standard protocol used to monitor and manage devices on IP networks. Originally developed in the late 1980s, SNMP has become the dominant protocol for network management across virtually every industry that deploys networked equipment.
Consider a facility with dozens or hundreds of networked embedded devices — sensors, controllers, gateways, and actuators spread across a building, factory floor, or campus. Each device has operational parameters that need monitoring (uptime, error counts, temperature, link status) and configuration that may need remote adjustment (IP addresses, thresholds, operating modes). Without a standard protocol, every vendor would invent its own monitoring interface, and integrators would face an impossible patchwork of proprietary tools.
SNMP provides a universal framework: any SNMP-capable device exposes a structured set of variables that any standard SNMP management tool can read, write, and monitor. This means a single network management system (NMS) can oversee devices from dozens of vendors using one protocol.
SNMP is widely deployed in:
In all these domains, the common thread is networked embedded devices that must be remotely monitored and managed at scale. This is exactly where NetBurner devices operate.
Manager and Agent.** SNMP follows a client-server model. The manager (also called the NMS) is software running on a workstation that polls devices and collects data. The agent is the software running on each managed device that responds to queries and sends notifications. A NetBurner device runs an SNMP agent.
MIB (Management Information Base).** A MIB is a structured collection of variables that an agent exposes. Think of it as a schema or data dictionary. MIB-II (RFC 1213) is the standard MIB implemented by virtually all SNMP-capable devices — it defines variables for system identification, network interfaces, IP, TCP, UDP, and SNMP protocol statistics. Vendors extend MIB-II with enterprise MIBs that expose device-specific variables.
OID (Object Identifier).** Every variable in a MIB is identified by a globally unique dotted-number sequence called an OID. For example, the system description variable sysDescr has OID 1.3.6.1.2.1.1.1.0. OIDs form a hierarchical tree administered by IANA, ensuring no two vendors accidentally use the same identifier.
Community Strings.** In SNMPv1 and SNMPv2c, access control is handled by community strings — essentially passwords sent in cleartext with each request. By convention, the read community defaults to "public" and the write community to "private", though these should always be changed in production. The NetBurner implementation supports up to 32 access classes via a bitmask system, allowing fine-grained access control beyond the basic read/write split.
Operations.** SNMP defines a small set of operations:
| Operation | Description |
|---|---|
| GET | Retrieve the value of a specific variable by OID |
| GETNEXT | Retrieve the next variable in the MIB tree (used to walk tables) |
| SET | Change the value of a writable variable |
| TRAP | Unsolicited notification sent from agent to manager when an event occurs |
Traps.** Unlike GET/SET which are manager-initiated, traps are sent by the agent to alert the manager about events such as device startup, authentication failures, link state changes, or application-specific conditions. Traps are sent to a configured trap destination IP address on UDP port 162.
The NetBurner SNMP package supports SNMPv1 and SNMPv2c. These versions use community-string authentication and are widely supported by management tools. SNMPv3, which adds encryption and stronger authentication, is not currently supported.
For most embedded and industrial deployments, SNMPv1/v2c with properly configured community strings on a secured network provides adequate security. If your application requires encrypted SNMP communication, consider layering additional network security (VPN, network segmentation) around your devices.
The NetBurner SNMP package provides a complete SNMP agent implementation for NetBurner devices. It includes:
snmptranslate utility compiles your MIB definition files into C++ source code, generating function stubs that you fill in with your application logicconfig_obj frameworkThe NetBurner MIB-II implementation provides full coverage with these exceptions:
ipForwarding variable is read-only and set to not-forwardingipRouteTable is read-only — it reflects current IP connections and ARP table routes but cannot be written toWorking with SNMP requires familiarity with MIB concepts, OID structure, and standard SNMP tools. While this guide introduces the basics, you will benefit from prior experience with tools like snmpwalk, snmpget, and snmpset. If you are new to SNMP, we recommend experimenting with these tools against the SimpleSNMP example before attempting custom MIBs.
The four common command-line tools are listed below. Most operating systems make them available. If not, a common source for the tools is Net-SNMP at https://www.net-snmp.org/, or there are Windows utilities included in C:\gitroot\nburn3\snmp\pcbin.
| Tool | Description |
|---|---|
snmpget | Get a single SNMP variable by OID |
snmpgetnext | Get the next variable following the specified OID |
snmpset | Set a single SNMP variable |
snmpwalk | Walk the entire SNMP tree (or a subtree) |
The SNMP protocol operates entirely on OIDs — dotted-number sequences like 1.3.6.1.2.1.1.1.0. It knows nothing about human-readable names like sysDescr. The translation from OID to name (and back) is performed by the SNMP tools by parsing MIB text files.
To walk all SNMP variables on a device at IP address 10.1.1.118 using the default read community "public":
To get a specific variable:
To set a writable variable (requires the write community string):
By convention, MIB definitions are not supposed to change once published. The SNMP tools cache parsed MIB data in a .index file within the $(NNDK_ROOT)/mibs directory.
Important:** If you modify any MIB text file in your project, you must delete the .index file so that a new index will be automatically generated when you run snmptranslate.exe. Otherwise your changes will appear to have no effect.
This level gets a basic SNMP agent running on your NetBurner device with MIB-II support. No custom MIB variables are defined — the agent responds to standard MIB-II queries for system information, network statistics, and interface data.
A complete working example is provided in $(NNDK_ROOT)/examples/snmp/SimpleSNMP.
Create the file overload/nbrtos/include/predef-overload.h in your project directory with the following content:
This is all that is needed to enable SNMP support. Unlike NetBurner 2.x, no system library rebuild is required.
Every SNMP device must provide two identification variables that are reported as standard MIB-II values. Define these as global const char * variables in your application:
SYSDESC becomes sysDescr.0 (OID 1.3.6.1.2.1.1.1.0) — a human-readable description of your deviceSYSOID becomes sysObjectID.0 (OID 1.3.6.1.2.1.1.2.0) — a unique OID identifying your product type
Enterprise Numbers:** The OID prefix 1.3.6.1.4.1 is the IANA-managed enterprises subtree. The number 8174 is NetBurner's assigned Private Enterprise Number. For your own products, you should obtain your own enterprise number from IANA at https://www.iana.org/assignments/enterprise-numbers/.
Instantiate a global SnmpServlet object. This starts the SNMP agent listening on UDP port 161:
This replaces the 2.x StartSnmpProcessor() function call. The servlet integrates into the NetBurner servlet framework for event-driven packet processing.
SNMP configuration is managed by the global TheSnmpConfig object, which provides persistent storage via the config_obj framework. The configuration includes:
| Field | Type | Default | Description |
|---|---|---|---|
SysContact | config_string | "" | System contact person |
SysName | config_string | "" | System name |
SysLocation | config_string | "" | System location |
ReadCommunity | config_pass | "public" | Read community string |
WriteCommunity | config_pass | "public" | Write community string |
trap_destination | config_IPADDR4 | 0.0.0.0 | Trap destination IP |
trap_enable_flags | config_bool | Enable authentication traps |
These values are automatically persisted to flash. To save changes programmatically:
This replaces the 2.x SysInfo structure and its GetSysInfo()/SetSysInfo() functions. You no longer need to write custom flash storage code for SNMP configuration.
With just this code, your device will respond to standard SNMP queries:
SNMP specifies that community names are to be used for access control, but it does not specify how they are to be changed. The typical solution is to change them as part of your custom MIB. The example below will create a trivial custom MIB and implement the ability to change the community name settings using this MIB. You will find a completed version of this project in the NburnMIB example directory. There are five parts to this process.
For this example we are going to implement the absolute minimal MIB. Copy this text into a text file. We will assume that this is named Nburn_Cname_Mib.txt for the purposes of this discussion. The full text is shown below.
The NetBurner SNMP tools provide a utility snmptranslate that will convert a custom MIB into a .cpp source file to implement the MIB.
Important:** The MIB requires several inputs, specifically RFC1155-SMI.txt. Copy this file from \nburn\snmp\mibs to the directory where your custom MIB is located. Then run snmptranslate to generate the .cpp file:
C:\gitroot\nburn3\snmp\pcbin.The auto-generated file only has the outline for what you want to do. You will need to go everywhere there is a #warning in the file and add your custom code for implementing the actual SNMP variables. In this case there are six functions to fill in:
Note on IP address types:** In NetBurner 3.x, the SNMPReadObject and SNMPWriteObject classes do not have constructor overloads for IPADDR4. IP address MIB variables should use unsigned int for the function signatures and ASN_typeIpAddr for the ASN type constant. Cast between IPADDR4 and unsigned int in the function body.
We want these functions to report and set the variables we have defined. In NetBurner 3.x, SNMP configuration (community strings, trap destination, etc.) is managed by the global TheSnmpConfig object, which provides automatic persistent storage via the config_obj framework. Use SaveConfigToStorage() to persist changes to flash.
Write functions are called twice: once with bTest = 1 to validate the new value, and once with bTest = 0 to apply it.
The bodies of all six functions can be found in src/Nburn_Cname_Mib.cpp in this example project.
We normally allow you to read SNMP variables with the read community name, and set them with the write community name (think passwords). However, it would be a bit stupid if we could read the value of the write community name using only a READ_COMMUNITY_MASK; so one additional modification is made to the auto-generated .cpp file. We must change the read permissions of the WRITECOMMUNITY variable from READ_COMMUNITY_MASK to WRITE_COMMUNITY_MASK:
Edit your makefile to add the MIB .cpp file. In NetBurner 3.x, the makefile uses CPP_SRC and includes boilerplate.mk:
SNMP support in NetBurner 3.x is enabled by creating the file overload/nbrtos/include/predef-overload.h in your project directory with the following content:
This replaces the 2.x requirement of rebuilding the system libraries. No library rebuild is needed in 3.x.
In your main.cpp, the SNMP agent is started by instantiating a global SnmpServlet object. This replaces the 2.x StartSnmpProcessor() call:
The MIB text file you created must be located where the MIB tools can find it. Copy the MIB text file you just created to your project folder. Delete the .index file if one exists so a new index will automatically be created by the MIB tools. Your new MIB is now ready to be used with tools like snmpwalk.
The general process for implementing your own custom MIB closely follows the steps outlined above. One area that is somewhat different is tables. If you do not already know what an SNMP table is, you need to research the topic before reading this section.
When the snmptranslate utility parses a MIB definition for a table, it generates a different set of functions. This will be illustrated with the udpEntry table from MIB-II:
These three functions allow you to:
The first two functions are completely written by the snmptranslate utility. The final function needs to be filled in by the programmer. The programmer has three responsibilities:
AddTableElementudpEntry when a new UDP table element is created. This must include a void *data_el that encapsulates whatever data is needed to access this element.RemoveTableElementudpEntry whenever a UDP table element is to be destroyed. Important: This must include the same void *data_el passed in when the table was created.void *data_el into the specific MIB variables that make up the table element.The PutTableElements function as generated by snmptranslate:
Important:** At this time, the NetBurner SNMP system does not implement writing to dynamically created table elements. However, table elements can be created using the standard SNMP write variable definitions. If you have a specific need for dynamic writable tables, please contact NetBurner Support and we will assist you.
The default NetBurner implementation provides two community names: read and write. It is often desirable to have multiple community names providing multiple levels of access and object visibility.
The NetBurner SNMP implementation can support 32 different access classes. All visibility and access decisions are based on a 32-bit mask. Each SNMP element includes a mask parameter. This is the last element in the variable definitions:
The present code defines:
You could easily define an additional mask:
To connect these mask values to the community name you would have to write a function to convert community names to mask values, and place a pointer to that function in the function pointer:
Then somewhere in your system initialization you will need to set up the function pointer:
The NetBurner SNMP system provides for three types of traps:
The authentication failure trap and warm start traps are automatically generated within the SNMP system at the appropriate times. These traps are sent to the destination defined in TheSnmpConfig.trap_destination.
Basic traps without additional variables, generated by application code. If you pass in IPADDR::NullIP() as the destination, it uses the value stored in TheSnmpConfig.trap_destination:
Generic trap types:
| Value | Constant | Description |
|---|---|---|
| 0 | SNMP_COLDSTART_TRAP | Device has been powered on |
| 1 | SNMP_WARMSTART_TRAP | Device has been restarted |
| 2 | SNMP_LINKDOWN_TRAP | Network link went down |
| 3 | SNMP_LINKUP_TRAP | Network link came up |
| 4 | SNMP_AUTHENTICATIONFAIL_TRAP | SNMP authentication failure |
| 6 | SNMP_ENTERPRISE_TRAP | Enterprise-specific (custom) trap |
Custom traps with additional variable bindings use the function:
Important:** This requires that you write a callback function that will actually put the variables into the trap.
The ASN class provides the following methods for building trap variable bindings:
| Method | Description |
|---|---|
PutHeader(0x30) | Start a SEQUENCE container |
FixUpHeader() | Finalize SEQUENCE length |
PutOidFromString(oid) | Add an OID from string |
PutOctetString(str) | Add a string value |
PutInt(val) | Add an integer value |
PutUInt(val) | Add an unsigned integer |
PutIPAddr(addr) | Add an IP address |
PutCounter32(val) | Add a counter value |
PutGauge32(val) | Add a gauge value |
PutTimeTick(val) | Add a time tick value |