No navigation frame on the left?  Click here.

SNMP without SNMP

Before you read further: SNMP is, for the beginner, a rather complex topic. The sample here shows how to deal with one particular aspect of the Microsoft SNMP implementation; it is not a general tutorial. It also does not use the SNMP wire protocol, neither directly nor theough the SNMP Management API, opting instead to talk to the data-gathering SNMP Extension Agents directly. (But talking to those and talking to the Management API is extremely similar.)

If you want to learn about SNMP, you may want to try the SNMP section in one of IBM's redbooks; if you are looking for an easier way to write code using SNMP, you want to look at HP's implementation of SNMP++. (Downside: The license agreement says, "User hereby grants a royalty-free license to any and all derivatives based upon this software code base." Since there is no restriction, HP can do with your code whatever they want.)

 

One of the questions I come across rather often is "How do I get X?" where X is the route table, the ARP table, or NIC and network information. SNMP offers a way to get these things -- provided the target machine allows it, and provided it has SNMP installed in the first place.

Now, there is an easier method, too; NT5 and Win98 both offer the "IP Helper API," documented in the newer Platform SDKs. NT4 supports parts of it; if you need more than what KB article Q193059 (INFO: IP Helper APIs Add Net Config and Stat Info to Win32 Apps) offers, or if you must support older platforms, or if you are just interested in the less-common statistics kept by the system, read on.

If such information is sought for the local machine, there is a way that does not require SNMP to be installed; the fragments that automatically come with your installation of Windows are sufficient.

These "fragments" are DLLs, called SNMP Extension Agents; they are what the SNMP Service calls when a remote request for some information comes in. We can do that, too: this sample loads an SNMP Extension Agent of your choice and queries it for all SNMP variables it exports. inetmib1.dll is suggested by default, containing protocol info, NIC data, ARP and routing tables, and the like. hostmib.dll and lmmib2.dll are also worthy targets.

SNMP sample screenshot -- snmp.gif (16050 bytes)

The interesting things happen in Node::enumSubtree(), near the end of util.cpp: Starting with the AsnObjectIdentifier that got assigned to the subtree root in SnmpDlg::openEA() (which asked the DLL for all the subtree roots it knows about), the code sequentially walks through the MIB subtree, stopping only at an error, or when going past the end of the tree.

The sample does two things that might throw you for a loop:

It calls SnmpMgrOidToStr(), which may require the presence of an installed SNMP service, to display pretty names for SNMP variables, but this is expendable chrome.
It employs a kluge, deleting trailing zeros from the OIDs (Object Identifiers) it gets back -- if it didn't, most of the boldfaced items above would actually have a subitem each, with a ".0" appended, containing the value proper. This can be controlled with NO_TRAILING_ZERO_IN_OID, set in util.h, and affecting Node::enumSubtree().

If you wish to keep OIDs around for later queries, you must disable the NO_TRAILING_ZERO_IN_OID kluge, as the SNMP Extension Agent sees the zero as part of the OID -- without the ".0", the OID becomes invalid.

Also note that SNMP Extension Agents rely heavily on structures of which parts are allocated dynamically, mostly through SnmpUtilMemAlloc() and relatives. I wrapped those structs that one needs often into (again, klugy) classes: AsnAny, representing a data item, into AA; and AsnObjectIdentifier, carrying an OID, into AOI. These classes are not meant to be a sample of good OO design; they are a hack I put together to save myself some typing. Besides, what do you expect from a sample that took less than twelve hours from start to finish?

snmp.zip, 26 KB (includes executable, built with VC++ 6.0SP1/MFC in a DLL)
(and ever since Lou Bergandi kindly pointed my error out, the \res\ subdirectory is also included -- yes, the sample can now be built without having to improvise. My sincere apologies for any inconvenience caused by this mistake of mine.)