DZone 's Guide to


Learn about the GET and SET operations in terms of attempting SNMP with RESTful mapping, along with some HATEOAS tips and tricks.

· Integration Zone ·
Free Resource

Welcome back! This is Part II of our RESTful mapping attempt of SNMP protocol. Last time, we looked at the basics of this mapping — starting from OIDs and SNMP objects. Today, we'll discuss mapping the GET and SET operations with some hints on HATEOAS guidelines.


A first security option can be represented by the HTTP basic authentication “realm.” That is the string assigned by the server to identify the protection space of the Request-URI. It may be used to resemble the context/contextEngineID depicted in SNMP protocol and represented in the RFC 4088 URI scheme.

Thanks to HTTP capabilities and configuration parameters, according to the same functionalities provided by SNMP, it is up to the ROA architect together with the MIB specification to define and implement resource specificities and security constraints and behaviors. When doing an HTTP GET operation on a resource, for example, the user may simply receive the data back, whereas another resource may ask for username and password or it may refuse the access and so on according to MIB definition and needs. The responding device may render each resource (MIB object) and fields as read-only or not available for reading (for any reason) and so on.

With respect to actual networking security, is reasonable that HTTPS intrinsic security replaces SNMPv3 capabilities and it is theoretically even possible to apply this protocol usage in a more aimed and fine-grained way — specific resources as a whole or filtered resources parts may require the use of HTTPS while other resources may need HTTP basic authentication only, and so on.

Giving the HTTP basic authentication and enhanced security provided by HTTPS, the actual mapping between SNMPv2/v3 security capabilities and HTTP(S) is a surplus and no longer considered. Except for OID mapping and operations on resources, the idea described here considers the use of HTTP(S) authentication as mandatory to reflect the proper and correct use of the protocol (also considering that HTTP(S) security level is not inferior to SNMPv2/v3 one).

As said, then, it is up to MIB definition and ROA architect to provide the correct behavior of the resources according to security and users’ profiles and permissions.

Tree Parent Objects Mapping

When the user does a request on resources that do not represent actual value objects (either scalar or tabular), mapped to MIB elements without actual content (sub-trees, instead of leaves), then the HTTP responses and the REST concepts still fulfill the uniform interface — but the representation will describe the contained objects. For example, OID represents the .iso.org.dod.internet.mgmt.mib-2.alarmMIB.alarmObjects.alarmActive object and is not a leaf object itself (it contains alarmActiveTable at, so its representation shall necessarily describe the actual objects it contains.

Requesting the alarmActive resource at OID will output a linked list of its children objects (and actual resources). For this example, the HTTP response body will contain links for these objects: alarmActiveTable, alarmActiveVariableTable, and all other tabular and scalar objects in this MIB area.

The actual output format contained in the HTTP response may easily depend on application or users’ needs.

This behavior still complies with REST and RESTful concepts, provides resources information, links resources between themselves, and describes a fully connected environment in which even resource containers are reachable and manageable as resources themselves. Simple output in this situation can leverage HTML5 or XHTML through <dl>/<dt>/<dd> sequences, <table> tags, and similar or specific XML, YAML, or JSON formats. The goal, again, is to keep a uniform interface for requests and responses, favoring MIB navigation and linking between resources whether the user does requests on MIB tree objects that are not leaves or on actual MIB data objects.

GetBulk and GetNext Requests Mapping

In order to complete the set of SNMP reading operations, there is the need to take care of GetNextRequest and GetBulkRequest. They are quite similar, in which GetBulkRequest is a sort of optimized version of the GetNextRequest operation. The GetNextRequest discovers available variables and values. The response contains the lexicographically next variable in the MIB. It is possible to walk the whole MIB with iterative requests starting at OID 0.

As per GetRequest, even GetNextRequest can specify columns filtering. The GetBulkRequest, instead, returns a set of multiple variable bindings (variables plus values) according to the request. The request can also specify max-repetitions and non-repeaters fields for further control. When asking for a simple OID not corresponding to an actual object but to a sub-tree (i.e., for the whole iso.org.dod.internet MIB), the requestor receives links to sub-resources and sub-trees.

The user can automatically (or manually, for the human user) navigate them to explore the MIB or even automatically build its own data structure and content representation. It’s even possible to navigate the MIB through a sequence of RESTful GET operations and produce graphical views of the MIB (such as here or here) or directly ask for a graphical format of the same and so on.

A possible example of RESTful GET request to retrieve the MIB above could be something like this:

GET / HTTP/1.1
Host: example.com:80
Accept: text/plain

Depending on the request, the acceptable types may differ: Accept: application/xml for W3C standard XML or Accept: text/html for classic HTML content and so on. The response to this request shall obviously contain the required content-type (whether available) and all the standard-required fields, together with the properly formatted content associated with required resource.

HTTP/1.1 200 OK
Content-Type: text/plain; -8
Date: Saturday, 26 April 2014 9:22:34 PM CEST
Server: RESTful SNMP 1.0
Connection: close
Directory: http://example.com:80/
Management (mgmt): http://example.com:80/
Experimental: http://example.com:80/
Private: http://example.com:80/
Security: http://example.com:80/
SNMPv2: http://example.com:80/
mail: http://example.com:80/

These above, considering text/plain as request/response content-type, is a pure list of key-value pairs. Whether, for example, application/XML is needed, an example of (part of) the answer could be something like:

  <name>Management (mgmt)</name>

Or, when it's classic text:

<a href=”http://example.com:80/”>SNMPv2</a>

And so on, depending on requirements, specifications, and user needs. Limits to the actual format are the available MIME types.

For these reasons, the uniform interface could be considered a limitation with respect to Get{Bulk; Next}Request of SNMP protocol. Anyway, the uniform interface and usability of HTTP GET request as described above allows more flexibility and filtering options, leaving to application specificities and user needs the capability to browse literally through the MIB or to send multiple different (uniform) requests to many resources that can be later manipulated or computed in other ways to produce different results.

Since MIB represents a hierarchical data structure called a tree, both human and automatic users may adopt at least four possible tree traversal methods: pre-order, in-order, post-order, or level-order (breadth-first). Obviously, the ROA architect and designers can do more customizations to provide specific content in the link, location, or content-location headers in HTTP response or even provide specific clients that, according to GetBulkRequest or GetNExtRequest behaviors, may translate such behaviours in specific sequences of HTTP GET operations through the uniform REST interface.

The basics of this idea, however, still follow the REST and ROA concepts and require that the requesting an object (scalar, tabular, or sub-tree) shall provide all information to retrieve associated objects (mainly for sub-trees) in order to create a fully connected set of resources that can be browsed and navigated both automatically and manually.

SetRequest Mapping

Till now, simple reading operations (SNPM GET{Bulk; Next}Request corresponding to HTTP GET) have been considered. For writing operations, applying the uniform interface base concepts depicted above, the URI structures are, obviously, the same. For writing, an HTTP request body is required that contains the data for the MIB object.

Writing both scalar and tabular objects uses the HTTP PUT operation: scalar objects, when identified by URI, will respond to the HTTP PUT request modifying their value with the one provided in the HTTP request coming from the (human or software) agent.

For tabular objects, when identified by URI with possibly indexing and filtering components, the same writing capability is uniformly provided, stated that, obviously, the HTTP request body shall contain all needed data.

For scalar objects, the URI immediately identifies them, so the HTTP entity-body of the PUT operation contains the simple value. Using the HTTP entity-body will help the receiving system managing it, considering the Content-Type field describing the actual format of the data. It is simpler using the common “query string” mode (key=value): URI_ROOT/{resource}?objectName=newValue.

Since the key is already identified by the URI, URI_ROOT/slashed/OID/for/the/scalar/object?newValue could be used. The HTTP request will also contain the value description in the Content-Type field; this requires some care for URI encoding whether special characters are contained in the scalar object value.

For tabular objects, once the user knows the indexes, the PUT method is the only way to interact with a resource of the MIB: using the same GET scheme to create the URI, the HTTP entity-body shall contain the values for each and all the fields in the URI request.

If the URI aims a row with fixed columns (URI_ROOT/1/3/6/1/2/1/118/1/1/2/a_name/1342/1/4;6;9), the entity-body shall contain a set of key/value pair corresponding to the fields to be set. This can be done in any format, from JSON to XML to simple text-encoded key/value pairs like 7=42¶8=1701¶9=1974¶10=1975 and so on.

The usage of key/value pairs can be easily used for single rows modification putting them in the query string, with the usual common way beingURI_ROOT/1/3/6/1/2/1/118/1/1/2/?4=42&6=1701. When the user must write multiple rows, even if it is still possible to address each of them via specifically built entity-body contents, the suggestion is transforming the set of indexes in a set of distinct PUT operations, if possible, to better keep interface consistency.

Following above considerations, if the user must create a resource for which (any reason) it does not know its full URI, the SetRequest-equivalent operation must use the POST method. If some tables have specific server-side rules to build the indexes and these rules are not public, a possible POST request may be URI_ROOT/slashed/OID/for/the/tabular/object/list,of,columns that has the key-value pairs in the HTTP entity-body.

The system shall reply to the POST request with a “201 Created” status code response and the Location header field describing the full URI with the new system-built index that, as said, may rely on an internal DB indexing number, on a secret algorithm, or whatever. In this situation only, the POST may be used and the final URI would be: URI_ROOT/slashed/OID/for/the/tabular/object/system-built_index/list,of,column. And with this complete URI ,the user will be able to, from that moment on, autonomously GET from or PUT to that resource.

And that's all for this second part! In the third part, we'll add more behaviors to this mapping by looking at how to manage SNMP traps.

Check out the other articles here:

http, integration, restful, snmp, tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}