3. SNMP DPI PROTOCOL This section describes the actual protocol used between the SNMP agent and sub-agents. 3.1 CONNECTION ESTABLISHMENT In a TCP/IP environment, the SNMP agent listens on an arbitrary TCP/UDP port for a connection request from a sub-agent. It is important to realize that a well-known port is not used: every invocation of the SNMP agent will potentially result in a different TCP/UDP port being used. A sub-agent needs to determine this port number to establish a connection. The sub-agent learns the port number from the agent by sending it one conventional SNMP get-request PDU. The port numbers are maintained by the SNMP agent as the objects whose identifiers are: 1.3.6.1.4.1.2.2.1.1.0 dpiPort.0 (old DPI 1.x form) 1.3.6.1.4.1.2.2.1.1.1.0 dpiPortForTCP.0 1.3.6.1.4.1.2.2.1.1.2.0 dpiPortForUDP.0 These variables are registered under the IBM enterprise-specific tree. See 4, "DPI 2.0 MIB definition" for more information. The SNMP agent replies with a conventional SNMP response PDU that contains the port number to be used. This response is examined by the sub-agent and the port number is extracted. The sub-agent then establishes the connection to the specified port. On the surface, this procedure appears to mean that the sub-agent must be able to create and parse SNMP packets, but this is not the case. A DPI Application Programming Interface (API) normally provides a library routine, query_DPI_port(), which can be used to generate and parse the required SNMP packets. This very small routine (under 100 lines of C), does not greatly increase the size of any sub-agent. NOTE: Since this RFC does not define an API, the actual code of and interface to a query_DPI_port() type of function depends on the implementation. For completeness, byte-by-byte descriptions of the packets to be generated by an SNMP DPI API routine query_DPI_port() are provided below. This is probably of little interest to most readers and reading the source of a query_DPI_port() function provides much of
the same information. 3.1.1 SNMP PDU TO GET THE AGENT'S DPI PORT As noted, before a TCP/UDP connection to the SNMP agent can be made, the sub-agent must learn which port that the agent is listening on. To do so, it can issue an SNMP GET for the variable dpiPortForTCP.0 (1.3.6.1.4.1.2.2.1.1.1.0) or variable dpiPortForUDP.0 (1.3.6.1.4.1.2.2.1.1.2.0). The SNMP PDU can be constructed as shown below. This PDU must be sent to UDP port 161 on the host where the agent runs (probably the same host where the sub-agent runs). The (SNMPv1) packet shown below is for the TCP port.
+-----------------------------------------------------------------+ | Table 1 (Page 1 of 2). SNMP GET PDU for dpiPortForTCP.0 | +---------------+----------------+--------------------------------+ | OFFSET | VALUE | FIELD | +---------------+----------------+--------------------------------+ | 0 | 0x30 | ASN.1 header | +---------------+----------------+--------------------------------+ | 1 | 37 + len | PDU_length, see formula below | +---------------+----------------+--------------------------------+ | 2 | 0x02 0x01 0x00 | SNMP version: | | | | (integer,length=1,value=0) | +---------------+----------------+--------------------------------+ | 5 | 0x04 | community name (string) | +---------------+----------------+--------------------------------+ | 6 | len | length of community name | +---------------+----------------+--------------------------------+ | 7 | community name | varies | +---------------+----------------+--------------------------------+ | 7 + len | 0xa0 0x1c | SNMP GET request: | | | | request_type=0xa0,length=0x1c | +---------------+----------------+--------------------------------+ | 7 + len + 2 | 0x02 0x01 0x01 | SNMP request ID: | | | | integer,length=1,ID=1 | +---------------+----------------+--------------------------------+ | 7 + len + 5 | 0x02 0x01 0x00 | SNMP error status: | | | | integer,length=1,error=0 | +---------------+----------------+--------------------------------+ | 7 + len + 8 | 0x02 0x01 0x00 | SNMP index: | | | | integer,length=1,index=0 | +---------------+----------------+--------------------------------+ | 7 + len + 11 | 0x30 0x11 | varBind list, length=0x11 | +---------------+----------------+--------------------------------+ | 7 + len + 13 | 0x30 0x0f | varBind, length=0x0f | +---------------+----------------+--------------------------------+ | 7 + len + 15 | 0x06 0x0b | Object ID, length=0x0b | +---------------+----------------+--------------------------------+
+-----------------------------------------------------------------+ | Table 1 (Page 2 of 2). SNMP GET PDU for dpiPortForTCP.0 | +---------------+----------------+--------------------------------+ | OFFSET | VALUE | FIELD | +---------------+----------------+--------------------------------+ | 7 + len + 17 | 0x2b 0x06 0x01 | Object-ID: | | | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.1 | | | 0x02 0x01 0x01 | Object-instance: 0 | | | 0x01 0x00 | | +---------------+----------------+--------------------------------+ | 7 + len + 28 | 0x05 0x00 | null value, length=0 | +---------------+----------------+--------------------------------+ | NOTE: Formula to calculate "PDU_length": | | | | PDU_length = length of version field and string tag (4 bytes)| | + length of community length field (1 byte) | | + length of community name (depends...) | | + length of SNMP GET request (32 bytes) | | | | = 37 + length of community name | +-----------------------------------------------------------------+ 3.1.2 SNMP PDU CONTAINING THE RESPONSE TO THE GET Assuming that no errors occurred, the port is returned in the last few octets of the received packet. In the simple case, where the port number will be between 1024 and 16,385, the format of the packet is shown below. Note: In practice, the port number can be any positive number in the range from 1 through 65,535. A port number of 0 means that the agent does not have a dpiPort defined for the requested protocol. So the actual port value maybe in the last 1, 2 or 3 octets. The sample implementation code shows how to handle the response to cover all those cases, including error conditions. Note: The (SNMPv1) packet shown below is for the TCP port. +-----------------------------------------------------------------+ | Table 2 (Page 1 of 3). SNMP RESPONSE PDU for dpiPortForTCP.0 | +---------------+----------------+--------------------------------+ | OFFSET | VALUE | FIELD | +---------------+----------------+--------------------------------+ | 0 | 0x30 | ASN.1 header | +---------------+----------------+--------------------------------+ | 1 | 39 + len | length, see formula below | +---------------+----------------+--------------------------------+
+-----------------------------------------------------------------+ | Table 2 (Page 2 of 3). SNMP RESPONSE PDU for dpiPortForTCP.0 | +---------------+----------------+--------------------------------+ | OFFSET | VALUE | FIELD | +---------------+----------------+--------------------------------+ | 2 | 0x02 0x01 0x00 | version | | | | (integer,length=1,value=0) | +---------------+----------------+--------------------------------+ | 5 | 0x04 | community name (string) | +---------------+----------------+--------------------------------+ | 6 | len | length of community name | +---------------+----------------+--------------------------------+ | 7 | community name | | +---------------+----------------+--------------------------------+ | 7 + len | 0xa2 0x1e | SNMP RESPONSE: | | | | request_type=0xa2,length=0x1e | +---------------+----------------+--------------------------------+ | 7 + len + 2 | 0x02 0x01 0x01 | SNMP request ID: | | | | integer,length=1,ID=1 | +---------------+----------------+--------------------------------+ | 7 + len + 5 | 0x02 0x01 0x00 | SNMP error status: | | | | integer,length=1,error=0 | +---------------+----------------+--------------------------------+ | 7 + len + 8 | 0x02 0x01 0x00 | SNMP index: | | | | integer,length=1,index=0 | +---------------+----------------+--------------------------------+ | 7 + len + 11 | 0x30 0x13 | varBind list, length=0x13 | +---------------+----------------+--------------------------------+ | 7 + len + 13 | 0x30 0x11 | varBind, length=0x11 | +---------------+----------------+--------------------------------+ | 7 + len + 15 | 0x06 0x0b | Object ID, length=0x0b | +---------------+----------------+--------------------------------+ | 7 + len + 17 | 0x2b 0x06 0x01 | Object-ID: | | | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.1 | | | 0x02 0x01 0x01 | Object-instance: 0 | | | 0x01 0x00 | | +---------------+----------------+--------------------------------+ | 7 + len + 28 | 0x02 0x02 | integer, length=2 | +---------------+----------------+--------------------------------+ | 7 + len + 30 | MSB LSB | port number (MSB, LSB) | +---------------+----------------+--------------------------------+
+-----------------------------------------------------------------+ | Table 2 (Page 3 of 3). SNMP RESPONSE PDU for dpiPortForTCP.0 | +---------------+----------------+--------------------------------+ | NOTE: Formula to calculate "PDU_length": | | | | PDU_length = length of version field and string tag (4 bytes)| | + length of community length field (1 byte) | | + length of community name (depends...) | | + length of SNMP RESPONSE (34 bytes) | | | | = 39 + length of community name | +-----------------------------------------------------------------+ 3.2 SNMP DPI PACKET FORMATS Each request to, or response from, the agent or sub-agent is constructed as a "packet" and is written to the stream. Each packet is prefaced with the length of the data remaining in the packet. The length is stored in network byte order, the most significant byte (MSB) first, least significant byte (LSB) last. If we consider a stream connection (like TCP), the receiving side will read the packet by doing something similar to: unsigned char len_bfr[2]; unsigned char *bfr; int len; read(fd,len_bfr,2); len = len_bfr[0] * 256 + len_bfr[1]; bfr = malloc(len); read(fd,bfr,len); Note: The above example makes no provisions for error handling or a read returning less than the requested amount of data,and it is not intended to be used literally. 3.2.1 DPI PACKET HEADER The first part of every packet identifies the application protocol being used as well as some version information. The protocol major version is intended to indicate, in broad terms, what version of the protocol is used. The protocol minor version is intended to identify major incompatible versions of the protocol. The protocol release is intended to indicate incremental modifications to the protocol. The constants that are valid for these fields are defined in Table 15.
The next field, present in all packets, is the packet ID. It contains packet identification that can help an agent or sub-agent match responses with request. This is useful with UDP connections over which packets can be lost. The packet ID is a monotonically increasing unsigned 16-bit integer which wraps at its maximum value. The next field, present in all packets, is the packet type. It indicates what kind of packet we're dealing with (OPEN, REGISTER, GET, GETNEXT, GETBULK, SET, COMMIT, UNDO, TRAP, RESPONSE, UNREGISTER, or CLOSE). The permitted values for this field are defined in Table 16. +-----------------------------------------------------------------+ | Table 3. SNMP DPI packet header. Present in all packets. | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type | +------------+----------------------------------------------------+ From this point onwards, the contents of the packet are defined by the protocol being used. The remainder of this section describes: o Layout of packets for the SNMP DPI protocol, version 2.0. o Constants as defined with this version of the protocol. 3.2.2 OPEN In order for a sub-agent to communicate with a DPI capable SNMP agent, it must first send an SNMP DPI OPEN request to the agent to setup the "connection" with that agent. Such a packet contains the standard SNMP DPI header plus OPEN specific data. This data consists of:
o a timeout value (in seconds). This is a requested timeout value to be used for all requests for objects for which there is no timeout value specified for the sub-tree under which the object is registered. If you specify a zero timeout value, then the agent will use its own default timeout value. If you want a larger value than the default value, then you can specify it here. However, the agent may have a maximum value that you can never exceed. If you do ask for a larger timeout than that maximum, the agent will set it at the maximum it accepts. o the maximum number of varBinds per DPI packet that the sub-agent is prepared to handle. o Selected character set to be used for the representation of the OBJECT ID strings and DisplayStrings. The choices are the native character set (0) or the ASCII character set (1). See 3.3.5, "Character set selection" for more information in character set selection. An agent may choose to support only the native character set. o null terminated sub-agent ID, which is a unique ASN.1 OBJECT identifier, so in dotted ASN.1 notation. This string is represented in the selected character set. o null terminated sub-agent description, which is a DisplayString describing the sub-agent. This string is represented in the selected character set. This may be the null-string if there is no description. o optionally a password that the agent uses to validate the sub-agent. It depends on the agent implementation if a password is required. If no password is passed, the length must be specified as zero. The sub-agent must expect a response indicating success or failure. See Table 19 for the valid codes in a DPI RESPONSE to a DPI OPEN request. If the error_code in the RESPONSE is not SNMP_ERROR_DPI_noError, then the agent closes the connection.
+-----------------------------------------------------------------+ | Table 4. Layout SNMP DPI OPEN packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_OPEN | +------------+----------------------------------------------------+ | 8 | requested overall timeout (seconds, MSB to LSB) | +------------+----------------------------------------------------+ | 10 | max varBinds per DPI packet (MSB to LSB) | +------------+----------------------------------------------------+ | 12 | Selected character set (0=Native, 1=ASCII) | +------------+----------------------------------------------------+ | 13 | null terminated sub-agent ID (OID) | +------------+----------------------------------------------------+ | 13+L1 | null terminated sub-agent Description | +------------+----------------------------------------------------+ | 13+L2 | password length (zero if no password, MSB to LSB) | +------------+----------------------------------------------------+ | 15+L2 | password (if any) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = strlen(sub-agent ID) + 1 | | o L2 = L1 + strlen(sub-agent Description) + 1 | | o OID and Description strings use selected character set | +-----------------------------------------------------------------+ 3.2.3 CLOSE In order for a sub-agent to close the "connection" with the DPI capable SNMP agent, it must send an SNMP DPI CLOSE request to the agent. The agent will not send a response, but closes the physical connection and implicitly unregisters any sub-trees related to the connection. An agent may also send to the sub-agent an SNMP DPI CLOSE packet that contains the standard SNMP DPI header plus CLOSE specific data. This
data consists of: o a reason code for closing. See Table 21 for a list of valid reason codes. +-----------------------------------------------------------------+ | Table 5. Layout SNMP DPI CLOSE packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_CLOSE | +------------+----------------------------------------------------+ | 8 | reason code (1 octet) | +------------+----------------------------------------------------+ 3.2.4 ARE_YOU_THERE An ARE_YOU_THERE packet allows a sub-agent to determine if it still has a DPI connection with the agent. This packet is necessary because a sub-agent passively awaits requests from an agent and normally will not detect problems with an agent connection in a timely manner. (In contrast, an agent becomes aware of any sub-agent connection problem in a timely manner because it sets a timeout when sending request). A sub-agent can send a SNMP DPI ARE_YOU_THERE packet to an agent which will then return a RESPONSE with a zero error code and a a zero error index if the connection is healthy. Otherwise, the agent may return a RESPONSE with an error indication. If the connection is broken, the sub-agent will see no response at all. An ARE_YOU_THERE packet contains the standard SNMP DPI header with no additional data.
+-----------------------------------------------------------------+ | Table 6. Layout SNMP DPI ARE_YOU_THERE packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_ARE_YOU_THERE | +------------+----------------------------------------------------+ 3.2.5 REGISTER In order to register a branch in the MIB tree, an SNMP sub-agent sends an SNMP DPI REGISTER packet to the agent. Such a packet contains the standard SNMP DPI header plus REGISTER specific data. This data consists of: o a requested priority. There are 2 special values, namely minus one (-1, requests best available priority) and zero (0, requests next better priority than the highest priority in use). Any other value requests a specific priority or the next best priority if already in use). The lower the number, the better the priority. An agent will send requests to only the one sub-agent that has registered with the best priority. The agent returns the actual priority assigned in the RESPONSE packet in the error_index field. o a requested timeout. If a zero value is specified, then the agent uses the timeout value specified in the DPI OPEN request. If you want a shorter or longer timeout value for this specific sub-tree, then you specify it here. The agent has a maximum timeout it will allow in this field. The agent will use this value (or its maximum) to await a response to requests for this sub-tree. o an indication as to whether the sub-agent wishes to handle MIB view selection (SNMPv1 community string authentication) in subsequent GET, GETNEXT or SET, COMMIT, UNDO requests. Not all DPI capable agents need to support this feature, but they must at least recognize this indication and give an appropriate
response if they do not support it. o an indication as to whether the sub-agent wishes to handle the GETBULK itself. If not, then the agent will translate a GETBULK into multiple GETNEXT requests. Not all DPI capable agents need to support this feature. They may opt to always translate a GETBULK into multiple GETNEXT requests. In this case the agent will send the appropriate RESPONSE to indicate this. o the group ID (sub-tree) to be registered (with trailing dot). The group ID is represented in the selected character set as specified in DPI OPEN packet. The agent will respond with an SNMP DPI RESPONSE packet indicating registration error or success. The packet ID of the response will be the same as that for the REGISTER request to which this is a response. The group ID will be the same as that specified in the REGISTER request. There will be no instance returned (e.g. NULL string for instance ID). The value will be an SNMP_TYPE_NULL value with a zero length.
+-----------------------------------------------------------------+ | Table 7. Layout SNMP DPI REGISTER packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_REGISTER | +------------+----------------------------------------------------+ | 8 | requested priority (MSB to LSB) | +------------+----------------------------------------------------+ | 12 | timeout in seconds (MSB to LSB) | +------------+----------------------------------------------------+ | 14 | view selection (0 = you (agent) do, 1 = I do) | +------------+----------------------------------------------------+ | 15 | getbulk selection (0=use GetNext, 1=use GetBulk) | +------------+----------------------------------------------------+ | 16 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | NOTE: | | | | o group ID string uses selected character set | +-----------------------------------------------------------------+ 3.2.6 UNREGISTER In order to unregister a branch in the MIB tree, an SNMP sub-agent sends an SNMP DPI UNREGISTER packet to the agent. Such a packet contains the standard SNMP DPI header plus UNREGISTER specific data: a null terminated string (represented in the selected character set) representing the group ID in ASN.1 dotted notation and an indication as to the reason for the unregister (see table 14). The agent will respond with an SNMP DPI RESPONSE packet indicating error or success. The packet ID of the response will be the same as that for the UNREGISTER request to which this is a response. The group ID will be the same as that specified in the UNREGISTER request. There will be no instance returned (e.g. NULL string for
instance ID). The value will be an SNMP_TYPE_NULL value with a zero length. +-----------------------------------------------------------------+ | Table 8. Layout SNMP DPI UNREGISTER packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_UNREGISTER | +------------+----------------------------------------------------+ | 8 | reason code | +------------+----------------------------------------------------+ | 9 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | NOTE: | | | | o group ID string uses selected character set | +-----------------------------------------------------------------+ 3.2.7 GET When the SNMP agent receives a PDU containing an SNMP GET request for a variable that resides in a sub-tree registered by a sub-agent, it passes an SNMP DPI GET packet to the sub-agent. Such a packet contains the standard SNMP DPI header plus GET specific data: o the community name used in the SNMP PDU. The length is zero unless view handling was selected by the sub-agent. The length is also zero if the SNMP PDU was not in SNMPv1 format. o per varBind two null terminated strings (in the selected character set) representing the group and instance ID in ASN.1 dotted notation.
+-----------------------------------------------------------------+ | Table 9. Layout SNMP DPI GET packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_GET | +------------+----------------------------------------------------+ | 8 | community name length (MSB to LSB) | +------------+----------------------------------------------------+ | 10 | community name (if any) | +------------+----------------------------------------------------+ | 10+L1 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 10+L2 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 10+L3 | optionally more varBinds (group/instance ID pairs) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = length of community name | | o L2 = L1 + strlen(group ID) + 1 | | o L3 = L2 + strlen(instance ID) + 1 | | o group and instance ID strings use selected character set | +-----------------------------------------------------------------+ 3.2.8 GETNEXT When the SNMP agent receives a PDU containing an SNMP GETNEXT request for a variable for which a sub-agent may be authoritative, it passes an SNMP DPI GETNEXT packet to the sub-agent. Such a packet contains the standard SNMP DPI header plus GETNEXT specific data: o the community name used in the SNMP PDU. The length is zero unless view handling was selected by the sub-agent. The length is also zero if the SNMP PDU was not in SNMPv1 format. o per varBind two null terminated strings (in the selected
character set) representing the group and instance ID in ASN.1 dotted notation. +-----------------------------------------------------------------+ | Table 10. Layout SNMP DPI GETNEXT packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_GETNEXT | +------------+----------------------------------------------------+ | 8 | community name length (MSB to LSB) | +------------+----------------------------------------------------+ | 10 | community name | +------------+----------------------------------------------------+ | 10+L1 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 10+L2 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 10+L3 | optionally more varBinds (group/instance ID pairs) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = length of community name | | o L2 = L1 + strlen(group ID) + 1 | | o L3 = L2 + strlen(instance ID) + 1 | | o group and instance ID strings use selected character set | +-----------------------------------------------------------------+ 3.2.9 GETBULK When the SNMP agent receives a PDU containing an SNMP GETBULK request that includes variables for which a sub-agent may be authoritative, it checks if the sub-agent wants to handle the GETBULK itself (as specified at registration time). If so, it sends an SNMP DPI GETBULK packet to the sub-agent. Such a packet contains the standard SNMP DPI header plus GETBULK specific data:
o non-repeaters o max repetitions o per varBind two null terminated strings (in the selected character set) representing the group and instance ID in ASN.1 dotted notation. +-----------------------------------------------------------------+ | Table 11. Layout SNMP DPI GETBULK packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_GETBULK | +------------+----------------------------------------------------+ | 8 | non-repeaters (4 octets, MSB to LSB) | +------------+----------------------------------------------------+ | 12 | max-repetitions (4 octets, MSB to LSB) | +------------+----------------------------------------------------+ | 16 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 16+L1 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 16+L2 | optionally more varBinds (group/instance ID pairs) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = strlen(group ID) + 1 | | o L2 = L1 + strlen(instance ID) + 1 | | o group and instance ID strings use selected character set | +-----------------------------------------------------------------+ 3.2.10 SET, COMMIT AND UNDO When the SNMP agent receives a PDU containing an SNMP SET request for a variable that is in a sub-tree registered by a sub-agent, it passes one of 3 sequences of SNMP DPI packets to the sub-agent:
o SET, COMMIT This is the normal sequence. The SET request is the first phase. The sub-agent must verify that the SET request is valid and that the resources needed are available. The COMMIT request comes next. The sub-agent must now effectuate the SET request. o SET, UNDO If an SNMP packet has a SET request for multiple varBinds that reside in different sub-trees, then the agent first sends a SET to all sub-agents. If any sub-agent returns an error on the SET, then the agent sends UNDO to those sub-agents that returned no error on the SET, meaning the SET is being canceled. o SET, COMMIT, UNDO In the very rare circumstance where all sub-agents have responded error-free to a SET and where one of them fails to perform the COMMIT, then the agent sends an UNDO to all involved sub-agents (also those who completed COMMIT). Sub-agents should try, to the best of their ability, to never let a commit fail and to undo an already committed set if asked to do so. Such packets contain the standard SNMP DPI header plus SET specific data: o the community name used in the SNMP PDU. The length is zero unless view handling was selected by the sub-agent. The length is also zero if the SNMP PDU was not in SNMPv1 format. o per varBind: - two null terminated strings (in the selected character set) representing the group and instance ID in ASN.1 dotted notation. - the type, value length and value to be set. The permitted types for the type field are defined in Table 17. See 3.3.4, "Value Representation" for information on how the value data is represented in the packet value field.
+-----------------------------------------------------------------+ | Table 12. Layout SNMP DPI SET, COMMIT, UNDO packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_SET/COMMIT/UNDO | +------------+----------------------------------------------------+ | 8 | community name length (MSB to LSB) | +------------+----------------------------------------------------+ | 10 | community name | +------------+----------------------------------------------------+ | 10+L1 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 10+L2 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 10+L3 | SNMP Variable Type Value | +------------+----------------------------------------------------+ | 10+L3+1 | Length of value (2 octets, MSB to LSB) | +------------+----------------------------------------------------+ | 10+L3+3 | Value | +------------+----------------------------------------------------+ | 10+L4 | optionally more varBinds (sequences of group ID, | | | instance ID, Type, Length and Value) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = length of community name | | o L2 = L1 + strlen(group ID) + 1 | | o L3 = L2 + strlen(instance ID) + 1 | | o L4 = L3 + 3 + length of value | | o group and instance ID strings use selected character set | | o OID and DisplayString values use selected character set | | o Integer values are in network byte order | +-----------------------------------------------------------------+
3.2.11 RESPONSE An SNMP sub-agent must respond to a GET, GETNEXT, GETBULK, SET, COMMIT, UNDO or UNREGISTER request that it has received from the agent (unless it fails or has a bug ;-)). To do so, it sends an SNMP DPI RESPONSE packet to the agent. Such a packet contains the standard SNMP DPI header plus RESPONSE specific data: o an error_code, o an error_index, o plus for a successful GET, GETNEXT, or GETBULK, the name/type/length/value tuple(s) representing the returned object(s). For each varBind this is described as: - two null terminated strings (in the selected character set) representing the group and instance ID in ASN.1 dotted notation. - the type, value length and value of the object that is returned. The permitted types for the type field are defined in Table 17. See 3.3.4, "Value Representation" for information on how the value data is represented in the packet value field. For an unsuccessful GET, GETNEXT or GETBULK, the sub-agent does not need to return any name/type/length/value tuple(s), because by definition, the varBind information is the same as in the request to which this is a response, and the agent still has that information. The group ID and the packet ID must always be the same as the corresponding fields in request PDU which has prompted the RESPONSE. If the response is to a SET, COMMIT or UNDO request, there is no need to return any varBind information, because by definition, the varBind information is the same as in the request to which this is a response, and the agent still has that information. If the response is to a REGISTER or UNREGISTER, no variable (instance) is being returned, so the instance ID is the NULL string (one 0x00 byte). In the response to a REGISTER request indicating success, the error index contains the priority assigned by the agent. If the response is to an OPEN, ARE_YOU_THERE or CLOSE, no varBind data will be passed, so no group ID, instance ID or value data. The packet will only include the header, the error code and the error
index. +-----------------------------------------------------------------+ | Table 13. Layout SNMP DPI RESPONSE packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type = SNMP_DPI_RESPONSE | +------------+----------------------------------------------------+ | 8 | error code (1 octet) | +------------+----------------------------------------------------+ | 9 | error index (4 octets, MSB to LSB) | +------------+----------------------------------------------------+ | 15 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 15+L1 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 15+L2 | SNMP Variable Type Value | +------------+----------------------------------------------------+ | 15+L2+1 | Length of value (MSB to LSB) | +------------+----------------------------------------------------+ | 15+L2+3 | Value | +------------+----------------------------------------------------+ | 15+L3 | optionally more varBinds (sequences of group ID, | | | instance ID, Type, Length and Value) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = strlen(group ID) + 1 | | o L2 = L1 + strlen(instance ID) + 1 | | o L3 = L2 + 3 + length of value | | o group and instance ID strings use selected character set | | o OID and DisplayString values use selected character set | | o Integer values are in network byte order | +-----------------------------------------------------------------+
3.2.12 TRAP An SNMP sub-agent can request the agent to generate an SNMPv1 or SNMPv2 TRAP (depending on the trap destinations defined at the agent) by sending an SNMP DPI TRAP packet to the agent. Such a packet contains the standard SNMP DPI header plus TRAP specific data: o the generic and specific trap codes o optionally a null terminated string (in the selected character set) representing the enterprise ID in ASN.1 dotted notation. This enterprise ID will be sent with the TRAP. If the null string is passed, then the agent uses the sub-agent Identifier (OID as passed with the DPI OPEN packet) as the Enterprise ID. o optionally a set of one or more name/type/length/value tuples. representing varBinds to be sent with the trap. Each varBind consists of: - two null terminated strings (in the selected character set) representing the group and instance ID in ASN.1 dotted notation. - the type, value length and value of the object that is returned. The permitted types for the type field are defined in Table 17. See 3.3.4, "Value Representation" for information on how the value data is represented in the packet value field.
+-----------------------------------------------------------------+ | Table 14. Layout SNMP DPI TRAP packet | +------------+----------------------------------------------------+ | OFFSET | FIELD | +------------+----------------------------------------------------+ | 0 | packet length to follow (MSB to LSB) | +------------+----------------------------------------------------+ | 2 | protocol major version | +------------+----------------------------------------------------+ | 3 | protocol minor version | +------------+----------------------------------------------------+ | 4 | protocol release | +------------+----------------------------------------------------+ | 5 | packet id (MSB to LSB) | +------------+----------------------------------------------------+ | 7 | packet type - SNMP_DPI_TRAP | +------------+----------------------------------------------------+ | 8 | SNMP generic trap code | +------------+----------------------------------------------------+ | 12 | SNMP specific trap code | +------------+----------------------------------------------------+ | 14 | null terminated enterprise ID (no trailing dot) | +------------+----------------------------------------------------+ | 14+L1 | null terminated group ID (with trailing dot) | +------------+----------------------------------------------------+ | 14+L2 | null terminated instance ID (no trailing dot) | +------------+----------------------------------------------------+ | 14+L3 | SNMP Variable Type Value | +------------+----------------------------------------------------+ | 14+L3+1 | Length of value (MSB to LSB) | +------------+----------------------------------------------------+ | 14+L3+3 | Value | +------------+----------------------------------------------------+ | 14+L4 | optionally more varBinds (sequences of group ID, | | | instance ID, Type, Length and Value) | +------------+----------------------------------------------------+ | NOTE: | | | | o L1 = strlen(enterprise ID) + 1 | | o L2 = L1 + strlen(group ID) + 1 | | o L3 = L1 + L2 + strlen(instance ID) + 1 | | o L4 = L1 + L2 + L3 + 3 + length of Value | | o enterprise, group and instance ID strings use selected | | character set | | o OID and DisplayString values use selected character set | | o Integer values are in network byte order | +-----------------------------------------------------------------+