Click here to Skip to main content
15,902,636 members
Articles / Programming Languages / C#
Article

SNMP library

Rate me:
Please Sign up or sign in to vote.
4.56/5 (62 votes)
20 Apr 2006CPOL5 min read 1.4M   57.7K   144   254
Make SNMP request to get or set value on your computer, CISCO server, server in general, appliance,...

Introduction

Dear friends, ladies and gentleman welcome to the fabulous world of SNMP... With SNMP you can check many status of a server, switch, computer or whatever, you can modify values or parameters of that status. So a lot of thing very interesting...

Get value or set value by an SNMP request. How easy it should be, how easy I though it would be. With linux you can use the command snmpget or snmpset and you make the query and get your answer in 5 seconds.

I wanted the same with windows or more precisely I wanted to do it from a C# code. The idea was to create a very simple interface (dll) to use it in many applications. I didn't find any library easy to use, I didn't find exactly what I want.

So here it is... I create to project : one for the library-dll and another to test this dll and to show you how it's work.

First look !

C#
Console.WriteLine("test simple get");
Console.WriteLine("--------");


//Here is the point
SNMPObject s = new SNMPObject("1.3.6.1.2.1.1.5.0");
//With this OID you can get the name 
//of the computer/server you request

string myValue = s.getSimpleValue(new SNMPAgent("127.0.0.1"));
//Look on my computer

Console.WriteLine("My value is : " + myValue);

The result is :
Test simple get
--------------
My value is MyComputer-One

In two lines you have what you want...

Rewind...

What do we need... 2 things + 1 optional thing

The SNMPAgent : It's the server/computer requested. This server is defined by 2 variables : the IP address and the community string which is "public" by default. The community string is like a password.

The SNMPObject : It's the request itself. This object is defined by an OID. An OID is a series of number separated by a dot which describe the "place" where lives a kind of value (ex : name of computer = 1.3.6.1.2.1.1.5.0).

The Mib(Optional) : This object make the link between the OID and what it is. If you already know the OID you want, you don't need the Mib. But if you want to know for example the load of the CPU and do not know the OID, you need the Mib to know it. It's similar as a DNS with IP address.

Test and explanation:

Tester

C#
//LOAD all the MIB found into the directory c:\windows\System32\****************
    Mib myMib = new Mib();
  Console.WriteLine("**************Loading MIB's files**************");
  myMib.loadDirectoryMib(Environment.GetFolderPath(
                Environment.SpecialFolder.System));
//****************************************************************************


 //**************DISPLAY THE loading MIB************************
  //myMib.walk();
  //*************************************************************


 //*************INIT SNMP AGENT*********************
  SNMPAgent myAgent = new SNMPAgent("127.0.0.1","public","public");

  //if you do that please active the snmp capabilities
  //into your compture : "Add/remove windows component"
  //Becarefull => a firewall that stop traffic from localhost to localhost
  //will prevent this test to work. 
  //- "Management and monitoring tools"
  //************INIT SNMP OBJECT*********************
  SNMPObject myRequest = new SNMPObject("1.3.6.1.2.1.1.5.0",myMib);
  Console.WriteLine();
  Console.WriteLine("***************Make the request***************");
  Console.WriteLine("I am looking for the value : " + 
                            myRequest.getFullName());
  Console.WriteLine("My value is : " + myRequest.getSimpleValue(myAgent));
  Console.WriteLine("The type of my value is : " + myRequest.getType());
  Console.WriteLine("The description of my value is : " + 
                             myRequest.getDescription());

 //**********SOME OTHER TEST**********************
  testMultiGet();  
  testWalk();
  testSet();

  Console.ReadLine();

MIB loading

The first part of the code loads different mib files, usually on your computer in c:\windows\System32. As you should see all the files are read without any problem.
If you want you can walk into that mib to see all the value-OID-description found in the mib's files (by making myMib.walk()).
My experience shows me that sometimes a mib file cannot be loaded because the parser is not enough good to understand it. But most of the times there will be no problem.

When you create the object "Mib", it loads the files " SNMPv2-SMI.mib" which is hardcoded and is the base of all mib.
Remember you don't need to create an object Mib to make SNMP request, it's just a link between the OID, his name and his description.

Get value

This is the simplest thing you can do. First you need to defined a SNMP agent, then an SNMPObject and finally you can get the value and the type of this value.

If you give in argument, when you create the SNMPObject, a Mib object, you can also get the description and the full name of the OID.
This is the point I never found in any free source code in c#: Mix an MIB parser and an SNMP requester...

