RFC 2089

V2ToV1 Mapping SNMPv2 onto SNMPv1 within a bi-lingual SNMP agent

๐Ÿ“… published January 1997, from ietf

RFC 2089: V2ToV1 ๐Ÿ“ฎ๐ŸŽ€

Okay bestie, so this is RFC 2089, and its title is Mapping SNMPv2 onto SNMPv1 within a bi-lingual SNMP agent (nicknamed V2ToV1) โœจ. It was written by B. Wijnen from IBM and D. Levi from SNMP Research, Inc, and it's dated January 1997 ๐Ÿ—“๏ธ. It's marked as Informational ๐Ÿงš, which means it's a helpful document and not an official standard. The header doesn't mention anything it obsoletes or updates, so there's nothing to chase down there ๐Ÿ’….

Status of this Memo ๐Ÿ“œ

This memo gives info to the Internet community. It does not specify an Internet standard of any kind, and distribution of it is unlimited ๐ŸŒธ.

Abstract ๐Ÿฆ‹

The whole point of this memo is to write down one shared way of turning an SNMPv2 response into an SNMPv1 response, inside a bi-lingual SNMP agent. A bi-lingual agent is just one that speaks both SNMPv1 and SNMPv2 ๐Ÿซถ.

Table of Contents ๐Ÿ—‚๏ธ

  1.0  Introduction  . . . . . . . . . . . . . . . . . . . . . . .  2
  2.0  Mapping SNMPv2 into SNMPv1  . . . . . . . . . . . . . . . .  2
  2.1  Mapping SNMPv2 error-status into SNMPv1 error-status  . . .  3
  2.2  Mapping SNMPv2 exceptions into SNMPv1   . . . . . . . . . .  3
  2.3  Mapping noSuchObject and noSuchInstance   . . . . . . . . .  4
  2.4  Mapping endOfMibView  . . . . . . . . . . . . . . . . . . .  5
  2.5  Mapping SNMPv2 SMI into SNMPv1  . . . . . . . . . . . . . .  5
  3.0  Processing SNMPv1 requests  . . . . . . . . . . . . . . . .  6
  3.1  Processing an SNMPv1 GET request  . . . . . . . . . . . . .  6
  3.2  Processing an SNMPv1 GETNEXT request  . . . . . . . . . . .  7
  3.3  Processing an outgoing SNMPv2 trap  . . . . . . . . . . . .  8
  4.0  Acknowledgements  . . . . . . . . . . . . . . . . . . . . . 10
  5.0  References  . . . . . . . . . . . . . . . . . . . . . . . . 10
  6.0  Security Considerations   . . . . . . . . . . . . . . . . . 10
  7.0  Authors' Addresses  . . . . . . . . . . . . . . . . . . . . 11
  Appendix A.  Background Information  . . . . . . . . . . . . .   12
  A.1  Mapping of error-status Values  . . . . . . . . . . . . .   12
  A.2  SNMPv1 traps without Counter64 varBinds.  . . . . . . . .   12

1.0 Introduction ๐ŸŒท

So SNMPv1 (that's RFC1157 [1]) is now a full standard, and SNMPv2 (RFC1905 [1]) is a DRAFT standard ๐Ÿ“˜. Lots of agents are going to support both versions of requests coming in from SNMP management entities ๐Ÿ’œ. A lot of the time the instrumentation underneath will be built with the new SNMPv2 SMI and the SNMPv2 protocol ๐Ÿ”ง. That means the SNMP engine has a job: any SNMPv2 response data from that SNMPv2 compliant instrumentation needs to get converted into a proper SNMPv1 response, as long as the original request came in as an SNMPv1 request. The engine should also handle turning SNMPv2 traps into SNMPv1 traps ๐Ÿšจ, whether those traps came from an application or from the SNMPv2 compliant instrumentation, if the agent is set up to send traps to an SNMPv1 manager ๐Ÿ“จ.

It's really useful if every agent does this mapping the same way ๐Ÿ“. This document describes one, based on discussions and the consensus that seemed to form on the various mailing lists ๐Ÿ’ฌ. The authors also compared their own implementations of these mappings, found a few tiny differences, and decided to make their versions behave the same. Then they wrote it down so everyone else can benefit too ๐Ÿซถโœจ.

We recommend that all agents implement this same mapping ๐ŸŽ€.

Also, the mapping in this document should be followed by SNMP proxies that map between SNMPv1 management applications and SNMPv2 agents ๐Ÿฆ‹.

2.0 Mapping SNMPv2 into SNMPv1 ๐Ÿ’…

These are the kinds of mappings we need:

  • Mapping of the SNMPv2 error-status into SNMPv1 error-status ๐Ÿ”ฅ
  • Mapping of the SNMPv2 exceptions into SNMPv1 error-status ๐Ÿ™ˆ
  • Skipping object instances that have a non-SNMPv1 Syntax (specifically Counter64) ๐Ÿงš
  • Mapping of SNMPv2 traps into SNMPv1 traps ๐ŸŒˆ

2.1 Mapping SNMPv2 error-status into SNMPv1 error-status ๐Ÿ’–

SNMPv2 (RFC1905 [1]) gives us a bunch of error-status values that explain what went wrong in way more detail ๐Ÿ”. The problem is that an SNMPv1 manager doesn't understand those values ๐Ÿ˜ญ.

So here's the deal. If the instrumentation code returns response data and uses an SNMPv2 error-status to say whether the requested operation worked, and the original request was an SNMPv1 request, we must map that error-status into an SNMPv1 error-status when we build the SNMP response PDU ๐Ÿ› ๏ธ.

Here's the table for turning an SNMPv2 error-status into an SNMPv1 error-status:

          SNMPv2 error-status    SNMPv1 error-status
          ===================    ===================
          noError                noError
          tooBig                 tooBig
          noSuchName             noSuchName
          badValue               badValue
          readOnly               readOnly
          genErr                 genErr
          wrongValue             badValue
          wrongEncoding          badValue
          wrongType              badValue
          wrongLength            badValue
          inconsistentValue      badValue
          noAccess               noSuchName
          notWritable            noSuchName
          noCreation             noSuchName
          inconsistentName       noSuchName
          resourceUnavailable    genErr
          commitFailed           genErr
          undoFailed             genErr
          authorizationError     noSuchName

2.2 Mapping SNMPv2 exceptions into SNMPv1 ๐ŸŽญ

SNMPv2 has these things called exception values. They let an SNMPv2 response PDU hand back as much management info as it can, even if one or more of the requested variables don't exist ๐ŸŒŸ. SNMPv1 doesn't support exception values, so when any error happens it doesn't return the value of any management info ๐Ÿ˜ค.

When more than one variable doesn't exist, an SNMPv1 agent can only return one error and the index of one variable. The agent decides, based on how it's implemented, which variable gets named as the cause of the error through the error-index field ๐ŸŽฏ. So an SNMPv1 manager can't assume anything about whether the other variables in the request are valid ๐Ÿคทโ€โ™€๏ธ.

So when an SNMPv1 request comes in, we must check the varBinds returned from SNMPv2 compliant instrumentation for exception values, and turn those exception values into SNMPv1 error codes ๐Ÿ”.

What kind of exception we can get back, and what we have to do about it, depends on the SNMP operation that was requested:

  • For SNMP GET requests we can get back noSuchObject and noSuchInstance.
  • For SNMP GETNEXT requests we can get back endOfMibView.
  • For SNMP SET requests we cannot get back any exceptions.
  • For SNMP GETBULK requests we can get back endOfMibView, but such a request should only come in as an SNMPv2 request, so we do not have to worry about any mapping onto SNMPv1. If a GETBULK comes in as an SNMPv1 request, it is treated as an error and the packet is dropped ๐Ÿšซ.

2.3 Mapping noSuchObject and noSuchInstance ๐Ÿ™…โ€โ™€๏ธ

A noSuchObject or noSuchInstance exception from SNMPv2 compliant instrumentation means the requested object instance can't be returned ๐Ÿ’”. The SNMPv1 error code for that is noSuchName, so the error-status field of the response PDU should be set to noSuchName. The error-index field gets set to the index of the varBind where the exception happened, and the varBind list from the original request comes back with the response PDU ๐Ÿ“‹.

Also, when the response has more than one exception, the agent may pick any one of them to return ๐ŸŽฒ.

2.4 Mapping endOfMibView ๐Ÿ

When SNMPv2 compliant instrumentation sends back a varBind with an endOfMibView exception in response to a GETNEXT request, it's saying there are no object instances that come lexicographically after the object in the request ๐Ÿ”š. In an SNMPv1 agent this normally turns into a noSuchName error, so the error-status field of the response PDU should be set to noSuchName. The error-index field is set to the index of the varBind where the exception happened, and the varBind list from the original request is returned with the response PDU ๐Ÿ’Œ.

Also, when the response has more than one exception, the agent may pick any one of them to return ๐ŸŽฒ.

2.5 Mapping SNMPv2 SMI into SNMPv1 ๐Ÿงฉ

The SNMPv2 SMI (RFC1902 [2]) basically adds just one new syntax that causes trouble for SNMPv1 managers, and that's Counter64 ๐Ÿ˜ฌ. Everything else in it is fine for SNMPv1 managers ๐Ÿ‘.

What this means for bi-lingual agents is that they should make sure they never send a varBind with a Counter64 value to an SNMPv1 manager ๐Ÿšง.

The best accepted practice is to treat those object instances as implicitly left out of the view. So:

  • On an SNMPv1 GET request, we return an error-status of noSuchName, and the error-index is set to the varBind that causes the error ๐ŸŽฏ.
  • On an SNMPv1 GETNEXT request, we skip that object instance and go fetch the next object instance after the one with a syntax of Counter64 โญ๏ธ.
  • Any SET request with a varBind that has a Counter64 value must have come from an SNMPv2 manager, so it shouldn't cause a problem ๐Ÿ™Œ. If we do get a Counter64 value in an SNMPv1 SET packet, it should result in an ASN.1 parse error, since Counter64 isn't valid in the SNMPv1 protocol ๐Ÿšซ. When an ASN.1 parse error happens, the counter snmpInASNParseErrs is incremented and no response is returned ๐Ÿค.
  • GETBULK is an SNMPv2 operation, so it should never come from an SNMPv1 manager ๐Ÿ™…โ€โ™€๏ธ. If we do get a GETBULK PDU in an SNMPv1 packet, we consider it an invalid PDU-type and drop the packet ๐Ÿ—‘๏ธ.

3.0 Processing SNMPv1 requests ๐Ÿ›ค๏ธ

This section has a step by step walkthrough of how to handle SNMPv1 requests in an agent where the underlying instrumentation code is SNMPv2 compliant โœจ๐Ÿงš.

3.1 Processing an SNMPv1 GET request ๐ŸŽ€

okay so first, the request gets turned into a call to the underlying instrumentation. how that works is totally implementation specific, so you do you ๐Ÿงš

when the instrumentation sends back response data using SNMPv2 syntax and error-status values, then:

  1. If the error-status is anything other than noError:
    • a. The error status gets translated to an SNMPv1 error-status using the table from 2.1, "Mapping SNMPv2 error-status into SNMPv1 error-status" on page 2 ๐Ÿ’…
    • b. The error-index is set to the position (in the original request) of the varBind that caused the error-status.
    • c. The varBindList of the response PDU is made exactly the same as the varBindList that was received in the original request.
  2. If the error-status is noError, then look for any varBind that has an SNMPv2 exception (noSuchObject or noSuchInstance) or an SNMPv2 syntax that SNMPv1 doesn't know about (Counter64) ๐Ÿ‘€ (if there's more than one, the agent may choose any of them). If there are any such varBinds, then for the one chosen:
    • a. Set the error-status to noSuchName
    • b. Set the error-index to the position (in the varBindList of the original request) of the varBind that returned that SNMPv2 exception or syntax.
    • c. Make the varBindList of the response PDU exactly the same as the varBindList that was received in the original request.
  3. If there are no such varBinds, then:
    • a. Set the error-status to noError
    • b. Set the error-index to zero
    • c. Compose the varBindList of the response, using the data exactly as the instrumentation code returned it โœจ

3.2 Processing an SNMPv1 GETNEXT request ๐Ÿฆ‹

same energy as GET, but it's a little more involved, ngl. first the request gets turned into a call to the underlying instrumentation (implementation specific, as always). there may be repeated calls to the same or different pieces of instrumentation, all trying to find the first object that comes lexicographically after each object in the request. that part is also implementation specific ๐ŸŒˆ

once the instrumentation finally sends back response data using SNMPv2 syntax and error-status values, then:

  1. If the error-status is anything other than noError:
    • a. The error status gets translated to an SNMPv1 error-status using the table from 2.1, "Mapping SNMPv2 error-status into SNMPv1 error-status" on page 2 ๐Ÿ’…
    • b. The error-index is set to the position (in the original request) of the varBind that caused the error-status.
    • c. The varBindList of the response PDU is made exactly the same as the varBindList that was received in the original request.
  2. If the error-status is noError, then:
    • a. If there are any varBinds containing an SNMPv2 syntax of Counter64, then treat those varBinds as not in view, and repeat the call to the instrumentation code as often as needed until a value other than Counter64 comes back ๐Ÿ”
    • b. Look for any varBind that contains the SNMPv2 exception endOfMibView. (If there's more than one, the agent may choose any of them.) If there are any such varBinds, then for the one chosen:
      • 1) Set the error-status to noSuchName
      • 2) Set the error-index to the position (in the varBindList of the original request) of the varBind that returned that SNMPv2 exception.
      • 3) Make the varBindList of the response PDU exactly the same as the varBindList that was received in the original request.
    • c. If there are no such varBinds, then:
      • 1) Set the error-status to noError
      • 2) Set the error-index to zero
      • 3) Compose the varBindList of the response, using the data exactly as the instrumentation code returned it ๐Ÿซถ

3.3 Processing an outgoing SNMPv2 TRAP ๐ŸŒธ

okay this one is giving reverse engineering vibes ๐Ÿ”ฅ if SNMPv2 compliant instrumentation hands an SNMPv2 trap to the SNMP engine, and that trap passes all the regular checks and is headed to an SNMPv1 destination, then the steps below must be followed to convert it into an SNMPv1 trap. basically it's the reverse of the SNMPv1 to SNMPv2 mapping described in RFC1908 [3] ๐Ÿชž

  1. If any varBind in the varBindList has an SNMPv2 syntax of Counter64, then those varBinds are implicitly considered not in view, so they get removed from the varBindList that goes out with the SNMPv1 trap ๐Ÿ™ˆ
  2. The 3 special varBinds in the varBindList of an SNMPv2 trap (sysUpTime.0 (TimeTicks), snmpTrapOID.0 (OBJECT IDENTIFIER) and optionally snmpTrapEnterprise.0 (OBJECT IDENTIFIER)) get removed from the varBindList that goes out with the SNMPv1 trap. those 2 (or 3) varBinds are then used to decide how the other fields in the SNMPv1 trap PDU get set, like this:
    • a. The value of sysUpTime.0 is copied into the timestamp field of the SNMPv1 trap.
    • b. If the snmpTrapOID.0 value is one of the standard traps, the specific-trap field is set to zero and the generic-trap field is set according to this mapping:
   value of snmpTrapOID.0                generic-trap
   ===============================       ============
   1.3.6.1.6.3.1.1.5.1 (coldStart)                  0
   1.3.6.1.6.3.1.1.5.2 (warmStart)                  1
   1.3.6.1.6.3.1.1.5.3 (linkDown)                   2
   1.3.6.1.6.3.1.1.5.4 (linkUp)                     3
   1.3.6.1.6.3.1.1.5.5 (authenticationFailure)      4
   1.3.6.1.6.3.1.1.5.6 (egpNeighborLoss)            5

The enterprise field is set to the value of snmpTrapEnterprise.0 if that varBind is present. otherwise it's set to the value snmpTraps, as defined in RFC1907 [4] ๐Ÿงš

  • c. If the snmpTrapOID.0 value is not one of the standard traps, then the generic-trap field is set to 6 and the specific-trap field is set to the last subid of the snmpTrapOID.0 value.
    • If the next to last subid of snmpTrapOID.0 is zero, then the enterprise field is set to the snmpTrapOID.0 value, and the last 2 subids are truncated from that value.
    • If the next to last subid of snmpTrapOID.0 is not zero, then the enterprise field is set to the snmpTrapOID.0 value, and the last 1 subid is truncated from that value.

In any event, the snmpTrapEnterprise.0 varBind (if present) is ignored in this case ๐Ÿ™…โ€โ™€๏ธ

  1. The agent-addr field is set with the appropriate address of the sending SNMP entity, which is the IP address of the sending entity when the trap goes out over UDP. otherwise, the agent-addr field is set to address 0.0.0.0. ๐Ÿ’œ

4.0 Acknowledgements ๐Ÿซถ

the authors want to thank the SNMPv2 Working Group in general for their contributions ๐ŸŒท special thanks go to these individuals for their detailed review and comments:

  • Mike Daniele (DEC)
  • Dave Harrington (Cabletron)
  • Brian O'Keefe (Hewlett Packard)
  • Keith McCloghrie (Cisco Systems)
  • Dave Perkins (independent)
  • Shawn Routhier (Epilogue)
  • Juergen Schoenwaelder (University of Twente)

5.0 References ๐Ÿ“š

[1]  Jeffrey  D. Case, Mark Fedor, Martin Lee Schoffstall and James
     R. Davin, Simple  Network  Management  Protocol  (SNMP),  SNMP
     Research,  Performance  Systems  International, MIT Laboratory
     for Computer Science, RFC 1157, May 1990.

[2]  Jeffrey D. Case, Keith McCloghrie, Marshall T. Rose and Steven
     Waldbusser, Structure of Managment Information for  Version  2
     of  the  Simple  Network  Management  Protocol  (SNMPv2), SNMP
     Research Inc, Cisco Systems Inc, Dover Beach  Consulting  Inc,
     International Network Services, RFC1902, January 1996.

[3]  Jeffrey D. Case, Keith McCloghrie, Marshall T. Rose and Steven
     Waldbusser, Coexistence between Version 1 and Version 2 of the
     Internet-standard  Network Management Framework, SNMP Research
     Inc,  Cisco  Systems  Inc,   Dover   Beach   Consulting   Inc,
     International Network Services, RFC1908, January 1996.

[4]  Jeffrey D. Case, Keith McCloghrie, Marshall T. Rose and Steven
     Waldbusser,  Management  Information Base for Version 2 of the
     Simple Network Management  Protocol  (SNMPv2),  SNMP  Research
     Inc,   Cisco   Systems   Inc,   Dover  Beach  Consulting  Inc,
     International Network Services, RFC1907, January 1996.

6.0 Security Considerations ๐Ÿ”

Security considerations are not discussed in this memo. ๐Ÿ™ˆ


7.0 Authors' Addresses ๐Ÿ’Œ

Bert Wijnen
IBM International Operations
Watsonweg 2
1423 ND Uithoorn
The Netherlands

Phone: +31-079-322-8316
E-mail: wijnen@vnet.ibm.com


David Levi
SNMP Research, Inc
3001 Kimberlin Heights Rd.
Knoxville, TN 37920-9716
USA

Phone: +1-615-573-1434
E-mail: levi@snmp.com

APPENDIX A. Background Information ๐Ÿง 

here's some reasoning behind a few of the choices that got made ๐Ÿ’–

A.1 Mapping of error-status values ๐ŸŽฏ

the mapping from SNMPv2 error-status values to SNMPv1 error-status values is based on the common interpretation of how an SNMPv1 entity should create an error-status value from the elements of the procedure defined in RFC1157 [1].

someone suggested mapping wrongEncoding to genErr, since it could come from an ASN.1 parsing error. that might be true, but most of the time when we detect an ASN.1 parsing error, we don't know anything about the PDU data yet. most people who responded to our questions had already mapped it to badValue, so we "agreed" on badValue ๐Ÿ’…

A.2 SNMPv1 Traps without Counter64 varBinds. ๐Ÿฆ‹

RFC1448 says that if one of the objects in the varBindList isn't included in the view, then the trap is NOT sent. current SNMPv2u and SNMPv2* documents say the same thing. however, the "rough consensus" is that it's better to send partial information than no information at all. besides:

  • RFC1448 doesn't allow a TRAP to be sent with the varBinds that aren't in the view removed, so it's an all or nothing decision.
  • We do NOT include the Counter64 varBinds... so the "not in view" varBinds don't get sent to the trap destination.
  • The Counter64 objects are "implicit" not in view. If any objects are explicitly not in view, that gets checked before we do the conversion from an SNMPv2 trap to an SNMPv1 trap, so the trap is not sent at all. ๐ŸŒˆ
๐Ÿ“ฆ where this page comes from