Responding to SNMPv3 Traps

The SNMPTrapMgr/SNMPTCPTrapMgr provides two different ways of decoding SNMPv3 traps. You can use the AddUser method (please see the AddUser method documentation for more details) or you can use events, which is the approach covered here. The following is a detailed explanation of the sequence of events that fire and how to handle them. The included code snippets use the SNMPTrapMgr component, but the same concepts apply to the SNMPTCPTrapMgr component.

In order to respond to the events correctly, you will need to maintain the appropriate security credentials for each user. This includes the appropriate security level for that user as well as the passwords for authentication and, optionally, encryption. For the code examples in this article I am storing an example user's credentials in a hash table using Tuples, like this:

Tuple userMatt = Tuple.Create("matt", "mattengine"); securityLevelCache = new Hashtable(); securityLevelCache.Add(userMatt, 2); //userMatt has security level 2 (AuthPriv) Tuple mattPasswords = Tuple.Create("authpass", "encryptpass"); passwordCache = new Hashtable(); passwordCache.Add(userMatt, mattPasswords);

These stored credentials will be used to verify the values passed by parameter in the following events. Note that user credentials can be stored in whatever way you prefer, and the use of Tuples and hash tables is not necessary for following the principles of this article.

GetUserSecurityLevel Event Fires

When an SNMPv3 secure trap is received by the SNMPTrapMgr/SNMPTCPTrapMgr, the GetUserSecurityLevel event fires first to determine the correct security level for the username provided in the event argument. The SecurityLevel parameter should be set to 1 (Auth - authentication only) or 2 (AuthPriv - authentication and encryption) depending on the stored security credentials of the user. The exit value of SecurityLevel will determine how many times the GetUserPassword Event will fire: once for Auth and twice for AuthPriv.

Here is an example of a GetUserSecurityLevel event handler setting SecurityLevel to the appropriate value:

static void on_GetUserSecurityLevel(object sender, SnmptrapmgrGetUserSecurityLevelEventArgs e) { Tuple user = Tuple.Create(e.User, e.EngineId); if (securityLevelCache.Contains(user)) { e.SecurityLevel = (int)securityLevelCache[user]; } else { e.SecurityLevel = -1; } }

GetUserPassword Event Fires

The GetUserPassword event now fires to ask for the Authentication Password associated with the user. The PasswordType parameter will be '1' to signal that an Authentication Password should be provided. This same event will fire again for Privacy if SecurityLevel was set to '2' in the GetUserSecurityLevel event, so it is important to check the value of PasswordType in the event handler. The exit value of the Password parameter must be the Authentication password for the appropriate user in order for the process to continue.

Here is an example of a GetUserPassword event handler setting the Authentication password for the appropriate user:

static void on_GetUserPassword(object sender, SnmptrapmgrGetUserPasswordEventArgs e) { Tuple user = Tuple.Create(e.User, e.EngineId); if (passwordCache.Contains(user)) { switch (e.PasswordType) { case 1: e.Password = ((Tuple)passwordCache[user]).Item1; break; } } else { e.Password = ""; } }

GetUserPassword Event Fires Again

If SecurityLevel was set to '2' in the GetUserSecurityLevel event, the GetUserPassword event fires again. The PasswordType parameter will now be '2' for Privacy, and the Password parameter should be set to the encryption password. At this time you also specify the Algorithm to tell the component what type of encryption is used here. The following encryption algorithms are supported:

  • 1 - DES (default)
  • 2 - AES
  • 3 - 3DES
  • 4 - AES192
  • 5 - AES256

Here's an example of setting the Encryption password and algorithm for the appropriate user (note that this is the same event handler as above, and as such the above code is repeated here):

static void on_GetUserPassword(object sender, SnmptrapmgrGetUserPasswordEventArgs e) { Tuple user = Tuple.Create(e.User, e.EngineId); if (passwordCache.Contains(user)) { switch (e.PasswordType) { case 1: e.Password = ((Tuple)passwordCache[user]).Item1; break; case 2: e.Password = ((Tuple)passwordCache[user]).Item2; e.Algorithm = 1; //using default encryption algorithm break; } } else { e.Password = ""; } }

Trap Event Fires

The Trap event now fires, where the trap's OID and other properties can be accessed. A list of the properties available in the Trap event can be found in the documentation.

We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.