Receive SNMP version 1 and 2c Trap notifications

SNMP Traps are used by SNMP agents to notify managers of events.

Example included in this section applies for SnmpSharpNet Library version 0.4.3 and later.

using System;
using System.Net;
using System.Net.Sockets;
using SnmpSharpNet;
namespace traprecv {
	class Program {
		static void Main(string[] args) {
			// Construct a socket and bind it to the trap manager port 162 
			Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
			IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 162);
			EndPoint ep = (EndPoint)ipep;
			socket.Bind(ep);
			// Disable timeout processing. Just block until packet is received 
			socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
			bool run = true;
			int inlen = -1;
			while (run) {
				byte[] indata = new byte[16 * 1024];
				// 16KB receive buffer int inlen = 0;
				IPEndPoint peer = new IPEndPoint(IPAddress.Any, 0);
				EndPoint inep = (EndPoint)peer;
				try {
					inlen = socket.ReceiveFrom(indata, ref inep);
				}
			 	catch( Exception ex ) {
					Console.WriteLine("Exception {0}", ex.Message);
					inlen = -1;
				}
			 	if (inlen > 0) {
					// Check protocol version int 
					int ver = SnmpPacket.GetProtocolVersion(indata, inlen);
					if (ver == (int)SnmpVersion.Ver1) {
						// Parse SNMP Version 1 TRAP packet 
						SnmpV1TrapPacket pkt = new SnmpV1TrapPacket();
						pkt.decode(indata, inlen);
						Console.WriteLine("** SNMP Version 1 TRAP received from {0}:", inep.ToString());
						Console.WriteLine("*** Trap generic: {0}", pkt.Pdu.Generic);
						Console.WriteLine("*** Trap specific: {0}", pkt.Pdu.Specific);
						Console.WriteLine("*** Agent address: {0}", pkt.Pdu.AgentAddress.ToString());
						Console.WriteLine("*** Timestamp: {0}", pkt.Pdu.TimeStamp.ToString());
						Console.WriteLine("*** VarBind count: {0}", pkt.Pdu.VbList.Count);
						Console.WriteLine("*** VarBind content:");
						foreach (Vb v in pkt.Pdu.VbList) {
							Console.WriteLine("**** {0} {1}: {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString());
						}
						Console.WriteLine("** End of SNMP Version 1 TRAP data.");
					} else {
						// Parse SNMP Version 2 TRAP packet 
						SnmpV2Packet pkt = new SnmpV2Packet();
						pkt.decode(indata, inlen);
						Console.WriteLine("** SNMP Version 2 TRAP received from {0}:", inep.ToString());
						if ((SnmpSharpNet.PduType)pkt.Pdu.Type != PduType.V2Trap) {
							Console.WriteLine("*** NOT an SNMPv2 trap ****");
						} else {
							Console.WriteLine("*** Community: {0}", pkt.Community.ToString());
							Console.WriteLine("*** VarBind count: {0}", pkt.Pdu.VbList.Count);
							Console.WriteLine("*** VarBind content:");
							foreach (Vb v in pkt.Pdu.VbList) {
								Console.WriteLine("**** {0} {1}: {2}", 
								   v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString());
							}
							Console.WriteLine("** End of SNMP Version 2 TRAP data.");
						}
					}
				} else {
					if (inlen == 0)
						Console.WriteLine("Zero length packet received.");
				}
			}
		}
	}
}

Same example using Visual Basic:

Imports SnmpSharpNet
Imports System.Threading
Imports System.Net.Sockets
Imports System.Net
Imports System.IO
 
