📄 traphandler.cs
字号:
using System;
using System.Net;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Messaging;
using System.Runtime.InteropServices;
using System.Xml;
using WinSnmp;
namespace SnmpTrapHandler
{
/// <summary>
/// SnmpTrapHandler console application
/// </summary>
class TrapHandler
{
private IntPtr hSnmp = (IntPtr)0;
private IntPtr OTSBuffer;
private SnmpAPI.SnmpCallback SnmpCB;
public void Start()
{
int major, minor, level, translate, retran;
//
// Allocate global data buffers
//
OTSBuffer = Marshal.AllocHGlobal(1408);
//
// Create the callback delegate
//
SnmpCB = new SnmpAPI.SnmpCallback(OnSnmpMessage);
//
// Startup the snmp api
//
SNMPAPI_STATUS rc = SnmpAPI.SnmpStartup(out major, out minor, out level, out translate, out retran);
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
throw new Exception("SNMP Initialization Error");
//
// Establish a WinSNMP session
//
IntPtr hSnmp = SnmpAPI.SnmpCreateSession(IntPtr.Zero, 0, SnmpCB, IntPtr.Zero);
//
// Register for all traps
//
rc = SnmpAPI.SnmpRegister(hSnmp, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 1);
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
throw new Exception("SNMP Initialization Error");
//
// Turn on retransmission policy handling
//
SnmpAPI.SnmpSetRetransmitMode(SNMPAPI_RETRANSMIT.SNMPAPI_ON);
//
// Set the translation mode
//
SnmpAPI.SnmpSetTranslateMode(SNMPAPI_TRANSLATE.SNMPAPI_UNTRANSLATED_V2);
return;
}
public void Stop()
{
//
// Unregister all traps
//
SNMPAPI_STATUS rc = SnmpAPI.SnmpRegister(hSnmp, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0);
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
throw new Exception("SNMP Initialization Error");
//
// Close our session
//
SnmpAPI.SnmpClose(hSnmp);
//
// Close down the snmp api
//
SnmpAPI.SnmpCleanup();
//
// Free the global buffer
//
Marshal.FreeHGlobal(OTSBuffer);
return;
}
protected SNMPAPI_STATUS OnSnmpMessage(IntPtr session, IntPtr hwnd, int msg, uint wparam, uint lparam, IntPtr data)
{
ArrayList vars;
int type, id, status, index;
IntPtr vbl, src, dest, ctxt, pdu;
string source = "", destination = "", context = "";
try {
//
// Get the trap
//
SNMPAPI_STATUS rc = SnmpAPI.SnmpRecvMsg(session, out src, out dest, out ctxt, out pdu);
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
throw new Exception("SnmpRecvMsg Error");
//
// Convert the source, destination, and context to displayable strings
//
rc = SnmpAPI.SnmpEntityToStr(src, 1408, OTSBuffer);
if (rc != SNMPAPI_STATUS.SNMPAPI_FAILURE)
source = Marshal.PtrToStringAnsi(OTSBuffer);
rc = SnmpAPI.SnmpEntityToStr(dest, 1408, OTSBuffer);
if (rc != SNMPAPI_STATUS.SNMPAPI_FAILURE)
destination = Marshal.PtrToStringAnsi(OTSBuffer);
rc = SnmpAPI.SnmpEntityToStr(ctxt, 1408, OTSBuffer);
if (rc != SNMPAPI_STATUS.SNMPAPI_FAILURE)
context = Marshal.PtrToStringAnsi(OTSBuffer);
//
// Make sure we clean these up
//
SnmpAPI.SnmpFreeEntity(src);
SnmpAPI.SnmpFreeEntity(dest);
SnmpAPI.SnmpFreeContext(ctxt);
//
// Get the response id, error status, and variable list
//
rc = SnmpAPI.SnmpGetPduData(pdu, out type, out id, out status, out index, out vbl);
//
// Free the pdu
//
SnmpAPI.SnmpFreePdu(pdu);
//
// Throw an exception if we have any problems
//
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
throw new Exception("SnmpGetPduData Error");
//
// Process the trap message. We ignore anything else
//
switch (type) {
case (int)SNMPAPI_PDU.SNMP_PDU_TRAP:
Console.WriteLine("\nTrap received...");
Console.WriteLine("Source: " + source);
Console.WriteLine("Destination: " + destination);
Console.WriteLine("Context: " + context);
Console.WriteLine("Id: " + id);
vars = VblToArrayList(vbl);
SnmpAPI.SnmpFreeVbl(vbl);
Console.WriteLine("\nVariables (OIDs) in trap: ");
foreach (string s in vars)
Console.WriteLine(" " + s);
break;
default:
break;
}
} catch (Exception e) {
string s = e.Message;
Console.WriteLine(s);
}
GC.Collect();
return(SNMPAPI_STATUS.SNMPAPI_SUCCESS);
}
protected ArrayList VblToArrayList(IntPtr vbl)
{
int count = 0;
ArrayList al = new ArrayList();
SMIOID name = new SMIOID();
SMIVALUE val = new SMIVALUE();
SNMPAPI_STATUS rc;
//
// Get the variable count and set the capacity of the arraylist. This
// speeds our processing as there's no need to expand the list as
// we add entries.
//
rc = SnmpAPI.SnmpCountVbl(vbl);
if (rc != SNMPAPI_STATUS.SNMPAPI_FAILURE)
count = (int)rc;
al.Capacity = count;
for (int i = 1; i <= count; i++) {
rc = SnmpAPI.SnmpGetVb(vbl, i, ref name, ref val);
if (rc != SNMPAPI_STATUS.SNMPAPI_SUCCESS)
break;
//
// Build the variable name
//
string soid = OidToString(ref name);
string v = VbToString(ref val);
if (soid != null)
al.Add(soid + ": " + v);
}
return(al);
}
protected string OidToString(ref SMIOID oid)
{
string soid = null;
try {
SNMPAPI_STATUS rc = SnmpAPI.SnmpOidToStr(ref oid, 1408, OTSBuffer);
if (rc != SNMPAPI_STATUS.SNMPAPI_FAILURE)
soid = Marshal.PtrToStringAnsi(OTSBuffer);
SnmpAPI.SnmpFreeDescriptor((int)SNMPAPI_SYNTAX.SNMP_SYNTAX_OID, ref oid);
} catch (Exception e) {
Console.WriteLine("OidToString Exception:\n" + e.Message + "\n" + e.StackTrace);
}
return(soid);
}
protected string VbToString(ref SMIVALUE sval)
{
string val = "";
//
// Convert all types to a string value
//
switch (sval.type) {
//
// Standard 32 bit integer conversion
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_INT:
val = sval.val.sNumber.ToString();
break;
//
// Standard 32 bit unsigned integer conversion
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_UINT32:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_CNTR32:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_GAUGE32:
val = sval.val.uNumber.ToString();
break;
//
// Timeticks are in hundredths of a second (.01). We need to multiply
// by ten to send ms (.001) to TimeSpan.
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_TIMETICKS:
val = TimeSpan.FromMilliseconds((long)sval.val.uNumber*10).ToString();
val = val.Substring(0, val.Length-4);
break;
//
// Standard 64 bit integer conversion
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_CNTR64:
val = sval.val.hNumber.ToString();
break;
//
// Byte array conversion. SNMP doesn't differentiate between
// ASCII and binary data, so we perform a check ourselves and
// convert binary data to ASCII (using ToBase64String, which is uuencode).
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_BITS:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_OPAQUE:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_OCTETS:
if (sval.val.str.size > 0) {
int i = 0;
byte[] bits = new byte[sval.val.str.size];
Marshal.Copy(sval.val.str.octets, bits, 0, (int)sval.val.str.size);
for (i = 0; i < bits.Length; i++) {
if (char.IsControl((char)bits[i]) && (i < bits.Length-1 || bits[i] != 0)) {
val = Convert.ToBase64String(bits, 0, bits.Length);
break;
}
}
if (i == bits.Length)
val = Marshal.PtrToStringAnsi(sval.val.str.octets, (int)sval.val.str.size);
SnmpAPI.SnmpFreeDescriptor((int)sval.type, ref sval.val.str);
}
break;
//
// Ip Address conversion
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_NSAPADDR:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_IPADDR:
IPAddress addr = new IPAddress((long)(UInt32)Marshal.ReadIntPtr(sval.val.str.octets));
val = addr.ToString();
SnmpAPI.SnmpFreeDescriptor((int)sval.type, ref sval.val.str);
break;
//
// SNMP OID conversion
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_OID:
val = OidToString(ref sval.val.oid);
break;
//
// Catch the rest
//
case SNMPAPI_SYNTAX.SNMP_SYNTAX_NULL:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_NOSUCHOBJECT:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_NOSUCHINSTANCE:
case SNMPAPI_SYNTAX.SNMP_SYNTAX_ENDOFMIBVIEW:
val = "(null)";
break;
}
return(val);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -