Don't fall in the traps...

... or the Hitchhiker's guide to SNMP - part III ...

Well, what I had really in mind when I started writing this entry, was to demonstrate how to send an SNMP trap from within an application deployed in Sun's AppServer. You might think that was a curious idea - and I may even agree. However, I quickly realized that I wouldn't be able to make my demonstration without first saying a few words about traps in SNMP. So if you're looking at SNMP because the only thing you want to do is sending SNMP notifications - then here are probably a few things you should know if you don't want to... fall in the traps...

Overview

Before going further and starting to describe traps in SNMP, I might be able to entice you into some background reading. I have already written quite a few blog entries related to SNMP - and some of them will provide you with a layer of background SNMP culture:

Finally - here is a list of the subjects we will talk about today:

What is an SNMP trap?

An SNMP trap is an asynchronous SNMP notification, sent from one SNMP entity (traditionally, an SNMP agent) to another SNMP entity (traditionally, an SNMP manager or management console). An SNMP trap is made from two things: an SNMP PDU - which is defined at the protocol level, and a MIB definition - which explains the semantics of the notification and defines its payload.

The trap PDU

The trap PDU is defined at protocol level. At this point - we can make the distinction between three kind of traps: traps in SNMP v1, traps in SNMP v2 & v3, and SNMP informs.

I am not going to launch here in a full description of the SNMP PDU used to transport SNMP traps, and the interested reader is kindly invited to refer directly to the appropriate RFC for each of the SNMP versions. However, here are a few facts you should probably know:

Traps in SNMP v1

In SNMP v1 - there was a specific PDU dedicated for traps. SNMP v1 made the distinction between generic traps (defined by the SNMP protocol itself) and proprietary traps (defined in application MIBs) and termed 'enterpriseSpecific', since they would only apply to the specific domain of the application in which they were defined.

Generic traps were identified by a small enumerated integer - defined in RFC 1157 as

        generic-trap      -- generic trap type
             INTEGER {
                 coldStart(0),
                 warmStart(1),
                 linkDown(2),
                 linkUp(3),
                 authenticationFailure(4),
                 egpNeighborLoss(5),
                 enterpriseSpecific(6)
              },
                        

Enterprise specific traps where identified by:

  • The value of 'generic-trap' set to enterpriseSpecific(6)
  • An enterprise OID identifying the 'registration authority' under which the trap was defined
  • A 'specific-trap' integer uniquely identifying the trap type within the registration domain defined by the enterprise OID.

These information (generic-trap, specific-trap, enterprise OID), were reflected in specific fields defined in the SNMP v1 Trap-PDU (see RFC 1157 and RFC 1215 for more details).

Traps in SNMP v2 & v3

Starting with SNMP v2 - and continued in SNMP v3 also - all SNMP PDUs have been normalized - that is, they are all built on the same structure, and no longer have any specific fields depending on their type. The only thing that distinguishes them is their PDU type tag - and of course - the semantics of the objects they transport - but this semantics is no longer reflected in the structure of the PDU itself.

As a result, SNMP v2/v3 (the protocols) no longer make the distinction between 'generic traps' and 'specific traps'. SNMP v2/v3 simply define a PDU to transport asynchronous notifications (traps) - but the semantics of the trap is now completely defined in the MIB in which that trap is defined. It therefore presents a much more regular and cleaner separation between the protocol (SNMP) and the model (MIBs) than it used to in SNMP v1.

Associated to this, RFC 3584, Coexistence between Version 1, Version 2, and Version 3 of the Internet-standard Network Management Framework, explains the mappings between traps defined in the various versions of the protocols and in particular shows how traps defined in MIBs written using SMIv1 can be transported with higher version of the protocols. Readers who may not be familiar with the arcanes of the various SNMP versions are invited to refer to my previous entry, Simple Is Not Easy for a brief introduction.

SNMP Informs

In addition to PDU normalization, SNMP v2 introduced a new verb in the protocol, called 'INFORM'. Originally, 'INFORM's were thought to provide a communication channel between SNMP Manager entities - that is, Manager to Manager communication. In reallity, 'INFORM's have been used as a means to implement acknowledged notifications, a task they are much better suited to.

Since all PDUs have been normalized - the content of an 'INFORM' PDU can be rigorously identical to that of a trap PDU. Upon reception of an 'INFORM' PDU, an SNMP entity is required to send it back to the originating application, whose address can be found in the received UDP packet - thus acknowledging the reception of the 'INFORM' message.