Module Module1
 
    Sub Main()
        Dim socket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
        Dim ipep As IPEndPoint = New IPEndPoint(System.Net.IPAddress.Any, 162)
        socket.Bind(ipep)
        Dim run As Boolean = True
 
        While True
            Dim inbuf() As Byte = New [Byte](16 * 1024) {}
            Dim peer As IPEndPoint = New IPEndPoint(System.Net.IPAddress.Any, 0)
            Dim inep As EndPoint = peer
            Dim inlen As Integer
            Try
                inlen = socket.ReceiveFrom(inbuf, 0, inbuf.Length, SocketFlags.None, inep)
            Catch ex As Exception
                Console.WriteLine("Exception: " & ex.Message)
                inlen = -1
            End Try
            If inlen > 0 Then
                Dim ver As Integer = SnmpPacket.GetProtocolVersion(inbuf, inlen)
                If ver = SnmpVersion.Ver1 Then
                    Dim pkt As SnmpV1TrapPacket = New SnmpV1TrapPacket()
                    pkt.decode(inbuf, inlen)
                    Console.WriteLine("** SNMP Version 1 TRAP received from {0}:", inep.ToString())
                    Console.WriteLine("*** Trap generic: {0}", pkt.Pdu.Generic)
                    Console.WriteLine("*** Trap specific: {0}", pkt.Pdu.Specific)
                    Console.WriteLine("*** Agent address: {0}", pkt.Pdu.AgentAddress.ToString())
                    Console.WriteLine("*** Timestamp: {0}", pkt.Pdu.TimeStamp.ToString())
                    Console.WriteLine("*** VarBind count: {0}", pkt.Pdu.VbList.Count)
                    Console.WriteLine("*** VarBind content:")
                    Dim v As Vb
                    For Each v In pkt.Pdu.VbList
                        Console.WriteLine("**** {0} {1}: {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString())
                    Next
                    Console.WriteLine("** End of SNMP Version 1 TRAP data.")
                ElseIf ver = SnmpVersion.Ver2 Then
                    Dim pkt As SnmpV2Packet = New SnmpV2Packet()
                    pkt.decode(inbuf, inlen)
                    Console.WriteLine("** SNMP Version 2 TRAP received from {0}:", inep.ToString())
                    If (pkt.Pdu.Type <> PduType.V2Trap) Then
                        Console.WriteLine("*** NOT an SNMPv2 trap ****")
                    Else
                        Console.WriteLine("*** Community: {0}", pkt.Community.ToString())
                        Console.WriteLine("*** VarBind count: {0}", pkt.Pdu.VbList.Count)
                        Console.WriteLine("*** VarBind content:")
                        Dim v As Vb
                        For Each v In pkt.Pdu.VbList
                            Console.WriteLine("**** {0} {1}: {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString())
                        Next
                        Console.WriteLine("** End of SNMP Version 2 TRAP data.")
                    End If
                Else
                    Console.WriteLine("Invalid protocol version number {0}", ver.ToString())
                End If
            Else
                If inlen = 0 Then
                    Console.WriteLine("Zero length packet received.")
                End If
            End If
        End While
 
    End Sub
 
End Module

Testing above code with Net-SNMP snmptrap utility, following output is generated by traprecv utility above:

C:\>traprecv
** SNMP Version 2 TRAP received from 127.0.0.1:64416:
*** Community: public
*** VarBind count: 2
*** VarBind content:
**** 1.3.6.1.2.1.1.5.0 OctetString: MyHost
**** 1.3.6.1.2.1.1.1.0 OctetString: Host do you like my trap
** End of SNMP Version 2 TRAP data.
** SNMP Version 1 TRAP received from 127.0.0.1:64417:
*** Trap generic: 3
*** Trap specific: 0
*** Agent address: 127.0.0.1
*** Timestamp: 432d 21h 8m 0s 550ms
*** VarBind count: 1
*** VarBind content:
**** 1.3.6.1.2.1.1.5.0 OctetString: MyHost
** End of SNMP Version 1 TRAP data.

Commands used to generate traps:

C:\>snmptrap -v 2c -c public localhost .1.3.6.1.2.1.1 localhost \
       sysName.0 s "MyHost" sysDescr.0 s "Host do you like my trap"

C:\>snmptrap -v 1 -c public localhost .1.3.6.1.2.1.1 localhost 3 0 "" sysName.0 s "MyHost"