You can also get multiple value in one shot. See inside the procedure testMultiGet().

Walk

If you can to launch an SNMP request on all OID starting by "1.3.6.1.2.1" just launch the command : myAgent.walk(new SNMPObject("1.3.6.1.2.1"))

Set

The set command is the last thing you can do. Be sure that you have the right to make the command on the given OID.
In this example the set command won't work because you can not change the name of your computer by an SNMP request.

Result

Here is what you should get after

**************Loading MIB's files**************
  Load C:\WINDOWS\System32\accserv.mib
  Load C:\WINDOWS\System32\authserv.mib
  Load C:\WINDOWS\System32\dhcp.mib
  Load C:\WINDOWS\System32\ftp.mib
  Load C:\WINDOWS\System32\hostmib.mib
  Load C:\WINDOWS\System32\http.mib
  Load C:\WINDOWS\System32\inetsrv.mib
  Load C:\WINDOWS\System32\ipforwd.mib
  Load C:\WINDOWS\System32\lmmib2.mib
  Load C:\WINDOWS\System32\mcastmib.mib
  Load C:\WINDOWS\System32\mib_ii.mib
  Load C:\WINDOWS\System32\mipx.mib
  Load C:\WINDOWS\System32\mripsap.mib
  Load C:\WINDOWS\System32\msft.mib
  Load C:\WINDOWS\System32\msipbtp.mib
  Load C:\WINDOWS\System32\msiprip2.mib
  Load C:\WINDOWS\System32\nipx.mib
  Load C:\WINDOWS\System32\smi.mib
  Load C:\WINDOWS\System32\wfospf.mib
  Load C:\WINDOWS\System32\wins.mib

***************Make the request***************
  I am looking for the value : mgmt.mib-2.system.sysName.0
  My value is : MYCOMPUTER-ONE
  The type of my value is : OctetString
  The description of my value is : "An administratively-assigned 
  name for this managed node. By convention, this is the node's
  fully-qualified domain name."


  test walk
  ---------

  Rentre dans le Walk
  []: 1.3.6.1.2.1.2.2.1.1.1,1,Int
  []: 1.3.6.1.2.1.2.2.1.1.2,2,Int
  []: 1.3.6.1.2.1.2.2.1.2.1,MS TCP Loopback interface ,OctetString
  []: 1.3.6.1.2.1.2.2.1.2.2,3Com EtherLink XL 10/100 PCI 
          TX NIC (3C905B-TX) - Packet Scheduler Miniport, OctetString
  []: 1.3.6.1.2.1.2.2.1.3.1,24,Int
  []: 1.3.6.1.2.1.2.2.1.3.2,6,Int
  []: 1.3.6.1.2.1.2.2.1.4.1,1520,Int
  []: 1.3.6.1.2.1.2.2.1.4.2,1500,Int
  []: 1.3.6.1.2.1.2.2.1.5.1,10000000,Gauge32
  []: 1.3.6.1.2.1.2.2.1.5.2,100000000,Gauge32
  []: 1.3.6.1.2.1.2.2.1.6.1,,OctetString
  []: 1.3.6.1.2.1.2.2.1.6.2, P♦r☺?,OctetString
  []: 1.3.6.1.2.1.2.2.1.7.1,1,Int
  []: 1.3.6.1.2.1.2.2.1.7.2,1,Int
  []: 1.3.6.1.2.1.2.2.1.8.1,1,Int
  []: 1.3.6.1.2.1.2.2.1.8.2,1,Int
  []: 1.3.6.1.2.1.2.2.1.9.1,0:00:00.00,TimeTicks
  []: 1.3.6.1.2.1.2.2.1.9.2,0:00:00.00,TimeTicks
  []: 1.3.6.1.2.1.2.2.1.10.1,298230716,Counter32
  []: 1.3.6.1.2.1.2.2.1.10.2,363462946,Counter32
  []: 1.3.6.1.2.1.2.2.1.11.1,3525581,Counter32
  []: 1.3.6.1.2.1.2.2.1.11.2,16924899,Counter32
  []: 1.3.6.1.2.1.2.2.1.12.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.12.2,1091948,Counter32
  []: 1.3.6.1.2.1.2.2.1.13.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.13.2,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.14.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.14.2,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.15.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.15.2,112810,Counter32
  []: 1.3.6.1.2.1.2.2.1.16.1,298230716,Counter32
  []: 1.3.6.1.2.1.2.2.1.16.2,3148083931,Counter32
  []: 1.3.6.1.2.1.2.2.1.17.1,3516517,Counter32
  []: 1.3.6.1.2.1.2.2.1.17.2,14109746,Counter32
  []: 1.3.6.1.2.1.2.2.1.18.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.18.2,18964,Counter32
  []: 1.3.6.1.2.1.2.2.1.19.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.19.2,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.20.1,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.20.2,0,Counter32
  []: 1.3.6.1.2.1.2.2.1.21.1,0,Gauge32
  []: 1.3.6.1.2.1.2.2.1.21.2,4294967258,Gauge32
  []: 1.3.6.1.2.1.2.2.1.22.1,0.0,Oid
  []: 1.3.6.1.2.1.2.2.1.22.2,0.0,Oid

  test multi get
  --------------
  oid : 1.3.6.1.2.1.1.5.0
  value : MYCOMPUTER-ONE
  type : OctetString
  oid : 1.3.6.1.2.1.2.2.1.16.1
  value : 298230716
  type : Counter32

  test Set
  --------
  Read the value before the modification
  oid : 1.3.6.1.2.1.1.5.0
  value : MYCOMPUTER-ONE
  type : OctetString

  Set the value
  Error: SNMP: Variable does not exist; status: NoSuchName; index: 0
  *** SNMP protocol error while processing <op>:
  SNMP error status: NoSuchName
  SNMP error index: 0
  Error: SNMP: Variable does not exist; status: NoSuchName; index: 0

  Read the value after the modification
  oid : 1.3.6.1.2.1.1.5.0
  value : MYCOMPUTER-ONE
  type : OctetString

