Example #1
0
        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);
        }