What's in a trap?

As we have seen earlier, a trap is not only defined by the protocol itslef, but also, by its MIB definition. In SNMPv1, using SMIv1, traps were defined using the TRAP-TYPE macro. For instance, here is how we would have defined the jvmLowMemoryPoolUsageNotif trap had we used SMIv1:

jvmLowMemoryPoolUsageNotif TRAP-TYPE
    ENTERPRISE  jvmMgtMIBLowMemoryNotifs
    VARIABLES   { jvmMemPoolName, jvmMemPoolUsed, jvmMemPoolThreshdCount }
    DESCRIPTION
           "This notification is sent when the memory usage threshold of
	    a memory pool is exceeded.
           "
    REFERENCE "J2SE 5.0 API Specification,
              java.lang.management.MemoryNotification,
	      java.lang.management.MemoryPoolMXBean"
    ::= 1 
                        

In SMIv2, the TRAP-TYPE macro has been replaced by the NOTIFICATION-TYPE macro - so this is how our actual trap definition, from the JVM-MANAGEMENT-MIB looks like:

jvmLowMemoryPrefix OBJECT IDENTIFIER 
    ::= { jvmMgtMIBLowMemoryNotifs 0 } 

jvmLowMemoryPoolUsageNotif NOTIFICATION-TYPE
    OBJECTS {  jvmMemPoolName, jvmMemPoolUsed, jvmMemPoolThreshdCount }
    STATUS current
    DESCRIPTION
           "This notification is sent when the memory usage threshold of
	    a memory pool is exceeded.
           "
    REFERENCE "J2SE 5.0 API Specification,
              java.lang.management.MemoryNotification,
	      java.lang.management.MemoryPoolMXBean"
    ::= { jvmLowMemoryPrefix  1 }
                        

When the jvmLowMemoryPoolUsageNotif trap is sent through SNMPv2, its OID 'jvmLowMemoryPoolUsageNotif' (or jvmMgtMIBLowMemoryNotifs.0.1) will be included in the varbind list of the SNMPv2 trap PDU, thus permitting to identify which trap is being sent:

[snmpTrapOID.0=jvmMgtMIBLowMemoryNotifs.0.1]

This information replaces the tuple:

(enterprise='jvmMgtMIBLowMemoryNotifs', generic-trap='enterpriseSpecific(6)', specific-trap=1)

that used to be sent through SNMPv1.

Trap Conversion

RFC 3584, Coexistence between Version 1, Version 2, and Version 3 of the Internet-standard Network Management Framework, explains how this mapping is done:
In SNMPv1, a trap used to be identified by three things: its enterprise OID, its generic-trap value, and its specific trap value.
In SNMPv2, these three things have been replaced by a single thing: the notification OID.
Basically, we can say that a trap that used to be defined in SNMP v1 by

(enterprise='jvmMgtMIBLowMemoryNotifs', generic-trap='enterpriseSpecific(6)', specific-trap=1)
        

will be defined in SNMPv2 by the OID 'jvmMgtMIBLowMemoryNotifs.0.1'.
Note that for what used to be 'generic-traps' - linkUp, linkDown etc... standard OIDs have been provided - as explained by RFC 3584:

      generic-trap parameter   snmpTrapOID.0
      ======================   =============
      0                        1.3.6.1.6.3.1.1.5.1 (coldStart)
      1                        1.3.6.1.6.3.1.1.5.2 (warmStart)
      2                        1.3.6.1.6.3.1.1.5.3 (linkDown)
      3                        1.3.6.1.6.3.1.1.5.4 (linkUp)
      4                        1.3.6.1.6.3.1.1.5.5 (authenticationFailure)
      5                        1.3.6.1.6.3.1.1.5.6 (egpNeighborLoss)
                        

Why do I need a MIB definition?

Well, as we have seen, TRAP-TYPE definition, or NOTIFICATION-TYPE definition, is really important - because it defines:

  • The trap identification (enterprise,generic-trap,specific-trap) in SMIv1, trap OID in SMIv2, that is going to be sent over the wire to the manager,
  • The semantics of the trap being sent (english text written in the trap DESCRIPTION clause),
  • The list of additional variables (VARIABLES or OBJECTS clause) that a manager can expect that trap to contain.

Without the MIB definition, it would be impossible for a client application to understand the purpose and semantics of the trap. Indeed, it would be like trying to code against a binary Java library without having access to its Javadoc.

What are the limitations of using traps or informs?

The first limitation is that if you want to be SNMP compliant, you need to send traps for which a definition exists. You cannot 'invent' a trap OID. You could use an existing one - and the MIBs defined by the IETF disman group may be a good source to look at, or you could write your own MIB definition. You will not need to compile the MIB definition in order to write the code that sends the trap, but you will need it to explain to your SNMP clients what they should expect and what it all means.

The second limitation is that traps are transported in SNMP over UDP. As such they are not reliable. Therefore, it is not guaranteed that anybody will receive your traps. Usually, it is rare that traps are swallowed by the network, but it can happen. Also if you are using SNMPv3, your trap could be rejected by the remote application if it doesn't arrive in a timely fashion.

Of course, you could use SNMP informs instead of traps - in order to be sure that your notification has been delivered, but this may not be as satisfactory as you would require: this time it's the response to your inform that could be lost or delayed by the network.

Because these problems can happen, it is usually recommended for SNMP applications not to rely on traps being delivered. It is recommended to design your SNMP MIB in such a way that an SNMP manager could discover that it has missed a trap simply by querrying the state of the objects defined in the MIB. For instance, using the JVM-MANAGEMENT-MIB, a manager can determine that it has missed a jvmLowMemoryPoolUsageNotif notification if it sees that the jvmMemPoolThreshdCount has increased.
This means that if you are considering using traps, and want to adhere to SNMP best practices, you should also be prepared to code a full fledged SNMP agent in order to answer to SNMP manager queries.

Finally, there's a limitation in SNMP packet sizes. You cannot stuff just anything in an UDP packet. This means that planning to use SNMP simply as a transport to tunnel non SNMP information encoded e.g. in plain text, or OCTET-STRING may not always work.

Conclusion

SNMP is often seen as an attractive solution because:

  • It is a standard protocol, almost ubiquitous
  • They say it's simple - well, at least, it's well known
  • Configuring firewalls to let SNMP traffic through is usually quite manageable
  • It goes through UDP - so it's relatively lightweight in terms of network resource consumption (doesn't need an opened peer to peer connection)
  • Sending traps is simple

But don't forget the other side of the medal:

  • It does have its limitations
  • It is not appropriate for everything
  • You cannot ignore MIBs
  • You need to understand what you're doing
  • If you use SNMP v3, configuration will most probably be tricky

Well, if you still think that SNMP traps is what you need - wait for my next blog entry! I might be finally able to talk about my original subject, which was: how to send traps from an application deployed in Sun AppServer.

So watch out! Don't fall in the traps!


Cheers,
Update: If you are looking for an introduction to multi indexed SNMP tables, you may also want to read the 4th episode in the Hitchhiker's Guide To SNMP series: Welcome to the SNMP table!
Comments:

no comments

Posted by ZAHID MAJID on July 31, 2006 at 09:17 AM CEST #

no reply ;-)

Posted by daniel on July 31, 2006 at 10:43 AM CEST #

Hey,Daniel,

Your SNMP series are really good resources for me to learn. Right now I am working on a project that requires writing some business data (defined by RFC3881 which is xml format) into the SNMP trap. In my case, I need to convert the RFC3881 xml schema into the MIB definition. I know there's lots of tools can used to build the MIB. but I did not heard any of them can convert to XML Schema into MIB. any suggestion from you?

Thanks in advance.

Richard

Posted by richard shan on March 03, 2009 at 11:25 AM CET #

Thanx a lot for the article. Let me know if there is an easy way to send traps using a plugin or something using grails in groovy and log4j.

Ushani

Posted by Ushani on October 01, 2009 at 06:34 AM CEST #

its very helpful and very easy to understand.
i thank to Daniel for his wonderful work !!

Posted by praveen on November 19, 2009 at 11:24 PM CET #

Thanks for the info.

Posted by Lý Thông on May 23, 2012 at 10:57 AM CEST #

Post a Comment:
Comments are closed for this entry.
About

Daniel Fuchs blogs on Scene Builder, JMX, SNMP, Java, etc...

The views expressed on this blog are those of the author and do not necessarily reflect the views of Oracle.

Search

Categories
Archives
« September 2015
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today