Points of Interest

Firstly I needed the possibilities to make some SNMP request. After using it, I saw the billion of possibilities SNMP can give me. So now I use SNMP every days in a pleiad of projects.

I hope you'll get fun with SNMP as I do.

History

I based this dll from 4 other dll dispatched in 2 parts :

SnmpComp and tableReader with the namespace : Org.Snmp.Snmp_pp. This dll allow me to make any snmp request I want it. It's quite difficult to understand at first, it's difficult to compile but when you are in... well, it should be ok. Here is the web site where you can find it : http://www.republika.pl/maom_onet/snmp/snmp_ppnet/. Please note that I modified the original dll to adapt it to my need, to the current project.

mib and tools with the namespace : RFC1157 . This dll allow me to read a MIB files, to parse it and finaly to make the link between an OID, its type, its description and its fullname. It was developped by Malcolm Crowe and you can find the code : http://cis.paisley.ac.uk/crow-ci0/#Research. Take care that some of mib files cannot be read by his parser...

This project was born with these two priceless sources...

Feel free to send feed back, I'll correct all the error you may see...

- 8 February 2006 : release version 1.0 of SNMPDLL
- 20 March 2006 : add the source code of snmp_ppnet (for the last version see http://www.republika.pl/maom_onet/snmp/snmp_ppnet/). This code source is only for people who want to see the code of SNMPComp.dll used by SNMPDLL.dll

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Belgium Belgium
Discover www.plugandtable.com

You'll be surprise about this incredible tool !

Comments and Discussions

 
GeneralRe: Set command in GUI project Pin
zitun13-Nov-08 5:37
zitun13-Nov-08 5:37 
GeneralRe: Set command in GUI project Pin
Lex Li29-Nov-08 23:20
professionalLex Li29-Nov-08 23:20 
QuestionI need your help ---feedback text Pin
WuJie913113-Oct-08 3:28
WuJie913113-Oct-08 3:28 
AnswerRe: I need your help ---feedback text Pin
zitun13-Oct-08 3:52
zitun13-Oct-08 3:52 
GeneralRe: I need your help ---feedback text Pin
WuJie913113-Oct-08 22:30
WuJie913113-Oct-08 22:30 
GeneralRe: I need your help ---feedback text Pin
zitun14-Oct-08 22:32
zitun14-Oct-08 22:32 
GeneralRe: I need your help ---feedback text Pin
WuJie913115-Oct-08 22:42
WuJie913115-Oct-08 22:42 
General64 bit Windows Server 2003 Issues - NullReferenceException, Timeouts, Erratic Behaivors Pin
John Gilmore3-Oct-08 4:53
John Gilmore3-Oct-08 4:53 
Hello all,

First, let me praise Zitum for creating such an important library for us and to get many of us started. Even though I am having this problem does not mean others will. The code works flawlessly on a 32 bit system but fails on a 64 bit server. Granted, I may have done something stupid and maybe someone will point that out to me but the code fails to work on a 64 bit system. We have had other issues with other DLL's that simply failed on a 64 bit server and have had to come up with workarounds. Also, I understand that this problem may not even be 64 bit but I can only conclude that it is based on my tests and the issues other people have had with migrating to 64 bit with other DLL's and products.

There is alot of background information I am providing here that may help others before using this DLL Library or that may be able to offer a workaround for me and others. I am also going to research this more and if I am right that this is a 64 bit issue, would like to help contribute to make the necessary changes to the core once I have more SNMP Programing knowlege and am able to make a working solution.

I'm first going to talk about our environment. Next some background & implementation details. Last section is what I coded to cause the error and what kind of errors (Technical Programming & Error Details).

I. Environment:
----------------------------------------------
I just wanted to let everyone know that I had used this component quite successfully in one of my projects in my development environment but not in produciton.

My development environment consists of Windows XP Pro (32 bit OS) where as the Production Server is Windows Server 2003 R2 Standard x64 Edition.

To ensure there were no other issues in my application causing the problem, I created a new project, referenced the minimun number of assemblies and used only the required DLL's from this SNMP Library. This worked in my development environment in both IIS and in the .NET development server

II. Background & Implementation Details:
---------------------------------------------
The issue was _not_ using the MIB Browser; I already knew the printers OID necessary and all I needed to do was communicate with one device: a printer. I only needed to know its current status.

I did not load the MIB files as I saw a post concering that and it was only necessary to load the MIBs if you need to do a whole lot more in the application than what I am doing. Of course, this limits its expadability but that is something we are aware of and keeping a note that as hardware changes we need to stay with the same brand of equiptment and if something does change concering the OID's we will simply use Dell Open Manage software to obtain the new OID of the printer for the device status. If we plan to use a different printer we will use other software to obtain the data we need.

No recompiles would be necessary as I created a custom Web.Config entree for the printer share name, all the necessary OID's for that printer, the printer priority (incase we have multiple printers and want to use another one for fail over) and of course the IP Address among with other important details.

III. Technical Programming And Error Details
--------------------------------------------------------------
Since I wasn't using all the features of this library this limits the potential of other bugs actually causing this. I am going to paste my test code below that works perfect in my Windows XP Pro - 32 bit System but fails on Windows Server 2003 Standard x64:

protected void Button1_Click(object sender, EventArgs e)
{
    SNMPAgent myAgent = GetSnmpAgent("10.1.21.217");
    SNMPObject snmpObject = GetSNMPObject("1.3.6.1.2.1.25.3.2.1.5.1");
    this.lblInfo.Text = snmpObject.getSimpleValue(myAgent); // Returns the value we want
}

 private SNMPAgent GetSnmpAgent(string ipAddress)
 {
    SNMPAgent myAgent = new SNMPAgent(ipAddress);
    return myAgent;
}

private SNMPObject GetSNMPObject(string oid)
{
    try
    {
        //SNMPObject snmpObject = new SNMPObject(oid, myMib); // When I was loading the mib. I decided since I knew my oid and wasn't browsing I didn't need it.  Although I did try it and it would raise an exception too. 

        SNMPObject snmpObject = new SNMPObject(oid); // Exception raised here
        return snmpObject;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}


I have included these references:
mib (When I was loading the MIBs before hand.,
SnmpComp,
SNMPDll

Additional Notes: When I did use the Mib I ensured the mibs were in the place I was loading them from, verified no permission issues and even moved them into a directory within the web application and pointed the load directory to be just that. Its important to note the MIBS were loading, as well as the same version as I copied all the MIBs from my environment to the 64 bit environment.

The exceptions would be raised only in production (64 bit) and not on mine. Below is what exactly happened:

1. When in production, timeouts would happen with this code from time to time. When a timeout would occur this lead me to initally beleive there was an issue with SNMP on the server. I ensure SNMP was installed, no firewall was blocking traffic and verified that SNMP actually worked on the Windows Server 2003 by using the WMI Tester using SNMP and setting up traps, etc.

2. When a timeout did not occur I would recevie our favoriate exception: Object Reference not set to an instance of an object or a NullReferenceException. It would happen on the line of code:

SNMPObject snmpObject = new SNMPObject(oid); 


Interestingly, at one point while the timeout was happening (which I conclue was due to the above line of code due to the fact I put this into production (The app was being published and released into production) and I was doing my production test to make sure it worked as it did in my environment. (Not production debugging, but just a test to make sure it works as intended)

Next thing I know is the entire IIS worker process shut down. I was not able to reproduce this that night ( I wasn't about to try and reproduce it during the day!)

The event viewer logs contained 5 of these:
Faulting application w3wp.exe, version 6.0.3790.3959, stamp 45d6968e, faulting module kernel32.dll, version 5.2.3790.4062, stamp 4626467c, debug? 0, fault address 0x00022366.  Reported by the .NET Runtime 2.0 Error Reporting


And it contained 5 of theses:
A process serving application pool 'DefaultAppPool' suffered a fatal communication error with the World Wide Web Publishing Service. The process id was '1684'. The data field contains the error number. 


Those 5 were within seconds of each of the first 5.

Then after those 5 it has:
Application pool 'DefaultAppPool' is being automatically disabled due to a series of failures in the process(es) serving that application pool.


We have set that after 5 failures like this for it to shutdown and all. This is the default and maybe we as a company need to look at that. I just need to know best practices first concerning that. We restarted IIS to get us back and running sooner.

All of this while the SNMPObject snmpObject = new SNMPObject(oid); was executing
Since then, I created a new app pool just for this application. I can only conclude that it was the SNMPObject causing the problem, although I have no definitive evidence of such. I don't know what the process ID's were at the time so there is no definitve way. Also, I don't know how to interpre the DATA section contained within the Event itself and I couldn't find any resources on that. Perhaps someone can provide info?

I could not recreate those failures of IIS Worker Process restarting but I was doing this when no one else was using the production system. It is possible it could have been a combination of things.

Overall the product is great but I would like to know if others had the same problem on a 64 bit server. I saw a post in here I beleive and they had a 64 bit server. Also, I would like to help improve upon it once I am more familar, if this is the case.

Good luck to all!
John
GeneralRe: 64 bit Windows Server 2003 Issues - NullReferenceException, Timeouts, Erratic Behaivors Pin
zitun13-Oct-08 3:51
zitun13-Oct-08 3:51 
GeneralRe: 64 bit Windows Server 2003 Issues - NullReferenceException, Timeouts, Erratic Behaivors Pin
Lex Li19-Oct-08 2:13
professionalLex Li19-Oct-08 2:13 
GeneralChange port number Pin
gusnaige1-Oct-08 4:50
gusnaige1-Oct-08 4:50 
GeneralRe: Change port number Pin
Lex Li19-Oct-08 2:17
professionalLex Li19-Oct-08 2:17 
GeneralTrap Receiver Pin
sund7wells6-Jul-08 23:55
sund7wells6-Jul-08 23:55 
GeneralRe: Trap Receiver Pin
Lex Li8-Jul-08 16:28
professionalLex Li8-Jul-08 16:28 
GeneralProblems with Set Pin
CyberSlag5k16-Jun-08 9:06
CyberSlag5k16-Jun-08 9:06 
GeneralRe: Problems with Set Pin
Lex Li21-Jun-08 20:09
professionalLex Li21-Jun-08 20:09 
GeneralRe: Problems with Set Pin
CyberSlag5k23-Jun-08 6:38
CyberSlag5k23-Jun-08 6:38 
GeneralRe: Problems with Set Pin
CyberSlag5k24-Jun-08 3:37
CyberSlag5k24-Jun-08 3:37 
GeneralRe: Problems with Set Pin
Lex Li25-Jun-08 2:59
professionalLex Li25-Jun-08 2:59 
GeneralRe: Problems with Set Pin
idurli26-Nov-08 13:59
idurli26-Nov-08 13:59 
Question"Object reference not set to an instance of an object" Pin
psaverman4-Jun-08 22:54
psaverman4-Jun-08 22:54 
QuestionWhen will the async method to get the value of OID come out ? Pin
tymfr5-May-08 15:47
tymfr5-May-08 15:47 
GeneralList of network devices Pin
nsadhasivam2-May-08 19:59
nsadhasivam2-May-08 19:59 
GeneralAnother open source SNMP implementation for .NET initiated Pin
Lex Li26-Apr-08 21:41
professionalLex Li26-Apr-08 21:41 
GeneralRe: Another open source SNMP implementation for .NET initiated Pin
Lex Li16-May-08 18:00
professionalLex Li16-May-08 18:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.