RFC 2089
V2ToV1 Mapping SNMPv2 onto SNMPv1 within a bi-lingual SNMP agent
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
Counter64value must have come from an SNMPv2 manager, so it shouldn't cause a problem ๐. If we do get aCounter64value in an SNMPv1 SET packet, it should result in an ASN.1 parse error, sinceCounter64isn't valid in the SNMPv1 protocol ๐ซ. When an ASN.1 parse error happens, the countersnmpInASNParseErrsis 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:
- 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.
- 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.
- 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:
- 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.
- 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] ๐ช
- 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 ๐
- 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 ๐ โโ๏ธ
- 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
- ietf: rfc2089 1997-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms