summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc1228.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rfc/rfc1228.txt')
-rw-r--r--doc/rfc/rfc1228.txt2803
1 files changed, 2803 insertions, 0 deletions
diff --git a/doc/rfc/rfc1228.txt b/doc/rfc/rfc1228.txt
new file mode 100644
index 0000000..a8e7932
--- /dev/null
+++ b/doc/rfc/rfc1228.txt
@@ -0,0 +1,2803 @@
+
+
+
+
+
+
+Network Working Group G. Carpenter
+Request for Comments: 1228 B. Wijnen
+ T.J. Watson Research Center, IBM Corp.
+ May 1991
+
+
+ SNMP-DPI
+ Simple Network Management Protocol
+ Distributed Program Interface
+
+Status of this Memo
+
+ This RFC describes a protocol that International Business Machines
+ Corporation (IBM) has been implementing in most of its SNMP agents to
+ allow dynamic extension of supported MIBs. This is an Experimental
+ Protocol for the Internet community. Discussion and suggestions for
+ improvement are requested. Please refer to the current edition of
+ the "IAB Official Protocol Standards" for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+ABSTRACT
+
+ The Simple Network Management Protocol (SNMP) [1] Distributed Program
+ Interface (DPI) is an extension to SNMP agents that permits end-users
+ to dynamically add, delete or replace management variables in the
+ local Management Information Base without requiring recompilation of
+ the SNMP agent. This is achieved by writing a so-called sub-agent
+ that communicates with the agent via the SNMP-DPI.
+
+ For the author of a sub-agent, the SNMP-DPI eliminates the need to
+ know the details of ASN.1 [2] or SNMP PDU (Protocol Data Unit)
+ encoding/decoding [1, 3].
+
+ This protocol has been in use within IBM since 1989 and is included
+ in the SNMP agents for VM, MVS and OS/2.
+
+ Potentially useful sample sub-agent code and implementation examples
+ are available for anonymous FTP from the University of Toronto.
+
+MOTIVATION
+
+ The Simple Network Management Protocol [1] defines a protocol that
+ permits operations on a collection of variables. This set of
+ variables is called the Management Information Base (MIB) and a core
+ set of variables has previously been defined [4, 5]; however, the
+ design of the MIB makes provision for extension of this core set.
+ Thus, an enterprise or individual can define variables of their own
+ which represent information of use to them. An example of a
+
+
+
+Carpenter & Wijnen [Page 1]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ potentially interesting variable which is not in the core MIB would
+ be CPU utilization (percent busy). Unfortunately, conventional SNMP
+ agent implementations provide no means for an end-user to make
+ available new variables.
+
+ The SNMP DPI addresses this issue by providing a light-weight
+ mechanism by which a process can register the existence of a MIB
+ variable with the SNMP agent. When requests for the variable are
+ received by the SNMP agent, it will pass the query on to the process
+ acting as a sub-agent. This sub-agent then returns an appropriate
+ answer to the SNMP agent. The SNMP agent eventually packages an SNMP
+ response packet and sends the answer back to the remote network
+ management station that initiated the request.
+
+ None of the remote network management stations have any knowledge
+ that the SNMP agent calls on other processes to obtain an answer. As
+ far as they can tell, there is only one network management
+ application running on the host.
+
+THEORY OF OPERATION
+
+CONNECTION ESTABLISHMENT
+
+ Communication between the SNMP Agent and its clients (sub-agents)
+ takes place over a stream connection. This is typically a TCP
+ connection, but other stream-oriented transport mechanisms can be
+ used. As an example, the VM SNMP agent allows DPI connections over
+ IUCV (Inter-User Communications Vehicle) [6, 7]. Other than the
+ connection establishment procedure, the protocol used is identical in
+ these environments.
+
+REGISTRATION
+
+ Regardless of the connection-oriented transport mechanism used, after
+ establishing a connection to the SNMP agent, the sub-agent registers
+ the set of variables it supports. Finally, when all the variable
+ classes have been registered, the sub-agent then waits for requests
+ from the SNMP agent or generates traps as required.
+
+DPI ARCHITECTURE
+
+ There are three requests that can be initiated by the SNMP agent:
+ GET, GET-NEXT and SET. These correspond directly to the three SNMP
+ requests that a network management station can make. The sub-agent
+ responds to a request with a RESPONSE packet.
+
+ There are currently two requests that can be initiated by a sub-
+ agent: REGISTER and TRAP.
+
+
+
+Carpenter & Wijnen [Page 2]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+------------------------------------------------------------------------
+
+*---------------------------------*
+| SNMP Network |
+| Management Station |
+| |
+|---------------------------------|
+| SNMP Protocol |
+*---------------------------------*
+ A | Get A
+ | | GetNext | GetResponse
+ Trap | | Set |
+ | V |
+*---------------------------------* *----------------------*
+| SNMP Protocol | | DPI Interface |
+|---------------------------------| Reply | *-----------------|
+| | |<-----------| | |
+| SNMP Agent | | | | Client |
+| A *-----------+-> | MIB query | | |
+| | | Get/Set | |----------->| | or |
+| Trap| | info | SNMP | | | |
+|-----+------+-------* | | trap | | SNMP |
+| | V | | DPI |<-----------| | Sub-Agent |
+| TCP/IP layers, | | | | | |
+| Kernel | | |<-----------| | |
+*---------------------------------* Register *----------------------*
+
+------------------------------------------------------------------------
+Figure 1. SNMP DPI overview
+
+Remarks for Figure 1:
+
+ o The SNMP agent communicates with the SNMP manager via the
+ standard SNMP protocol.
+ o The SNMP agent communicates with the TCP/IP layers and kernel
+ (operating system) in an implementation-dependent manner. It
+ potentially implements the standard MIB view in this way.
+ o An SNMP sub-agent, running as a separate process (potentially
+ even on another machine), can register objects with the SNMP
+ agent.
+ o The SNMP agent will decode SNMP Packets. If such a packet
+ contains a Get/GetNext or Set request for an object registered
+ by a sub-agent, it will send the request to the sub-agent via
+ the corresponding query packet.
+ o The SNMP sub-agent sends responses back via a RESPONSE packet.
+ o The SNMP agent then encodes the reply into an SNMP packet and
+ sends it back to the requesting SNMP manager.
+ o If the sub-agent wants to report an important state change, it
+
+
+
+Carpenter & Wijnen [Page 3]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ sends a TRAP packet to the SNMP agent, which will encode it
+ into an SNMP trap packet and send it to the manager(s).
+
+SNMP DPI PROTOCOL
+
+ This section describes the actual protocol used between the SNMP
+ agent and sub-agents. This information has not previously been
+ published.
+
+CONNECTION ESTABLISHMENT
+
+ In a TCP/IP environment, the SNMP agent listens on an arbitrary TCP
+ 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 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 number
+ is maintained by the SNMP agent as the object whose identifier is
+ 1.3.6.1.4.1.2.2.1.1.0; this variable is registered under the IBM
+ enterprise-specific tree. 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. The DPI Application Program Interface (API) has a library
+ routine, query_DPI_port(), which can be used to generate and parse
+ the required SNMP packets. This routine is very small (under 100
+ lines of C), so it does not greatly increase the size of any sub-
+ agent).
+
+ For completeness, byte-by-byte descriptions of the packets generated
+ by the SNMP DPI API routine query_DPI_port() are provided below.
+ This is probably of little interest to most readers and reading the
+ source to query_DPI_port() provides much of the same information.
+
+SNMP PDU TO GET THE AGENT'S DPI PORT
+
+ As noted, before a TCP connection to the SNMP agent can be made, the
+ sub-agent must learn which TCP port that the agent is listening on.
+ To do so, it can issue an SNMP GET for an IBM enterprise-specific
+ variable 1.3.6.1.4.1.2.2.1.1.0.
+
+
+
+
+Carpenter & Wijnen [Page 4]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ NOTE: the object instance of ".0" is included for clarity in this
+ document.
+
+ 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).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 5]
+
+RFC 1228 SNMP-DPI May 1991
+
+
++----------------------------------------------------------------------+
+| Table 1. SNMP PDU for GET DPI_port. This is the layout of an SNMP |
+| PDU for GET DPI_port |
++-----------------+-----------------+----------------------------------+
+| OFFSET | VALUE | FIELD |
++-----------------+-----------------+----------------------------------+
+| 0 | 0x30 | ASN.1 header |
++-----------------+-----------------+----------------------------------+
+| 1 | 34 + len | pdu_length, see formula below |
++-----------------+-----------------+----------------------------------+
+| 2 | 0x02 0x01 0x00 | version (integer, length=1, |
+| | 0x04 | value=0), community name |
+| | | (string) |
++-----------------+-----------------+----------------------------------+
+| 6 | len | length of community name |
++-----------------+-----------------+----------------------------------+
+| 7 | community name | |
++-----------------+-----------------+----------------------------------+
+| 7 + len | 0xa0 0x1b | SNMP GET request: |
+| | | request_type=0xa0, length=0x1b |
++-----------------+-----------------+----------------------------------+
+| 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 0x10 | Varbind list, length=0x10 |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 13 | 0x30 0x0e | Varbind, length=0x0e |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 15 | 0x06 0x0a | Object ID, length=0x0a |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 17 | 0x2b 0x06 0x01 | Object instance: |
+| | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.0 |
+| | 0x02 0x01 0x01 | |
+| | 0x00 | |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 27 | 0x05 0x00 | null value, length=0 |
++-----------------+-----------------+----------------------------------+
++----------------------------------------------------------------------+
+
+The formula to calculate the length field "pdu_length" is as follows:
+
+ pdu_length = length of version field and string tag (4 bytes)
+
+
+
+Carpenter & Wijnen [Page 6]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ + length of community length field (1 byte)
+ + length of community name (depends...)
+ + length of SNMP GET request (29 bytes)
+
+ = 34 + length of community name
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 7]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+SNMP PDU CONTAINING THE RESPONSE TO THE GET
+
+Assuming that no errors occured, then the port is returned in the last 2
+octets of the received packet. The format of the packet is shown below:
+
++----------------------------------------------------------------------+
+| Table 2. SNMP RESPONSE PDU for GET of Agent's DPI port. This is the |
+| layout of an SNMP RESPONSE PDU for GET DPI_port |
++-----------------+-----------------+----------------------------------+
+| OFFSET | VALUE | FIELD |
++-----------------+-----------------+----------------------------------+
+| 0 | 0x30 | ASN.1 header |
++-----------------+-----------------+----------------------------------+
+| 1 | 36 + len | length, see formula below |
++-----------------+-----------------+----------------------------------+
+| 2 | 0x02 0x01 0x00 | version (integer, length=1, |
+| | 0x04 | value=0), community name |
+| | | (string) |
++-----------------+-----------------+----------------------------------+
+| 6 | len | length of community name |
++-----------------+-----------------+----------------------------------+
+| 7 | community name | |
++-----------------+-----------------+----------------------------------+
+| 7 + len | 0xa2 0x1d | SNMP RESPONSE: |
+| | | request_type=0xa2, length=0x1d |
++-----------------+-----------------+----------------------------------+
+| 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 0x12 | Varbind list, length=0x12 |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 13 | 0x30 0x10 | Varbind, length=0x10 |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 15 | 0x06 0x0a | Object ID, length=0x0a |
++-----------------+-----------------+----------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 8]
+
+RFC 1228 SNMP-DPI May 1991
+
+
++----------------------------------------------------------------------+
+| Table 2. SNMP RESPONSE PDU for GET of Agent's DPI port. This is the |
+| layout of an SNMP RESPONSE PDU for GET DPI_port |
++-----------------+-----------------+----------------------------------+
+| OFFSET | VALUE | FIELD |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 17 | 0x2b 0x06 0x01 | Object instance: |
+| | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.0 |
+| | 0x02 0x01 0x01 | |
+| | 0x00 | |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 27 | 0x02 0x02 | integer, length=2 |
++-----------------+-----------------+----------------------------------+
+| 7 + len + 29 | msb lsb | port number (msb, lsb) |
++-----------------+-----------------+----------------------------------+
++----------------------------------------------------------------------+
+
+The formula to calculate the length field "pdu_length" is as follows:
+
+ 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 (31 bytes)
+
+ = 36 + length of community name
+
+SNMP DPI PACKET FORMATS
+
+ Each request to or response from the 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 (most significant
+ byte first, least significant last). The receiving side will read
+ the packet by doing something similar to:
+
+ unsigned char len_bfr[2];
+ 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. This is not a
+ suggested coding style.
+
+
+
+Carpenter & Wijnen [Page 9]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ 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 10 on
+ page 18.
+
+ The next (common) field in all packets is the packet type. This
+ field indicates what kind of packet we're dealing with (SNMP DPI GET,
+ GET-NEXT, SET, TRAP, RESPONSE or REGISTER). The permitted values for
+ this field are defined in Table 11 on page 18.
+
++----------------------------------------------------------------------+
+| Table 3. SNMP DPI packet header. This header is present in all |
+| packets. |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | 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 the structure of packets for the SNMP DPI protocol, version 1.0.
+
+ o The constants as defined with this version of the protocol.
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 10]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+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, which basically is a null terminated string
+ representing the object ID in dotted ASN.1 notation (with a trailing
+ dot!).
+
++----------------------------------------------------------------------+
+| Table 4. SNMP DPI REGISTER packet. This is the layout of an SNMP |
+| DPI REGISTER packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type = SNMP_DPI_REGISTER |
++-------------+--------------------------------------------------------+
+| 6 | null terminated object ID |
++-------------+--------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 11]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+GET
+
+ When the SNMP agent receives a PDU containing an SNMP GET request for
+ a variable that a sub-agent registered with the 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, which is basically a null terminated string representing the
+ object ID in dotted ASN.1 notation.
+
++----------------------------------------------------------------------+
+| Table 5. SNMP DPI GET packet. This is the layout of an SNMP DPI GET |
+| packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type = SNMP_DPI_GET |
++-------------+--------------------------------------------------------+
+| 6 | null terminated object ID |
++-------------+--------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 12]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+GET-NEXT
+
+ When the SNMP agent receives a PDU containing an SNMP GET-NEXT
+ request for a variable for which a sub-agent may be authoritative, it
+ passes an SNMP DPI GET-NEXT packet to the sub-agent.
+
+ Such a packet contains the standard SNMP DPI header plus GET-NEXT-
+ specific data. These data take the form of two null terminated
+ strings. The first string represents the object ID in dotted ASN.1
+ notation; the second string represents the group ID in dotted ASN.1
+ notation.
+
++----------------------------------------------------------------------+
+| Table 6. SNMP DPI GET NEXT packet. This is the layout of an SNMP |
+| DPI GET NEXT packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type = SNMP_DPI_GET_NEXT |
++-------------+--------------------------------------------------------+
+| 6 | null terminated object ID |
++-------------+--------------------------------------------------------+
+| 6 + len | null terminated group ID |
++-------------+--------------------------------------------------------+
+| NOTE: len=strlen(object ID)+1 |
++----------------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 13]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+SET
+
+ When the SNMP agent receives a PDU containing an SNMP SET request for
+ a variable that a sub-agent registered with the agent, it passes an
+ SNMP DPI SET packet to the sub-agent.
+
+ Such a packet contains the standard SNMP DPI header plus SET specific
+ data, which is basically a null terminated string representing the
+ object ID in ASN.1 notation, with the type, value length and value to
+ be set. The permitted types for the type field are defined in Table
+ 12 on page 19. Integer values are sent as 4-byte elements in network
+ byte order (most significant byte first, least significant byte
+ last).
+
++----------------------------------------------------------------------+
+| Table 7. SNMP DPI SET packet. This is the layout of an SNMP DPI SET |
+| packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type = SNMP_DPI_SET |
++-------------+--------------------------------------------------------+
+| 6 | null terminated object ID |
++-------------+--------------------------------------------------------+
+| 6 + len | SNMP Variable Type Value |
++-------------+--------------------------------------------------------+
+| 6 + len + 1 | Length of value (MSB) |
++-------------+--------------------------------------------------------+
+| 6 + len + 2 | Length of value (LSB) |
++-------------+--------------------------------------------------------+
+| 6 + len + 3 | Value |
++-------------+--------------------------------------------------------+
+| NOTE: len=strlen(object ID)+1 |
++----------------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 14]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+RESPONSE
+
+ An SNMP sub-agent must respond to a GET, GET_NEXT or SET 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, which basically is an error_code plus (if there was no
+ error), the name/type/value tuple representing the returned object.
+ This is described as by a string representing the object ID in ASN.1
+ notation, plus the type, value length and value of the object that
+ was manipulated. The permitted types for the type field are defined
+ in Table 12 on page 19. Integer values are sent as 4-byte elements
+ in network byte order (most significant byte first, least significant
+ byte last).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 15]
+
+RFC 1228 SNMP-DPI May 1991
+
+
++----------------------------------------------------------------------+
+| Table 8. SNMP DPI RESPONSE packet. This is the layout of an SNMP |
+| DPI RESPONSE packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type = SNMP_DPI_RESPONSE |
++-------------+--------------------------------------------------------+
+| 6 | SNMP error code |
++-------------+--------------------------------------------------------+
+| 7 | null terminated object ID |
++-------------+--------------------------------------------------------+
+| 7 + len | SNMP Variable Type Value |
++-------------+--------------------------------------------------------+
+| 7 + len + 1 | Length of value (MSB) |
++-------------+--------------------------------------------------------+
+| 7 + len + 2 | Length of value (LSB) |
++-------------+--------------------------------------------------------+
+| 7 + len + 3 | Value |
++-------------+--------------------------------------------------------+
+| NOTE: len=strlen(object ID)+1 |
++----------------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+TRAP
+
+ An SNMP sub-agent can request the agent to generate a TRAP by sending
+ an SNMP DPI TRAP packet to the agent.
+
+ Such a packet contains the standard SNMP DPI header plus TRAP
+ specific data, which is basically the generic and specific trap code,
+ plus a name/type/value tuple. The tuple is described by a string
+ representing the object ID in ASN.1 notation, plus the type, value
+ length and value of the object that is being sent in the trap. The
+ permitted types for the type field are defined in Table 12 on page
+ 19. Integer values are sent as 4-byte elements in network byte order
+ (most significant byte first, least significant byte last).
+
+
+
+
+Carpenter & Wijnen [Page 16]
+
+RFC 1228 SNMP-DPI May 1991
+
+
++----------------------------------------------------------------------+
+| Table 9. SNMP DPI TRAP packet. This is the layout of an SNMP DPI |
+| TRAP packet |
++-------------+--------------------------------------------------------+
+| OFFSET | FIELD |
++-------------+--------------------------------------------------------+
+| 0 | packet length to follow (MSB) |
++-------------+--------------------------------------------------------+
+| 1 | packet length to follow (LSB) |
++-------------+--------------------------------------------------------+
+| 2 | protocol major version |
++-------------+--------------------------------------------------------+
+| 3 | protocol minor version |
++-------------+--------------------------------------------------------+
+| 4 | protocol release |
++-------------+--------------------------------------------------------+
+| 5 | packet type - SNMP_DPI_TRAP |
++-------------+--------------------------------------------------------+
+| 6 | SNMP generic trap code |
++-------------+--------------------------------------------------------+
+| 7 | SNMP specific trap code |
++-------------+--------------------------------------------------------+
+| 8 | null terminated object ID |
++-------------+--------------------------------------------------------+
+| 8 + len | SNMP Variable Type Value |
++-------------+--------------------------------------------------------+
+| 8 + len + 1 | Length of value (MSB) |
++-------------+--------------------------------------------------------+
+| 8 + len + 2 | Length of value (LSB) |
++-------------+--------------------------------------------------------+
+| 8 + len + 3 | Value |
++-------------+--------------------------------------------------------+
+| NOTE: len=strlen(object ID)+1 |
++----------------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 17]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+CONSTANTS AND VALUES
+
+ This section describes the constants that have been defined for this
+ version of the SNMP DPI Protocol.
+
+PROTOCOL VERSION AND RELEASE VALUES
+
++----------------------------------------------------------------------+
+| Table 10. Protocol version and release values |
++-----------------------------------+----------------------------------+
+| FIELD | VALUE |
++-----------------------------------+----------------------------------+
+| protocol major version | 2 (SNMP DPI protocol) |
++-----------------------------------+----------------------------------+
+| protocol minor version | 1 (version 1) |
++-----------------------------------+----------------------------------+
+| protocol release | 0 (release 0) |
++-----------------------------------+----------------------------------+
++----------------------------------------------------------------------+
+
+Any other values are currently undefined.
+
+PACKET TYPE VALUES
+
+ The packet type field can have the following values:
+
++----------------------------------------------------------------------+
+| Table 11. Valid values for the packet type field |
++-------+--------------------------------------------------------------+
+| VALUE | PACKET TYPE |
++-------+--------------------------------------------------------------+
+| 1 | SNMP_DPI_GET |
++-------+--------------------------------------------------------------+
+| 2 | SNMP_DPI_GET_NEXT |
++-------+--------------------------------------------------------------+
+| 3 | SNMP_DPI_SET |
++-------+--------------------------------------------------------------+
+| 4 | SNMP_DPI_TRAP |
++-------+--------------------------------------------------------------+
+| 5 | SNMP_DPI_RESPONSE |
++-------+--------------------------------------------------------------+
+| 6 | SNMP_DPI_REGISTER |
++-------+--------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 18]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+VARIABLE TYPE VALUES
+
+ The variable type field can have the following values:
+
++----------------------------------------------------------------------+
+| Table 12. Valid values for the Value Type field |
++-------+--------------------------------------------------------------+
+| VALUE | VALUE TYPE |
++-------+--------------------------------------------------------------+
+| 0 | text representation |
++-------+--------------------------------------------------------------+
+| 129 | number (integer) |
++-------+--------------------------------------------------------------+
+| 2 | octet string |
++-------+--------------------------------------------------------------+
+| 3 | object identifier |
++-------+--------------------------------------------------------------+
+| 4 | empty (no value) |
++-------+--------------------------------------------------------------+
+| 133 | internet address |
++-------+--------------------------------------------------------------+
+| 134 | counter (unsigned) |
++-------+--------------------------------------------------------------+
+| 135 | gauge (unsigned) |
++-------+--------------------------------------------------------------+
+| 136 | time ticks (1/100ths seconds) |
++-------+--------------------------------------------------------------+
+| 9 | display string |
++-------+--------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+ NOTE: Fields which represent values that are stored as a 4-byte
+ integer are indicated by ORing their base type value with 128.
+
+Error Code Values for SNMP Agent Detected Errors
+
+ The error code can have one of the following values:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 19]
+
+RFC 1228 SNMP-DPI May 1991
+
+
++----------------------------------------------------------------------+
+| Table 13. Valid values for the SNMP Agent Minor Error Code field |
++-------+--------------------------------------------------------------+
+| VALUE | SNMP AGENT ERROR CODE |
++-------+--------------------------------------------------------------+
+| 0 | no error |
++-------+--------------------------------------------------------------+
+| 1 | too big |
++-------+--------------------------------------------------------------+
+| 2 | no such name |
++-------+--------------------------------------------------------------+
+| 3 | bad value |
++-------+--------------------------------------------------------------+
+| 4 | read only |
++-------+--------------------------------------------------------------+
+| 5 | general error |
++-------+--------------------------------------------------------------+
++----------------------------------------------------------------------+
+
+SNMP DPI APPLICATION PROGRAM INTERFACE
+
+ This section documents an API that implements the SNMP DPI. This
+ information has been previously published [6, 8], but the information
+ provided below is more current as of May 14, 1991.
+
+OVERVIEW OF REQUEST PROCESSING
+
+GET PROCESSING
+
+ A GET request is the easiest to process. When the DPI packet is
+ parsed, the parse tree holds the object ID of the variable being
+ requested.
+
+ If the specified object is not supported by the sub-agent, it would
+ return an error indication of "no such name". No name/type/value
+ information would be returned.
+
+ unsigned char *cp;
+
+ cp = mkDPIresponse(SNMP_NO_SUCH_NAME,0);
+
+ If the object is recognized, then the sub-agent creates a parse tree
+ representing the name/type/value of the object in question (using the
+ DPI API routine mkDPIset()), and returns no error indication. This
+ is demonstrated below (a string is being returned).
+
+
+
+
+
+
+Carpenter & Wijnen [Page 20]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ char *obj_id;
+
+ unsigned char *cp;
+ struct dpi_set_packet *ret_value;
+ char *data;
+
+ /* obj_id = object ID of variable, like 1.3.6.1.2.1.1.1 */
+ /* should be identical to object ID sent in get request */
+ data = "a string to be returned";
+ ret_value = mkDPIset(obj_id,SNMP_TYPE_STRING,
+ strlen(data)+1,data);
+ cp = mkDPIresponse(0,ret_value);
+
+SET PROCESSING
+
+ Processing a SET request is only slightly more difficult than a GET
+ request. In this case, additional information is made available in
+ the parse tree, namely the type, length and value to be set.
+
+ The sub-agent may return an error indication of "no such name" if the
+ variable is unrecognized, just as in a GET request. If the variable
+ is recognized, but cannot be set, an error indication of "no such
+ name" should be also be returned, although it is tempting to return a
+ "read only" error.
+
+GET NEXT PROCESSING
+
+ GET-NEXT requests are the most complicated requests to process.
+ After parsing a GET-NEXT request, the parse tree will contain two
+ parameters. One is the object ID on which the GET-NEXT operation is
+ being performed. The semantics of the operation are that the sub-
+ agent is to return the name/type/value of the next variable it
+ supports whose name lexicographically follows the passed object ID.
+
+ It is important to realize that a given sub-agent may support several
+ discontiguous sections of the MIB tree. In such a situation it would
+ be incorrect to jump from one section to another. This problem is
+ correctly handled by examining the second parameter which is passed.
+ This parameter represents the "reason" why the sub-agent is being
+ called. It holds the prefix of the tree that the sub-agent had
+ indicated it supported.
+
+ If the next variable supported by the sub-agent does not begin with
+ that prefix, the sub-agent must return an error indication of "no
+ such name". If required, the SNMP agent will call upon the sub-agent
+ again, but pass it a different group prefix. This is illustrated in
+ the discussion below:
+
+
+
+
+Carpenter & Wijnen [Page 21]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ Assume there are two sub-agents. The first sub-agent registers two
+ distinct sections of the tree, A and C. In reality, the sub-agent
+ supports variables A.1 and A.2, but it correctly registers the
+ minimal prefix required to uniquely identify the variable class it
+ supports.
+
+ The second sub-agent registers a different section, B, which appears
+ between the two sections registered by the first agent.
+
+ If a remote management station begins dumping the MIB, starting from
+ A, the following sequence of queries would be performed:
+
+ Sub-agent 1 gets called:
+ get-next(A,A) == A.1
+ get-next(A.1,A) = A.2
+ get-next(A.2,A) = error(no such name)
+
+ Sub-agent 2 is then called:
+ get-next(A.2,B) = B.1
+ get-next(B.1,B) = error(no such name)
+
+ Sub-agent 1 gets called again:
+ get-next(B.1,C) = C.1
+
+REGISTER REQUESTS
+
+ A sub-agent must register the variables it supports with the SNMP
+ agent. The appropriate packets may be created using the DPI API
+ library routine mkDPIregister().
+
+ unsigned char *cp;
+
+ cp = mkDPIregister("1.3.6.1.2.1.1.2.");
+
+NOTE: object IDs are registered with a trailing dot (".").
+
+TRAP REQUESTS
+
+ A sub-agent can request that the SNMP agent generate a trap for it.
+ The sub-agent must provide the desired values for the generic and
+ specific parameters of the trap. It may optionally provide a
+ name/type/value parameter that will be included in the trap packet.
+ The DPI API library routine mkDPItrap() can be used to generate the
+ required packet.
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 22]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+DPI API LIBRARY ROUTINES
+
+ This section documents Application Program Interfaces to the DPI.
+
+ QUERY_DPI_PORT()
+
+ int port;
+ char *hostname, *community_name;
+
+ port = query_DPI_port(hostname, community_name);
+
+ The query_DPI_port() function is used by a DPI client to determine
+ what TCP port number is associated with the DPI. This port number is
+ needed to connect() to the SNMP agent. If the port cannot be
+ determined, -1 is returned.
+
+ The function is passed two arguments: a string representing the
+ host's name or IP address and the community name to be used when
+ making the request.
+
+ This function enables a DPI client to "bootstrap" itself. The port
+ number is obtained via an SNMP GET request, but the DPI client does
+ not have to be able to create and parse SNMP packets--this is all
+ done by the query_DPI_port() function.
+
+ NOTE: the query_DPI_port() function assumes that the community name
+ does not contain any null characters. If this is not the case, use
+ the _query_DPI_port() function which takes a third parameter, the
+ length of the community name.
+
+MKDPIREGISTER
+
+ #include "snmp_dpi.h"
+
+ unsigned char *packet;
+ int len;
+
+ /* register sysDescr variable */
+ packet = mkDPIregister("1.3.6.1.2.1.1.1.");
+
+ len = *packet * 256 + *(packet + 1);
+ len += 2; /* include length bytes */
+
+ The mkDPIregister() function creates the necessary register-request
+ packet and returns a pointer to a static buffer holding the packet
+ contents. The null pointer (0) is returned if there is an error
+ detected during the creation of the packet.
+
+
+
+
+Carpenter & Wijnen [Page 23]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ The length of the remainder packet is stored in the first two bytes
+ of the packet, as demonstrated in the example above.
+
+ NOTE: object identifiers are registered with a trailing dot (".").
+
+MKDPISET
+
+ #include "snmp_dpi.h"
+
+ struct dpi_set_packet *set_value;
+
+ char *obj_id;
+ int type, length;
+ char *value;
+
+ set_value = mkDPIset(obj_id, type, length, value);
+
+ The mkDPIset() function can be used to create the portion of a parse
+ tree that represents a name/value pair (as would be normally be
+ returned in a response packet). It returns a pointer to a
+ dynamically allocated parse tree representing the name/type/value
+ information. If there is an error detected while creating the parse
+ tree, the null pointer (0) is returned.
+
+ The value of type can be one of the following (which are defined in
+ the include file "snmp_dpi.h"):
+
+ o SNMP_TYPE_NUMBER
+ o SNMP_TYPE_STRING
+ o SNMP_TYPE_OBJECT
+ o SNMP_TYPE_INTERNET
+ o SNMP_TYPE_COUNTER
+ o SNMP_TYPE_GAUGE
+ o SNMP_TYPE_TICKS
+
+ The value parameter is always a pointer to the first byte of the
+ object's value.
+
+ NOTE: the parse tree is dynamically allocated and copies are made of
+ the passed parameters. After a successful call to mkDPIset(), they
+ can be disposed of in any manner the application chooses without
+ affecting the parse tree contents.
+
+MKDPIRESPONSE
+
+ #include "snmp_dpi.h"
+
+ unsigned char *packet;
+
+
+
+Carpenter & Wijnen [Page 24]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ int error_code;
+ struct dpi_set_packet *ret_value;
+
+ packet = mkDPIresponse(error_code, ret_value);
+
+ len = *packet * 256 + *(packet + 1);
+ len += 2; /* include length bytes */
+
+ The mkDPIresponse() function creates an appropriate response packet.
+ It takes two parameters. The first is the error code to be returned.
+ It may be 0 (indicating no error) or one of the following (which are
+ defined in the include file "snmp_dpi.h"):
+
+ o SNMP_NO_ERROR
+ o SNMP_TOO_BIG
+ o SNMP_NO_SUCH_NAME
+ o SNMP_BAD_VALUE
+ o SNMP_READ_ONLY
+ o SNMP_GEN_ERR
+
+ If the error code indicates no error, then the second parameter is a
+ pointer to a parse tree (created by mkDPIset()) which represents the
+ name/type/value information being returned. If an error is
+ indicated, the second parameter is passed as a null pointer (0).
+
+ If the packet can be created, a pointer to a static buffer containing
+ the packet contents is returned. This is the same buffer used by
+ mkDPIregister(). If an error is encountered while creating the
+ packet, the null pointer (0) is returned.
+
+ The length of the remainder packet is stored in the first two bytes
+ of the packet, as demonstrated in the example above.
+
+ NOTE: mkDPIresponse() always frees the passed parse tree.
+
+MKDPITRAP
+
+ #include "snmp_dpi.h"
+
+ unsigned char *packet;
+
+ int generic, specific;
+ struct dpi_set_packet *ret_value;
+
+ packet = mkDPItrap(generic, specific, ret_value);
+
+ len = *packet * 256 + *(packet + 1);
+ len += 2; /* include length bytes */
+
+
+
+Carpenter & Wijnen [Page 25]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ The mkDPItrap() function creates an appropriate trap request packet.
+ The first two parameters correspond to to value of the generic and
+ specific fields in the SNMP trap packet. The third field can be used
+ to pass a name/value pair to be provided in the SNMP trap packet.
+ This information is passed as the set-packet portion of the parse
+ tree. As an example, a linkDown trap for interface 3 might be
+ generated by the following:
+
+ struct dpi_set_packet *if_index_value;
+ unsigned long data;
+ unsigned char *packet;
+ int len;
+
+ data = 3; /* interface number = 3 */
+ if_index_value = mkDPIset("1.3.6.1.2.1.2.2.1.1", SNMP_TYPE_NUMBER,
+ sizeof(unsigned long), &data);
+ packet = mkDPItrap(2, 0, if_index_value);
+ len = *packet * 256 + *(packet + 1);
+ len += 2; /* include length bytes */
+ write(fd,packet,len);
+
+ If the packet can be created, a pointer to a static buffer containing
+ the packet contents is returned. This is the same buffer used by
+ mkDPIregister(). If an error is encountered while creating the
+ packet, the null pointer (0) is returned.
+
+ The length of the remainder packet is stored in the first two bytes
+ of the packet, as demonstrated in the example above.
+
+ NOTE: mkDPItrap() always frees the passed parse tree.
+
+PDPIPACKET
+
+ #include "snmp_dpi.h"
+
+ unsigned char *packet;
+
+ struct snmp_dpi_hdr *hdr;
+
+ hdr = pDPIpacket(packet)
+
+ The pDPIpacket() function parses a DPI packet and returns a parse
+ tree representing its contents. The parse tree is dynamically
+ allocated and contains copies of the information within the DPI
+ packet. After a successful call to pDPIpacket(), the packet may be
+ disposed of in any manner the application chooses without affecting
+ the contents of the parse tree. If an error is encountered during
+ the parse, the null pointer (0) is returned.
+
+
+
+Carpenter & Wijnen [Page 26]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ NOTE: the relevant parse tree structures are defined in the include
+ file "snmp_dpi.h", and that file remains the definitive reference.
+
+ The root of the parse tree is represented by a snmp_dpi_hdr
+ structure:
+
+ struct snmp_dpi_hdr {
+ unsigned char proto_major;
+ unsigned char proto_minor;
+ unsigned char proto_release;
+
+ unsigned char packet_type;
+ union {
+ struct dpi_get_packet *dpi_get;
+ struct dpi_next_packet *dpi_next;
+ struct dpi_set_packet *dpi_set;
+ struct dpi_resp_packet *dpi_response;
+ struct dpi_trap_packet *dpi_trap;
+ } packet_body;
+ };
+
+ The field of immediate interest is packet_type. This field can have
+ one of the following values (which are defined in the include file
+ "snmp_dpi.h"):
+
+ o SNMP_DPI_GET
+ o SNMP_DPI_GET_NEXT
+ o SNMP_DPI_SET
+
+ The packet_type field indicates what request is being made of the DPI
+ client. For each of these requests, the remainder of the packet_body
+ will be different.
+
+ If a get request is indicated, the object ID of the desired variable
+ is passed in a dpi_get_packet structure:
+
+ struct dpi_get_packet {
+ char *object_id;
+ };
+
+ A get-next request is similar, but the dpi_next_packet structure also
+ contains the object ID prefix of the group that is currently being
+ traversed:
+
+ struct dpi_next_packet {
+ char *object_id;
+ char *group_id;
+ };
+
+
+
+Carpenter & Wijnen [Page 27]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ If the next object whose object ID lexicographically follows the
+ object ID indicated by object_id does not begin with the suffix
+ indicated by group_id, the DPI client must return an error indication
+ of SNMP_NO_SUCH_NAME.
+
+ A set request has the most amount of data associated with it and this
+ is contained in a dpi_set_packet structure:
+
+ struct dpi_set_packet {
+ char *object_id;
+ unsigned char type;
+ unsigned short value_len;
+ char *value;
+ };
+
+ The object ID of the variable to be modified is indicated by
+ object_id The type of the variable is provided in type and may have
+ one of the following values:
+
+ o SNMP_TYPE_NUMBER
+ o SNMP_TYPE_STRING
+ o SNMP_TYPE_OBJECT
+ o SNMP_TYPE_EMPTY
+ o SNMP_TYPE_INTERNET
+ o SNMP_TYPE_COUNTER
+ o SNMP_TYPE_GAUGE
+ o SNMP_TYPE_TICKS
+
+ The length of the value to be set is stored in value_len and value
+ contains a pointer to the value.
+
+ NOTE: the storage pointed to by value will be reclaimed when the
+ parse tree is freed. The DPI client must make provision for copying
+ the value contents.
+
+FDPIPARSE
+
+ #include "snmp_dpi.h"
+
+ struct snmp_dpi_hdr *hdr;
+
+ fDPIparse(hdr);
+
+ The routine fDPIparse() frees a parse tree previously created by a
+ call to pDPIpacket This routine is declared as void--it has no return
+ value.
+
+ NOTE: after calling fDPIparse(), no further references to the parse
+
+
+
+Carpenter & Wijnen [Page 28]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ tree can be made.
+
+AGENT IMPLEMENTATION ISSUES
+
+ Although the SNMP DPI protocol is completely documented in this
+ paper, the document itself is somewhat biased towards clearly
+ defining the interface provided to sub-agents (i.e., it provides a
+ specification of a C language API). This detailed coverage is
+ possible because the client side of the interface is completely
+ self-contained.
+
+ The agent side of the interface has to be integrated into individual
+ vendor implementations, many of which may have a unique
+ organizational structure in an attempt to address various performance
+ and storage constraints. This makes it infeasible to provide much
+ more than suggestions for SNMP agent implementers. Unfortunately,
+ this leaves room for a large amount of interpretation which can lead
+ to implementations that don't necessarily work they way they should-
+ -too much ambiguity can be a bad thing.
+
+ The following characteristics of an agent implementation are to be
+ considered mandatory:
+
+DUPLICATE REGISTRATIONS
+
+ With this release of the protocol, order of registration is
+ significant. The last sub-agent to register a variable is the one
+ that is deemed to be authoritative. Variables implemented by the
+ base SNMP agent are considered to have been registered prior to any
+ sub-agent registrations. Thus sub-agents may re-implement support
+ for variables that were incorrectly implemented by a vendor.
+
+AUTOMATIC DEREGISTRATION ON CLOSE
+
+ All SNMP DPI connections are carried over a stream connection. When
+ the connection is closed by the client (no matter what the cause),
+ the agent must automatically unregister all of the variables that
+ were registered by the sub-agent.
+
+TIMELY RESPONSE CONSTRAINTS
+
+ A sub-agent must respond to a request in a timely fashion. In this
+ version of the protocol, we specify that a sub-agent must respond to
+ a request by the SNMP agent within 5 seconds. If the sub-agent does
+ not respond in time, the SNMP agent should terminate the connection
+ and unregister all of the variables that were previously registered
+ by the sub-agent in question.
+
+
+
+
+Carpenter & Wijnen [Page 29]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ NOTE: agent implementations that do not have access to a timer may
+ not be able to implement this. In that case, they leave themselves
+ open to being placed in a state where they are blocked forever if the
+ sub-agent malfunctions.
+
+SUPPORT FOR MULTIPLE MIB VIEWS
+
+ Some agents allow different MIB views to be selected based on the
+ community name used. It is not the intention of this document to
+ pass judgement on the various approaches that have been proposed or
+ implemented, but instead merely to recognize the existence of
+ implementations that support this feature.
+
+ The point of this discussion is to specify clearly that objects
+ supported by an SNMP DPI sub-agent are to be registered under the MIB
+ view that was selected by the community name used in the SNMP GET
+ request that obtained the DPI_port value.
+
+ The SNMP DPI does not specify a reserved port, but instead sub-agents
+ bootstrap themselves by making an SNMP GET request for the DPI_port
+ variable. This variable represents the TCP port to which the sub-
+ agent should connect. It should be understood that there is no
+ reason why the SNMP agent cannot have several listens (passive opens)
+ active, each corresponding to a distinct MIB view. The port number
+ returned then would be different based on the community name used in
+ the SNMP GET request for the DPI_port variable.
+
+CONSIDERATIONS FOR THE NEXT RELEASE
+
+ The SNMP DPI protocol makes provision for extension and parallel use
+ of potentially incompatible releases. The discussion above documents
+ the protocol as it is currently in use and has not discussed features
+ of interest that should be considered for a future revision.
+
+UNREGISTER
+
+ For closure, an UNREGISTER request could be of use.
+
+SUPPORT FOR ATOMIC SETS
+
+ The SNMP protocol [1] specifies that:
+
+ Each variable assignment specified by the SetRequest-PDU should be
+ effected as if simultaneously set with respect to all other
+ assignments specified in the same message.
+
+ The SNMP DPI has no provision for backing out a successfully
+ processed SET request if one of the subsequent variable assignments
+
+
+
+Carpenter & Wijnen [Page 30]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ fails. This omission is a reflection of several biases:
+
+ o the SNMP DPI was intended to be light-weight.
+
+ o a belief that the SNMP RFC prescribes semantics which are infeasible
+ to implement unless the range of applications is restricted.
+
+ It has been suggested that a new request, TEST_SET, be added to the
+ DPI protocol. Processing of a SET request would then be performed as
+ follows:
+
+ o all variables would be processed using TEST_SET unless any error
+ occurred. The subagents would verify that they could process the
+ request.
+
+ o if no error occurred, each of the variables would be reprocessed,
+ this time with a SET request.
+
+ A problem with such an approach is that it relies on the TEST_SET
+ operation to make an assertion that the request can be successfully
+ performed. If this is not possible, then it cannot be asserted that
+ the prescribed semantics will be provided. Such situations do exist,
+ for example, a SET request that causes the far-end channel service
+ unit to be looped up--one does not know if the operation will be
+ successful until it is performed.
+
+SAMPLE SNMP DPI API IMPLEMENTATION
+
+ The following C language sources show an example implementation of
+ the SNMP DPI Application Programming Interface as it would be exposed
+ to the sub-agents.
+
+SAMPLE SNMP DPI INCLUDE FILE
+
+ /* SNMP distributed program interface */
+
+ #define SNMP_DPI_GET 1
+ #define SNMP_DPI_GET_NEXT 2
+ #define SNMP_DPI_SET 3
+ #define SNMP_DPI_TRAP 4
+ #define SNMP_DPI_RESPONSE 5
+ #define SNMP_DPI_REGISTER 6
+
+ #define SNMP_DPI_PROTOCOL 2
+ #define SNMP_DPI_VERSION 1
+ #define SNMP_DPI_RELEASE 0
+
+ /* SNMP error codes from RFC 1098 (1067) */
+
+
+
+Carpenter & Wijnen [Page 31]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ #define SNMP_NO_ERROR 0
+ #define SNMP_TOO_BIG 1
+ #define SNMP_NO_SUCH_NAME 2
+ #define SNMP_BAD_VALUE 3
+ #define SNMP_READ_ONLY 4
+ #define SNMP_GEN_ERR 5
+
+ /* variable types */
+ #define SNMP_TYPE_TEXT 0 /* textual representation */
+ #define SNMP_TYPE_NUMBER (128|1) /* number */
+ #define SNMP_TYPE_STRING 2 /* text string */
+ #define SNMP_TYPE_OBJECT 3 /* object identifier */
+ #define SNMP_TYPE_EMPTY 4 /* no value */
+ #define SNMP_TYPE_INTERNET (128|5) /* internet address */
+ #define SNMP_TYPE_COUNTER (128|6) /* counter */
+ #define SNMP_TYPE_GAUGE (128|7) /* gauge */
+ #define SNMP_TYPE_TICKS (128|8) /* time ticks (1/100th sec) */
+ #define SNMP_TYPE_MASK 0x7f /* mask for type */
+
+
+ struct dpi_get_packet {
+ char *object_id;
+ };
+
+ struct dpi_next_packet {
+ char *object_id;
+ char *group_id;
+ };
+
+ struct dpi_set_packet {
+ char *object_id;
+ unsigned char type;
+ unsigned short value_len;
+ char *value;
+ };
+
+ struct dpi_resp_packet {
+ unsigned char ret_code;
+ struct dpi_set_packet *ret_data;
+ };
+
+ struct dpi_trap_packet {
+ unsigned char generic;
+ unsigned char specific;
+ struct dpi_set_packet *info;
+ };
+
+ struct snmp_dpi_hdr {
+
+
+
+Carpenter & Wijnen [Page 32]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ unsigned char proto_major;
+ unsigned char proto_minor;
+ unsigned char proto_release;
+
+ unsigned char packet_type;
+ union {
+ struct dpi_get_packet *dpi_get;
+ struct dpi_next_packet *dpi_next;
+ struct dpi_set_packet *dpi_set;
+ struct dpi_resp_packet *dpi_response;
+ struct dpi_trap_packet *dpi_trap;
+ } packet_body;
+ };
+
+ extern struct snmp_dpi_hdr *pDPIpacket();
+ extern void fDPIparse();
+ extern unsigned char *mkMIBquery();
+ extern unsigned char *mkDPIregister();
+ extern unsigned char *mkDPIresponse();
+ extern unsigned char *mkDPItrap();
+ extern struct dpi_set_packet *mkDPIset();
+
+SAMPLE QUERY_DPI_PORT() FUNCTION
+
+
+ #ifdef VM
+
+ #include <manifest.h>
+ #include <snmp_vm.h>
+ #include <bsdtime.h>
+ #include <bsdtypes.h>
+ #include <socket.h>
+ #include <in.h>
+ #include <netdb.h>
+ #include <inet.h>
+
+ #else
+
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+
+ #endif
+
+ static unsigned char asn1_hdr[] = {0x30};
+
+
+
+Carpenter & Wijnen [Page 33]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ /* insert length of remaining packet, not including this */
+ static unsigned char version[] = {0x02, 0x01, 0x00, 0x04};
+
+ /* integer, len=1, value=0, string */
+ /* insert community name length and community name */
+ static unsigned char request[] = {
+ 0xa0, 0x1b, /* get request, len=0x1b */
+ 0x02, 0x01, 0x01, /* integer, len=1,request_id = 1 */
+ 0x02, 0x01, 0x00, /* integer, len=1, error_status = 0 */
+ 0x02, 0x01, 0x00, /* integer, len=1, error_index = 0 */
+ 0x30, 0x10, /* varbind list, len=0x10 */
+ 0x30, 0x0e, /* varbind , len=0x0e */
+ 0x06, 0x0a, /* object ID, len=0x0a */
+ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x02, 0x01, 0x01, 0x00,
+ 0x05, 0x00 /* value, len = 0 */
+ };
+
+ static extract_DPI_port();
+
+ query_DPI_port(hostname, community_name)
+ char *hostname;
+ char *community_name;
+ {
+ int community_len;
+ int rc;
+
+ community_len = strlen(community_name);
+
+ rc = _query_DPI_port(hostname, community_name, community_len);
+ return (rc);
+ }
+
+ /* use if community_name has embedded nulls */
+
+ _query_DPI_port(hostname, community_name, community_len)
+ char *hostname;
+ char *community_name;
+ int community_len;
+ {
+ unsigned char packet[1024];
+ int packet_len;
+ int remaining_len;
+ int fd, rc, sock_len;
+ struct sockaddr_in sock, dest_sock;
+ struct timeval timeout;
+ unsigned long host_addr, read_mask;
+ int tries;
+
+
+
+
+Carpenter & Wijnen [Page 34]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ host_addr = lookup_host(hostname);
+ packet_len = 0;
+ bcopy(asn1_hdr, packet, sizeof(asn1_hdr));
+ packet_len += sizeof(asn1_hdr);
+
+ remaining_len = sizeof(version) + 1 +
+ community_len + sizeof(request);
+
+ packet[packet_len++] = remaining_len & 0xff;
+ bcopy(version, packet + packet_len, sizeof(version));
+ packet_len += sizeof(version);
+ packet[packet_len++] = community_len & 0xff;
+ bcopy(community_name, packet + packet_len, community_len);
+ packet_len += community_len;
+ bcopy(request, packet + packet_len, sizeof(request));
+ packet_len += sizeof(request);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ return (-1);
+ }
+ bzero(&sock, sizeof(sock));
+ sock.sin_family = AF_INET;
+ sock.sin_port = 0;
+ sock.sin_addr.s_addr = 0;
+ rc = bind(fd, &sock, sizeof(sock));
+ if (rc < 0)
+ return (-1);
+ timeout.tv_sec = 3;
+ timeout.tv_usec = 0;
+ bzero(&dest_sock, sizeof(dest_sock));
+ dest_sock.sin_family = AF_INET;
+ dest_sock.sin_port = htons(161);
+ dest_sock.sin_addr.s_addr = host_addr;
+
+ tries = 0;
+ while (++tries < 4) {
+ rc = sendto(fd, packet, packet_len, 0, &dest_sock,
+ sizeof(dest_sock));
+ read_mask = 1 << fd;
+ rc = select(read_mask + 1, &read_mask, 0, 0, &timeout);
+ if (rc <= 0)
+ continue;
+ sock_len = sizeof(dest_sock);
+ packet_len = recvfrom(fd, packet, sizeof(packet), 0,
+ &dest_sock, &sock_len);
+ if (packet_len <= 0) {
+ return (-1);
+
+
+
+Carpenter & Wijnen [Page 35]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ }
+ rc = extract_DPI_port(packet, packet_len);
+ return (rc);
+ }
+ return (-1);
+ }
+
+ static extract_DPI_port(packet, len)
+ unsigned char packet[];
+ int len;
+
+ {
+ int offset;
+ int port;
+
+ /* should do error checking (like for noSuchName) */
+ offset = len - 2;
+ port = (packet[offset] << 8) + packet[offset + 1];
+ return (port);
+ }
+
+SAMPLE DPI FUNCTIONS
+
+ /* DPI parser */
+
+ #ifdef VM
+ #include "manifest.h"
+ #endif
+
+ #include "snmp_dpi.h"
+
+ static struct dpi_get_packet *pDPIget();
+ static struct dpi_next_packet *pDPInext();
+ static struct dpi_set_packet *pDPIset();
+ static struct dpi_trap_packet *pDPItrap();
+ static struct dpi_resp_packet *pDPIresponse();
+
+ static void fDPIget();
+ static void fDPInext();
+ static void fDPIset();
+ static void fDPItrap();
+ static void fDPIresponse();
+
+ static int cDPIget();
+ static int cDPInext();
+ static int cDPIset();
+ static int cDPItrap();
+ static int cDPIresponse();
+
+
+
+Carpenter & Wijnen [Page 36]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ static struct snmp_dpi_hdr *mkDPIhdr();
+ static struct dpi_get_packet *mkDPIget();
+ static struct dpi_next_packet *mkDPInext();
+ struct dpi_set_packet *mkDPIset();
+
+
+ extern char *malloc();
+
+ static unsigned char new_packet[1024];
+ static int packet_len;
+
+ struct snmp_dpi_hdr *pDPIpacket(packet)
+ unsigned char *packet;
+ {
+ struct snmp_dpi_hdr *hdr;
+ int len, offset;
+
+
+ hdr = (struct snmp_dpi_hdr *) malloc(sizeof(struct snmp_dpi_hdr));
+ if (hdr == 0)
+ return (0);
+
+ len = (packet[0] << 8) + packet[1];
+ len += 2;
+ offset = 2;
+ hdr->proto_major = packet[offset++];
+ hdr->proto_minor = packet[offset++];
+ hdr->proto_release = packet[offset++];
+ hdr->packet_type = packet[offset++];
+ switch (hdr->packet_type) {
+ case SNMP_DPI_GET:
+ case SNMP_DPI_REGISTER:
+ hdr->packet_body.dpi_get =
+ pDPIget(packet + offset, len - offset);
+ break;
+ case SNMP_DPI_GET_NEXT:
+ hdr->packet_body.dpi_next =
+ pDPInext(packet + offset, len - offset);
+ break;
+ case SNMP_DPI_SET:
+ hdr->packet_body.dpi_set =
+ pDPIset(packet + offset, len - offset);
+ break;
+ case SNMP_DPI_TRAP:
+ hdr->packet_body.dpi_trap =
+ pDPItrap(packet + offset, len - offset);
+ break;
+ case SNMP_DPI_RESPONSE:
+
+
+
+Carpenter & Wijnen [Page 37]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ hdr->packet_body.dpi_response =
+ pDPIresponse(packet + offset, len - offset);
+ break;
+ }
+ return (hdr);
+ }
+
+ static struct dpi_get_packet *pDPIget(packet, len)
+ unsigned char *packet;
+ int len;
+ {
+ struct dpi_get_packet *get;
+ int l;
+
+ get = (struct dpi_get_packet *)
+ malloc(sizeof(struct dpi_get_packet));
+ if (get == 0)
+ return (0);
+ l = strlen(packet) + 1;
+ get->object_id = malloc(l);
+ strcpy(get->object_id, packet);
+ return (get);
+ }
+
+ static struct dpi_next_packet *pDPInext(packet, len)
+ unsigned char *packet;
+ int len;
+ {
+ struct dpi_next_packet *next;
+ int l;
+ unsigned char *cp;
+
+ next = (struct dpi_next_packet *)
+ malloc(sizeof(struct dpi_next_packet));
+ if (next == 0)
+ return (0);
+ cp = packet;
+ l = strlen(cp) + 1;
+ next->object_id = malloc(l);
+ strcpy(next->object_id, cp);
+ cp += l;
+ l = strlen(cp) + 1;
+ next->group_id = malloc(l);
+ strcpy(next->group_id, cp);
+ return (next);
+ }
+
+ static struct dpi_set_packet *pDPIset(packet, len)
+
+
+
+Carpenter & Wijnen [Page 38]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ unsigned char *packet;
+ int len;
+ {
+ struct dpi_set_packet *set;
+ int l;
+ unsigned char *cp;
+
+ if (len == 0)
+ return (0); /* nothing to parse */
+ set = (struct dpi_set_packet *)
+ malloc(sizeof(struct dpi_set_packet));
+ if (set == 0)
+ return (0);
+
+ cp = packet;
+ l = strlen(cp) + 1;
+ set->object_id = malloc(l);
+ strcpy(set->object_id, cp);
+ cp += l;
+ set->type = *(cp++);
+ l = (*(cp++) << 8);
+ l += *(cp++);
+ set->value_len = l;
+ set->value = malloc(l);
+ bcopy(cp, set->value, l);
+ return (set);
+ }
+
+ static struct dpi_trap_packet *pDPItrap(packet, len)
+ unsigned char *packet;
+ int len;
+ {
+ struct dpi_trap_packet *trap;
+
+ trap = (struct dpi_trap_packet *)
+ malloc(sizeof(struct dpi_trap_packet));
+ if (trap == 0)
+ return (0);
+
+ trap->generic = *packet;
+ trap->specific = *(packet + 1);
+ trap->info = pDPIset(packet + 2, len - 2);
+ return (trap);
+ }
+
+ static struct dpi_resp_packet *pDPIresponse(packet, len)
+ unsigned char *packet;
+ int len;
+
+
+
+Carpenter & Wijnen [Page 39]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ {
+ struct dpi_resp_packet *resp;
+
+ resp = (struct dpi_resp_packet *)
+ malloc(sizeof(struct dpi_resp_packet));
+ if (resp == 0)
+ return (0);
+
+ resp->ret_code = *packet;
+ resp->ret_data = pDPIset(packet + 1, len - 1);
+ return (resp);
+ }
+
+ void fDPIparse(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ if (hdr == 0)
+ return;
+ switch (hdr->packet_type) {
+ case SNMP_DPI_GET:
+ case SNMP_DPI_REGISTER:
+ fDPIget(hdr);
+ break;
+ case SNMP_DPI_GET_NEXT:
+ fDPInext(hdr);
+ break;
+ case SNMP_DPI_SET:
+ fDPIset(hdr);
+ break;
+ case SNMP_DPI_TRAP:
+ fDPItrap(hdr);
+ break;
+ case SNMP_DPI_RESPONSE:
+ fDPIresponse(hdr);
+ break;
+ }
+ free(hdr);
+ }
+
+ static void fDPIget(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ struct dpi_get_packet *get;
+
+ get = hdr->packet_body.dpi_get;
+ if (get == 0)
+ return;
+ if (get->object_id)
+
+
+
+Carpenter & Wijnen [Page 40]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ free(get->object_id);
+ free(get);
+ }
+
+ static void fDPInext(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ struct dpi_next_packet *next;
+
+ next = hdr->packet_body.dpi_next;
+ if (next == 0)
+ return;
+ if (next->object_id)
+ free(next->object_id);
+ if (next->group_id)
+ free(next->group_id);
+ free(next);
+ }
+
+ static void fDPIset(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ struct dpi_set_packet *set;
+
+ set = hdr->packet_body.dpi_set;
+ if (set == 0)
+ return;
+ if (set->object_id)
+ free(set->object_id);
+ if (set->value)
+ free(set->value);
+ free(set);
+ }
+
+ static void fDPItrap(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ struct dpi_trap_packet *trap;
+ struct dpi_set_packet *set;
+
+ trap = hdr->packet_body.dpi_trap;
+ if (trap == 0)
+ return;
+
+ set = trap->info;
+ if (set != 0) {
+ if (set->object_id)
+ free(set->object_id);
+
+
+
+Carpenter & Wijnen [Page 41]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ if (set->value)
+ free(set->value);
+ free(set);
+ }
+ free(trap);
+ }
+
+ static void fDPIresponse(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ struct dpi_resp_packet *resp;
+ struct dpi_set_packet *set;
+
+ resp = hdr->packet_body.dpi_response;
+ if (resp == 0)
+ return;
+
+ set = resp->ret_data;
+ if (set != 0) {
+ if (set->object_id)
+ free(set->object_id);
+ if (set->value)
+ free(set->value);
+ free(set);
+ }
+ free(resp);
+ }
+
+ unsigned char *cDPIpacket(hdr)
+ struct snmp_dpi_hdr *hdr;
+ {
+ int rc, len;
+ if (hdr == 0) {
+ return (0);
+ }
+ packet_len = 2;
+ new_packet[packet_len++] = hdr->proto_major;
+ new_packet[packet_len++] = hdr->proto_minor;
+ new_packet[packet_len++] = hdr->proto_release;
+ new_packet[packet_len++] = hdr->packet_type;
+ switch (hdr->packet_type) {
+ case SNMP_DPI_GET:
+ case SNMP_DPI_REGISTER:
+ rc = cDPIget(hdr->packet_body.dpi_get);
+ break;
+ case SNMP_DPI_GET_NEXT:
+ rc = cDPInext(hdr->packet_body.dpi_next);
+ break;
+
+
+
+Carpenter & Wijnen [Page 42]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ case SNMP_DPI_SET:
+ rc = cDPIset(hdr->packet_body.dpi_set);
+ break;
+ case SNMP_DPI_TRAP:
+ rc = cDPItrap(hdr->packet_body.dpi_trap);
+ break;
+ case SNMP_DPI_RESPONSE:
+ rc = cDPIresponse(hdr->packet_body.dpi_response);
+ break;
+ }
+ if (rc == -1)
+ return (0);
+ len = packet_len - 2;
+ new_packet[1] = len & 0xff;
+ len >>= 8;
+ new_packet[0] = len & 0xff;
+ return (new_packet);
+ }
+
+ static int cDPIget(get)
+ struct dpi_get_packet *get;
+ {
+ if (get->object_id == 0)
+ return (-1);
+
+ strcpy(&new_packet[packet_len], get->object_id);
+ packet_len += strlen(get->object_id) + 1;
+ return (0);
+ }
+
+ static int cDPInext(next)
+ struct dpi_next_packet *next;
+ {
+ if (next->object_id == 0)
+ return (-1);
+ if (next->group_id == 0)
+ return (-1);
+
+ strcpy(&new_packet[packet_len], next->object_id);
+ packet_len += strlen(next->object_id) + 1;
+ strcpy(&new_packet[packet_len], next->group_id);
+ packet_len += strlen(next->group_id) + 1;
+ return (0);
+ }
+
+ static int cDPIset(set)
+ struct dpi_set_packet *set;
+ {
+
+
+
+Carpenter & Wijnen [Page 43]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ int len;
+
+ if (set->object_id == 0)
+ return (-1);
+ if ((set->value == 0) && (set->value_len != 0))
+ return (-1);
+
+ strcpy(&new_packet[packet_len], set->object_id);
+ packet_len += strlen(set->object_id) + 1;
+ new_packet[packet_len++] = set->type;
+ len = set->value_len >> 8;
+ new_packet[packet_len++] = len & 0xff;
+ new_packet[packet_len++] = set->value_len & 0xff;
+ bcopy(set->value, &new_packet[packet_len], set->value_len);
+ packet_len += set->value_len;
+ return (0);
+ }
+
+ static int cDPIresponse(resp)
+ struct dpi_resp_packet *resp;
+ {
+ int rc;
+
+ if (resp == 0)
+ return (-1);
+
+ new_packet[packet_len++] = resp->ret_code;
+ if (resp->ret_data != 0) {
+ rc = cDPIset(resp->ret_data);
+ } else
+ rc = 0;
+ return (rc);
+ }
+
+ static int cDPItrap(trap)
+ struct dpi_trap_packet *trap;
+ {
+ int rc;
+
+ new_packet[packet_len++] = trap->generic;
+ new_packet[packet_len++] = trap->specific;
+ if (trap->info != 0)
+ rc = cDPIset(trap->info);
+ else
+ rc = 0;
+ return (rc);
+ }
+
+
+
+
+Carpenter & Wijnen [Page 44]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ unsigned char *mkMIBquery(cmd, oid_name, group_oid, type, len, value)
+ int cmd;
+ char *oid_name, *group_oid;
+ int type, len;
+ char *value;
+ {
+ struct snmp_dpi_hdr *hdr;
+ unsigned char *cp;
+
+ hdr = mkDPIhdr(cmd);
+ if (hdr == 0)
+ return (0);
+ switch (hdr->packet_type) {
+ case SNMP_DPI_GET:
+ case SNMP_DPI_REGISTER:
+ hdr->packet_body.dpi_get = mkDPIget(oid_name);
+ break;
+ case SNMP_DPI_GET_NEXT:
+ hdr->packet_body.dpi_next = mkDPInext(oid_name, group_oid);
+ break;
+ case SNMP_DPI_SET:
+ hdr->packet_body.dpi_set =
+ mkDPIset(oid_name, type, len, value);
+ break;
+ }
+ cp = cDPIpacket(hdr);
+ fDPIparse(hdr);
+ return (cp);
+ }
+
+ unsigned char *mkDPIregister(oid_name)
+ char *oid_name;
+ {
+ return (mkMIBquery(SNMP_DPI_REGISTER, oid_name));
+ }
+
+ unsigned char *mkDPIresponse(ret_code, value_list)
+ int ret_code;
+ struct dpi_set_packet *value_list;
+ {
+ struct snmp_dpi_hdr *hdr;
+ struct dpi_resp_packet *resp;
+ unsigned char *cp;
+
+ hdr = mkDPIhdr(SNMP_DPI_RESPONSE);
+ resp = (struct dpi_resp_packet *)
+ malloc(sizeof(struct dpi_resp_packet));
+ if (resp == 0) {
+
+
+
+Carpenter & Wijnen [Page 45]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ free(hdr);
+ return (0);
+ }
+ hdr->packet_body.dpi_response = resp;
+ resp->ret_code = ret_code;
+ resp->ret_data = value_list;
+ cp = cDPIpacket(hdr);
+ fDPIparse(hdr);
+ return (cp);
+ }
+
+ unsigned char *mkDPItrap(generic, specific, value_list)
+ int generic, specific;
+ struct dpi_set_packet *value_list;
+ {
+ struct snmp_dpi_hdr *hdr;
+ struct dpi_trap_packet *trap;
+ unsigned char *cp;
+
+ hdr = mkDPIhdr(SNMP_DPI_TRAP);
+ trap = (struct dpi_trap_packet *)
+ malloc(sizeof(struct dpi_trap_packet));
+ if (trap == 0) {
+ free(hdr);
+ return (0);
+ }
+ hdr->packet_body.dpi_trap = trap;
+ trap->generic = generic;
+ trap->specific = specific;
+ trap->info = value_list;
+ cp = cDPIpacket(hdr);
+ fDPIparse(hdr);
+ return (cp);
+ }
+
+ static struct snmp_dpi_hdr *mkDPIhdr(type)
+ int type;
+ {
+
+ struct snmp_dpi_hdr *hdr;
+
+ hdr = (struct snmp_dpi_hdr *) malloc(sizeof(struct snmp_dpi_hdr));
+ if (hdr == 0)
+ return (0);
+ hdr->proto_major = SNMP_DPI_PROTOCOL;
+ hdr->proto_minor = SNMP_DPI_VERSION;
+ hdr->proto_release = SNMP_DPI_RELEASE;
+ hdr->packet_type = type;
+
+
+
+Carpenter & Wijnen [Page 46]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ return (hdr);
+ }
+
+ static struct dpi_get_packet *mkDPIget(oid_name)
+ char *oid_name;
+ {
+ struct dpi_get_packet *get;
+ int l;
+
+ get = (struct dpi_get_packet *)
+ malloc(sizeof(struct dpi_get_packet));
+ if (get == 0)
+ return (0);
+
+ l = strlen(oid_name) + 1;
+ get->object_id = malloc(l);
+ strcpy(get->object_id, oid_name);
+ return (get);
+ }
+
+ static struct dpi_next_packet *mkDPInext(oid_name, group_oid)
+ char *oid_name;
+ char *group_oid;
+ {
+ struct dpi_next_packet *next;
+ int l;
+
+ next = (struct dpi_next_packet *)
+ malloc(sizeof(struct dpi_next_packet));
+ if (next == 0)
+ return (0);
+ l = strlen(oid_name) + 1;
+ next->object_id = malloc(l);
+ strcpy(next->object_id, oid_name);
+ l = strlen(group_oid) + 1;
+ next->group_id = malloc(l);
+ strcpy(next->group_id, group_oid);
+ return (next);
+ }
+
+ struct dpi_set_packet *mkDPIset(oid_name, type, len, value)
+ char *oid_name;
+ int type;
+ int len;
+ char *value;
+ {
+ struct dpi_set_packet *set;
+ int l;
+
+
+
+Carpenter & Wijnen [Page 47]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ set = (struct dpi_set_packet *)
+ malloc(sizeof(struct dpi_set_packet));
+ if (set == 0)
+ return (0);
+
+ l = strlen(oid_name) + 1;
+ set->object_id = malloc(l);
+ strcpy(set->object_id, oid_name);
+ set->type = type;
+ set->value_len = len;
+ set->value = malloc(len);
+ bcopy(value, set->value, len);
+ return (set);
+ }
+
+
+SAMPLE SOURCES FOR ANONYMOUS FTP
+
+ The complete source to two SNMP DPI-related programs is available for
+ anonymous ftp from the University of Toronto. The host name to use
+ is "vm.utcs.utoronto.ca" (128.100.100.2). The files are in the
+ "anonymou.204" minidisk, so one must issue a "cd anonymou.204" after
+ having logged in. Don't forget to use the binary transmission mode.
+
+The Ping Engine
+
+ This program is an SNMP DPI sub-agent which allows network management
+ stations to perform remote PINGs. The source to this applications is
+ in the file "ping_eng.tarbin". The source to the SNMP DPI API is
+ also contained within the archive.
+
+The DPI->SMUX daemon
+
+ This program illustrates what is required to include the SNMP DPI in
+ an SNMP agent. This is actually a SMUX-based agent that works with
+ the ISODE SNMP agent and provides an interface for SNMP DPI sub-
+ agents. The source to this program is in the file "dpid.tarbin".
+ ISODE 6.7, or later, is a prerequisite.
+
+References
+
+ [1] Case, J., Fedor, M., Schoffstall, M., and J. Davin, "Simple
+ Network Management Protocol", RFC 1157, SNMP Research,
+ Performance Systems International, Performance Systems
+ International, MIT Laboratory for Computer Science, May 1990.
+
+ [2] Information processing systems - Open Systems Interconnection,
+ "Specification of Abstract Syntax Notation One (ASN.1)",
+
+
+
+Carpenter & Wijnen [Page 48]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+ International Organization for Standardization, International
+ Standard 8824, December 1987.
+
+ [3] Information processing systems - Open Systems Interconnection,
+ "Specification of Basic Encoding Rules for Abstract Syntax
+ Notation One (ASN.1)", International Organization for
+ Standardization, International Standard 8825, December 1987.
+
+ [4] McCloghrie K., and M. Rose, "Management Information Base for
+ Network Management of TCP/IP-based internets", RFC 1156,
+ Performance Systems International and Hughes LAN Systems, May
+ 1990.
+
+ [5] Rose, M., and K. McCloghrie, "Structure and Identification of
+ Management Information for TCP/IP-based internets", RFC 1155,
+ Performance Systems International and Hughes LAN Systems, May
+ 1990.
+
+ [6] International Business Machines, Inc., "TCP/IP for VM:
+ Programmer's Reference", SC31-6084-0, 1990.
+
+ [7] International Business Machines, Inc., "Virtual Machine System
+ Facilities for Programming, Release 6", SC24-5288-01, 1988.
+
+ [8] International Business Machines, Inc., "TCP/IP Version 1.1 for
+ OS/2 EE: Programmer's Reference", SC31-6077-1, 1990.
+
+Security Considerations
+
+ Security issues are not discussed in this memo.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 49]
+
+RFC 1228 SNMP-DPI May 1991
+
+
+Authors' Addresses
+
+ Geoffrey C. Carpenter
+ IBM T. J. Watson Research Center
+ P. O. Box 218
+ Yorktown Heights, NY 10598
+
+ Phone: (914) 945-1970
+
+ Email: gcc@watson.ibm.com
+
+
+ Bert Wijnen
+ IBM International Operations
+ Watsonweg 2
+ 1423 ND Uithoorn
+ The Netherlands
+
+ Phone: +31-2975-53316
+
+ Email: wijnen@uitvm2.iinus1.ibm.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Carpenter & Wijnen [Page 50]
+ \ No newline at end of file