public static void Main(string[] args) { #if REQUIRES_CRT_INIT CRT.Auto.Initialize(); #endif if (args.Length < 2) { Console.WriteLine("SNMP++.NET command line utility\n" + "Author: Marek Malowidzki 2003,2004 ([email protected])\n" + "Based on SNMP++ package from Peter E. Mellquist (HP) and Jochen Katz\n" + "SNMP++.NET " + Assembly.GetAssembly(typeof(Snmp)) + " built on " + Snmp.BuildTime + "; SNMP++ v. " + Snmp.Snmp_ppVersion + "\n\n" + "Usage: " + Environment.GetCommandLineArgs()[0] + " <op> <agent> [<options>]\n" + "where:\n" + "op - SNMP operation to perform (get,getnext,getbulk,set,walk,table)\n" + "agent - IP address or DNS name of an agent\n" + "options are the following:\n" + "-v<version> - SNMP version to use (v1(default),v2c,v3)\n" + "-p<port> - port number to use\n" + "-r<retries> - number of retries (default: 2)\n" + "-t<timeout> - timeout in milliseconds (default: 1000)\n" + "-d<bool> - print debug messages\n" + "-o<oid> - subsequent OID\n" + "-T<type> - subsequent SNMP type name:\n" + string.Join(",", SnmpSyntax.SupportedSyntaxNames) + " (o stands for oid and s for string)\n" + "-V<value> - subsequent value\n" + "Debug options:\n" + "-Df<file> - log file name\n" + "-Dl<level> - log level\n" + "SNMPv1/v2c options:\n" + "-c<comm> - read community name (default: public)\n" + "-C<comm> - write community name (default: public)\n" + "SNMPv3 options:\n" + "-b<boot> - boot counter value (default: 100)\n" + "-sn<secName> - security name\n" + "-sl<secLevel>- security level (" + ManagerUtilities.EnumInfo(typeof(SecurityLevel), SecurityLevel.AuthPriv) + ")\n" + "-sm<secModel>- security model (" + ManagerUtilities.EnumInfo(typeof(SecurityModel), SecurityModel.USM) + ")\n" + "-xn<ctxName> - context name\n" + "-xe<ctxEngId>- context engine ID (default: discover)\n" + "-A<authProto>- authentication protocol (" + ManagerUtilities.EnumInfo(typeof(AuthProtocol), AuthProtocol.None) + ")\n" + "-P<privProto>- privacy protocol (" + ManagerUtilities.EnumInfo(typeof(PrivProtocol), PrivProtocol.None) + ")\n" + "-Ua<authPass>- authentication password\n" + "-Up<privPass>- privacy password\n" + "Table operation options:\n" + "-Os<rowOid> - row index to start from\n" + "-Oe<rowOid> - row index to finish at\n" + "-On<count> - max number of rows to retrieve\n" + "-Or<count> - rows per query or 0 for heuristics\n" + "Testing options:\n" + "-Xa<bool> - use asynchronous interface\n" + "-Xm<filePfx> - collect memory usage in <filePfx>.<ext> files, where ext denotes memory type\n" + "-Xn<repeat> - repeat number of times (default: 1)\n" + "-Xp<priority>- set process priority (" + ManagerUtilities.EnumInfo(typeof(ProcessPriorityClass), ProcessPriorityClass.Normal) + ")\n" + "-Xs<bool> - use asychronous interface for synchronous calls\n" + "-Xt<threads> - run multiple threads (default: 1)"); Environment.Exit(1); } string option = "<ip>"; Thread statsCollector = null; MemoryStats stats = null; int retCode = 1; try { UdpAddress udp = new UdpAddress(args[1]); SnmpVersion ver = SnmpVersion.SNMPv1; SnmpTarget.DefaultRetries = 2; SnmpTarget.DefaultTimeout = 1000; uint nRepeats = 1, nThreads = 1; int debugLevel = int.MinValue; string statsFile = null, debugFile = null; TableReader.GetTableOptions tableOptions = new TableReader.GetTableOptions(); bool async = false, asyncSync = false, debug = false; string readCommunity = "public", writeCommunity = "public"; AuthProtocol authProto = AuthProtocol.None; PrivProtocol privProto = PrivProtocol.None; string authPass = "", privPass = "", secName = "", ctxName = "", ctxEngId = ""; SecurityLevel secLevel = SecurityLevel.AuthPriv; SecurityModel secModel = SecurityModel.USM; uint boot = 100; string[] oids = new string[128], types = new string[128], vals = new string[128]; int noids = 0, ntypes = 0, nvals = 0; string val; int index = 2; while (ManagerUtilities.GetOption(args, out option, out val, ref index)) { char sub; switch (option) { case "v": ver = (SnmpVersion)Enum.Parse( typeof(SnmpVersion), "SNMPv" + val, true); break; case "p": udp = new UdpAddress(udp.Ip, int.Parse(val)); break; case "r": SnmpTarget.DefaultRetries = int.Parse(val); break; case "t": SnmpTarget.DefaultTimeout = int.Parse(val); break; case "d": debug = bool.Parse(val); break; case "o": oids[noids++] = val; break; case "T": types[ntypes++] = val; break; case "V": vals[nvals++] = val; break; case "c": readCommunity = val; break; case "C": writeCommunity = val; break; case "b": boot = uint.Parse(val); break; case "s": switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 'n': secName = val; break; case 'l': secLevel = (SecurityLevel)Enum.Parse( typeof(SecurityLevel), val, true); break; case 'm': secModel = (SecurityModel)Enum.Parse( typeof(SecurityModel), val, true); break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; case "x": switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 'n': ctxName = val; break; case 'e': ctxEngId = val; break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; case "A": authProto = (AuthProtocol)Enum.Parse( typeof(AuthProtocol), val, true); break; case "P": privProto = (PrivProtocol)Enum.Parse( typeof(PrivProtocol), val, true); break; case "D": switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 'f': debugFile = val; break; case 'l': debugLevel = int.Parse(val); break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; case "U": switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 'a': authPass = val; break; case 'p': privPass = val; break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; case "O": { switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 's': tableOptions.startRowIndex = new Oid(val); break; case 'e': tableOptions.endRowIndex = new Oid(val); break; case 'n': tableOptions.maxRows = int.Parse(val); break; case 'r': tableOptions.rowsPerQuery = int.Parse(val); break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; } case "X": switch (sub = ManagerUtilities.GetSubOption(ref val)) { case 'a': async = ParseBoolWithDefault(val); break; case 'm': statsFile = val; break; case 'n': nRepeats = uint.Parse(val); break; case 'p': System.Diagnostics.Process.GetCurrentProcess().PriorityClass = (ProcessPriorityClass)Enum.Parse( typeof(ProcessPriorityClass), val, true); break; case 's': asyncSync = ParseBoolWithDefault(val); break; case 't': if ((nThreads = uint.Parse(val)) <= 0) { throw new ArgumentException( val + ": invalid threads number"); } break; default: throw new ArgumentException( sub + ": invalid sub-option"); } break; default: throw new ArgumentException( "-" + option + ": invalid option"); } } if (noids == 0) { option = "<OIDs>"; throw new ArgumentException( "No OIDs specified, use -o option"); } bool asyncMode = async || asyncSync; // Debug options if (debugFile != null) { Snmp.DebugLogFile = debugFile; } if (debugLevel != int.MinValue) { Snmp.DebugLogLevel = debugLevel; } // Operation type processing option = "<Pdu creation>"; PduType pduType; OperType operType; GetOperType(args[0].ToLower(), out pduType, out operType); // Adjusting settings for a table operation if (operType == OperType.Table) { TableReader.UseAsyncInvoke = asyncMode; } // Pdu creation Pdu pdu; using (IMemoryManager mgr = MemoryManager.GetMemoryManager()) { Vb[] vbs = ManagerUtilities.CreateVbs(pduType, oids, noids, types, ntypes, vals, nvals); pdu = new Pdu(pduType, vbs); mgr.Remove(pdu); // remove Pdu from the memory manager } // SnmpTarget creation SnmpTarget target; if (ver == SnmpVersion.SNMPv3) { option = "<SNMPv3 initialization>"; V3MP.Init(new OctetStr("SNMP++.NET"), boot); USM usm = V3MP.Instance.Usm; usm.AddUsmUser(secName, authProto, privProto, authPass, privPass); target = new UTarget(udp, secName, secModel); pdu.SecurityLevel = secLevel; pdu.ContextName = new OctetStr(ctxName); pdu.ContextEngineId = new OctetStr(ctxEngId); } else { option = "<SNMPv1/v2c initialization>"; target = new CTarget(udp, ver, readCommunity, writeCommunity); } udp = null; // Memory usage statistics initialization option = "<Statistics collector initialization>"; if (statsFile != null) { stats = new MemoryStats(statsFile); statsCollector = new Thread(new ThreadStart(stats.Collect)); statsCollector.Priority = ThreadPriority.BelowNormal; statsCollector.Start(); } // Snmp session initialization & further processing option = "<SNMP session initialization>"; using (Snmp snmp = new Snmp(asyncMode)) { Thread.CurrentThread.Name = "0"; Barrier barrier; Delegate fun; if (async) { fun = new Delegate(AsyncProcess); barrier = new Barrier(nThreads + 1); } else { fun = new Delegate(Process); barrier = new Barrier(nThreads); } Manager mgr = new Manager(0, snmp, target, pdu, operType, ref tableOptions, barrier, nRepeats, asyncSync, debug); DateTime start = DateTime.Now; int ncalls = fun(mgr, ref option); double msec = DateTime.Now.Subtract(start).TotalMilliseconds; // clear references on stack pdu = null; target = null; mgr = null; Console.WriteLine("{0} {1} SNMP request(s) in {2} msec. ({3} req./sec.)", ncalls, asyncMode ? "asynchronous" : "synchronous", (int)msec, msec > 0 ? (1000 * (long)ncalls / msec) : 0); } retCode = 0; } catch (SnmpClassException e) { Console.Error.WriteLine("*** SNMP class error while processing {0}:\n" + "SnmpClass status code: {1}\n{2}", option, e.Status, e); } catch (SnmpException e) { Console.Error.WriteLine("*** SNMP protocol error while processing {0}:\n" + "SNMP error status: {1}\nSNMP error index: {2}\n{3}", option, e.ErrorStatus, e.ErrorIndex, e); } catch (Exception e) { Console.Error.WriteLine("*** Error while processing {0}:\n{1}", option, e); } Console.WriteLine("Remaining native SNMP++ objects before GC: " + MemoryManager.Count); if (statsCollector != null) { stats.WaitForNextStat(); } GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); if (statsCollector != null) { stats.WaitForNextStat(); statsCollector.Interrupt(); statsCollector.Join(); } // Despite our honest intentions, there may still be uncollected // SNMP++.NET objects, especially in the Release mode Console.WriteLine("Remaining native SNMP++ objects after GC: " + MemoryManager.Count); Environment.Exit(retCode); }