I wouldn't be surprised if you told me you have fallen in love with SNMP. Because it is so universal in network administration. Because it is a powerful all-round talent that supplies you with nearly every kind of information you need about whatever network device. Surely you love SNMP, if you know how to set it up on your machine. And if you know what OIDs are and what you need the MIB (files) for. And if your setup is fine, SNMP works reliably (at least it should), and you can live happily ever after.
But have you ever wondered what makes SNMP so universal? Why you can use it in the most heterogenous networks comprising many different devices, different computer architectures, different operating systems, and different platforms and their compilers that all store, process, and present data in different ways?
For example, different computer architectures have different internal data formats. Some of them use big-endian order to represent let's say integers, which means that they treat an integer with the most significant byte first. Whereas others process integers the little-endian way with the least significant byte first.
How would a service that needs to read this integer, after receiving it, know how to read it, the least or the most significant byte first? Regarding SNMP, how does an SNMP agent know in which format it needs to send an answer containing an integer value to the managing entity - in big-endian or little-endian? Obviously, applying the native method on every system may be pragmatic, but it is not a solution because you could not compare the resulting values.
It's time to get some tough facts straight!
As you surely remember, the communication partners in an SNMP conversation are the managing entity and the managed devices. They send and receive messages containing management information through the network via SNMP, no matter what operating systems, programming languages, and compilers are involved.
Obviously, independence is what you need to achieve. To be independent from operating systems, programming languages, and other sorts of components that create difference. How does SNMP become free? The answer is: Structure! More precisely, a commonly understood and standardized structure, known as SMI (which stands for Structure of Management Information).
Firstly, this includes a type-structure for the data that you use when using SNMP, or, in other words, a definition for the description of integers, strings, OIDs, and so on. And secondly, you need a binary mapping structure to express what happens to these data types, i.e. you need rules for how to transmit these data types in networks. Thanks to these definitions, the format becomes clear and independent. And since the format is a known standard, any machine in your network can receive and "understand" a given piece of SNMP management information and then decide on how to store it in the format that corresponds to its architecture. Of course, these principles also apply to the sending part of the SNMP communication.
Remember, for the Structure of Management Information to create independency, we need definitions for
The definition of SMI data types is derived from ASN.1 (Abstract Syntax Notation One). As its name says, ASN.1 is quite abstract and maybe not the best example for intuitive data structure definitions. However, it is highly effective. Let's see why. (Little side note: We can only cover a very small and simple subset of ASN.1 here. If you want more, check out, for example, ASN.1 related ISO/OSI sources.)
The ASN.1/SMI data types can be broken down into two categories: simple and complex. The former are called basic data types, the latter are so-called higher-level constructs. Let's look at an example of both data types. (SMI pro tip: SMI contains more data types than just those stemming from ASN.1.)
Basic Data Types
There's one basic data type that you must have heard about when dealing with SNMP. It is the OBJECT IDENTIFIER, or OID. The most common notation is the sequence of digits, for example
1.3.6.1.2.1.2
This OID includes the names of the respective OID tree nodes if you note it as defined in ASN.1 (You can find out more about the actual definition of OBJECT IDENTIFIER in the table below):
{iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1)}
In total, there are 11 basic data types for SMI MIB modules that have been defined in RFC-2578:
Here is an insight into some data type descriptions:
Data Type | Description |
---|---|
INTEGER | 32-bit integer with a value between -2^31 and 2^31-1 inclusive, or a value from a list of possible named constant values |
OCTET STRING | byte string representing arbitrary binary or textual data, up to 65,535 bytes long |
OBJECT IDENTIFIER | Its value is an ordered list of non-negative numbers, each called a sub-identifier. Maximum is 128 sub-identifiers (tuples), each one having a maximum value of 2^31-1. |
Opaque | uninterpreted ASN.1 value, needed for backward compatibility |
However, these are not the only basic data types, there are many more data types out there in the internet.
Let's move on to the higher-level constructs. Remember the MIB-2, one of the most important standard MIB module for SNMP? One of its sub-MIB modules is the Interfaces-MIB file (also well known as IF-MIB). You can find it in RFC 1213. Among many others, it contains the ifPhysAddress entry, an instance of the higher-level construct OBJECT-TYPE, which is used to specify the data type, status, and semantics of a managed object, in this case the physical address of an interface.
ifPhysAddress OBJECT-TYPE
SYNTAX PhysAddress
ACCESS read-only
STATUS mandatory
DESCRIPTION
“The interface’ address at the protocol layer
immediately ‘below’ the network layer in the
protocol stack. For interfaces which do not have
such an address (e.g., a serial line), this object
should contain an octet string of zero length.”
: := { ifEntry 6 }
PS: How do you know which OID belongs to the object ifPhysAddress? Take the OID of ifEntry and add a 6! (Umm... What is an OID?)
Other higher-level constructs are, for example, the MODULE IDENTITY and NOTIFICATION TYPE constructs. You want more? See RFC 2578.
After defining the data types and constructs, it's now time to take a look at the rules that define how SMI object instances are sent through a network. They are called Basic Encoding Rules (BER). The structure that they provide is TLV - which means Type, Length, and Value. This order is always the same. Yes, always. This way, a byte stream sent through a network is recognized immediately on every machine. Let's illustrate this with (part of) an SNMP message, say, an SNMP request. Every request needs a request ID. For our example, we will use the ID 9336.
Binary value | 0010 | 0010 | 0010 0100 0111 1000 | |
Bytestream (hex value) | 02 | 02 | 24 87 | |
BER | Type | Length | Value | |
Meaning | Integer | 2 Bytes | 9336 | |
Direction | → | → | → |
With these rules in place, every entity in the SNMP communication knows exactly how to interpret the sent or received bytes and translate them to the defined data types and constructs, regardless of the entity's own implementation and platform.
SMI offers a unified basis for definitions that regard the management information and their transfer in networks, for the sake of platform independence. SMI belongs to MIB and MIB belongs to SNMP. They are all inextricably tied together.
Stay tuned on our SNMP blog series if at least one of the following questions has already crossed your mind: