Solved

SNMP: reading MIB and converting them into OIDs

Posted on 2002-04-16
6
7,504 Views
Last Modified: 2013-11-29
Suppose I have a MIB of some sort and I want
to find out the SNMP-string.
How I go about this?
E.g. I have a file like this:
BEGIN>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
NetWare-Host-Ext-MIB DEFINITIONS ::= BEGIN

       IMPORTS
          enterprises, Counter
             FROM RFC1155-SMI

          OBJECT-TYPE
             FROM RFC-1212
          ifIndex
             FROM RFC1213-MIB

          hrDeviceIndex
             FROM HOST-RESOURCES-MIB;

       TransportDomain ::= INTEGER {
                 noAddress(1),
                 ipx(2),
                 ip(3),
                 appleTalkDDP(4)
            }
       TransportAddress    ::= OCTET STRING



       novell              OBJECT IDENTIFIER ::= { enterprises 23 }
       mibDoc              OBJECT IDENTIFIER ::= { novell 2 }

       nwHostExtensions    OBJECT IDENTIFIER ::= { mibDoc 27 }

       nwhrStorage         OBJECT IDENTIFIER ::= { nwHostExtensions 2 }
       nwhrDevice          OBJECT IDENTIFIER ::= { nwHostExtensions 3 }
       nwhrOdi             OBJECT IDENTIFIER ::= { nwHostExtensions 10 }


       nwhrStorageTypes
                      OBJECT IDENTIFIER ::= { nwhrStorage 1 }

       nwhrStorageVolume
                      OBJECT IDENTIFIER ::= { nwhrStorageTypes 1 }
       nwhrStorageMemoryPermanent
                      OBJECT IDENTIFIER ::= { nwhrStorageTypes 2 }

<<<<<<<<<<<<<<<<<<<<<<<<<END

and I want to translate this into a SNMP string like
1.3.1.3.4.5.1.34.5.5.


How do I read this stuff?

Plz don't refer me to a RFC/HTTP link where the info is.
But just give a example of an existing MIB.

Cheers,
 Miauw


0
Comment
Question by:miauw
  • 4
6 Comments
 
LVL 1

Expert Comment

by:lsmgms
Comment Utility
I assume your OS is WIN, then try to use SnmpMgrStrToOid.  Example quoted from SNMPUtil:

/*++ BUILD Version: 0001    // Increment this if a change has global effects

Copyright (c) 1991-1995  Microsoft Corporation

Module Name:

    snmputil.c

Abstract:

    Sample SNMP Management API usage for Windows NT.

    This file is an example of how to code management applications using
    the SNMP Management API for Windows NT.  It is similar in operation to
    the other commonly available SNMP command line utilities.

    Extensive comments have been included to describe its structure and
    operation.  See also "Microsoft Windows/NT SNMP Programmer's Reference".

Created:

    28-Jun-1991

Revision History:

--*/


static char *vcsid = "@(#) $Logfile:   N:/agent/mgmtapi/vcs/snmputil.c_v  $ $Revision:   1.5  $";


// General notes:
//   Microsoft's SNMP Management API for Windows NT is implemented as a DLL
// that is linked with the developer's code.  These APIs (examples follow in
// this file) allow the developer's code to generate SNMP queries and receive
// SNMP traps.  A simple MIB compiler and related APIs are also available to
// allow conversions between OBJECT IDENTIFIERS and OBJECT DESCRIPTORS.


// Necessary includes.

#include <windows.h>

#include <stdio.h>
#include <string.h>
#include <malloc.h>

#include <snmp.h>
#include <mgmtapi.h>


// Constants used in this example.

#define GET     1
#define GETNEXT 2
#define WALK    3
#define TRAP    4

#define TIMEOUT 6000 /* milliseconds */
#define RETRIES 3


// Main program.

INT _CRTAPI1 main(
    IN int  argumentCount,
    IN char *argumentVector[])
    {
    INT                operation;
    LPSTR              agent;
    LPSTR              community;
    RFC1157VarBindList variableBindings;
    LPSNMP_MGR_SESSION session;

    INT        timeout = TIMEOUT;
    INT        retries = RETRIES;

    BYTE       requestType;
    AsnInteger errorStatus;
    AsnInteger errorIndex;
    char        *chkPtr = NULL;


    // Parse command line arguments to determine requested operation.

    // Verify number of arguments...
    if      (argumentCount < 5 && argumentCount != 2)
        {
        printf("Error:  Incorrect number of arguments specified.\n");
        printf(
"\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
        printf(
  "        snmputil trap\n");

        return 1;
        }

    // Get/verify operation...
    argumentVector++;
    argumentCount--;
    if      (!strcmp(*argumentVector, "get"))
        operation = GET;
    else if (!strcmp(*argumentVector, "getnext"))
        operation = GETNEXT;
    else if (!strcmp(*argumentVector, "walk"))
        operation = WALK;
    else if (!strcmp(*argumentVector, "trap"))
        operation = TRAP;
    else
        {
        printf("Error:  Invalid operation, '%s', specified.\n",
               *argumentVector);

        return 1;
        }

    if (operation != TRAP)
        {
        if (argumentCount < 4)
            {
            printf("Error:  Incorrect number of arguments specified.\n");
            printf(
"\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
            printf(
  "        snmputil trap\n");

            return 1;
            }

        // Get agent address...
        argumentVector++;
        argumentCount--;
        agent = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
        strcpy(agent, *argumentVector);

        // Get agent community...
        argumentVector++;
        argumentCount--;
        community = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
        strcpy(community, *argumentVector);

        // Get oid's...
        variableBindings.list = NULL;
        variableBindings.len = 0;

        while(--argumentCount)
            {
            AsnObjectIdentifier reqObject;

            argumentVector++;

            // Convert the string representation to an internal representation.
            if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
                {
                printf("Error: Invalid oid, %s, specified.\n", *argumentVector);

                return 1;
                }
            else
                {
                // Since sucessfull, add to the variable bindings list.
                variableBindings.len++;
                if ((variableBindings.list = (RFC1157VarBind *)SNMP_realloc(
                    variableBindings.list, sizeof(RFC1157VarBind) *
                    variableBindings.len)) == NULL)
                    {
                    printf("Error: Error allocating oid, %s.\n",
                           *argumentVector);

                    return 1;
                    }

                variableBindings.list[variableBindings.len - 1].name =
                    reqObject; // NOTE!  structure copy
                variableBindings.list[variableBindings.len - 1].value.asnType =
                    ASN_NULL;
                }
            } // end while()

        // Make sure only one variable binding was specified if operation
        // is WALK.
        if (operation == WALK && variableBindings.len != 1)
            {
            printf("Error: Multiple oids specified for WALK.\n");

            return 1;
            }


        // Establish a SNMP session to communicate with the remote agent.  The
        // community, communications timeout, and communications retry count
        // for the session are also required.

        if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL)
            {
            printf("error on SnmpMgrOpen %d\n", GetLastError());

            return 1;
            }

        } // end if(TRAP)


    // Determine and perform the requested operation.

    if      (operation == GET || operation == GETNEXT)
        {
        // Get and GetNext are relatively simple operations to perform.
        // Simply initiate the request and process the result and/or
        // possible error conditions.


        if (operation == GET)
            requestType = ASN_RFC1157_GETREQUEST;
        else
            requestType = ASN_RFC1157_GETNEXTREQUEST;


        // Request that the API carry out the desired operation.

        if (!SnmpMgrRequest(session, requestType, &variableBindings,
                            &errorStatus, &errorIndex))
            {
            // The API is indicating an error.

            printf("error on SnmpMgrRequest %d\n", GetLastError());
            }
        else
            {
            // The API succeeded, errors may be indicated from the remote
            // agent.

            if (errorStatus > 0)
                {
                printf("Error: errorStatus=%d, errorIndex=%d\n",
                       errorStatus, errorIndex);
                }
            else
                {
                // Display the resulting variable bindings.

                UINT i;
                char *string = NULL;

                for(i=0; i < variableBindings.len; i++)
                    {
                    SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
                    printf("Variable = %s\n", string);
                    if (string) SNMP_free(string);

                    printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[i].value);

                    printf("\n");
                    } // end for()
                }
            }


        // Free the variable bindings that have been allocated.

        SnmpUtilVarBindListFree(&variableBindings);


        }
    else if (operation == WALK)
        {
        // Walk is a common term used to indicate that all MIB variables
        // under a given OID are to be traversed and displayed.  This is
        // a more complex operation requiring tests and looping in addition
        // to the steps for get/getnext above.


        AsnObjectIdentifier root;
        AsnObjectIdentifier tempOid;


        SnmpUtilOidCpy(&root, &variableBindings.list[0].name);

        requestType = ASN_RFC1157_GETNEXTREQUEST;


        while(1)
            {
            if (!SnmpMgrRequest(session, requestType, &variableBindings,
                                &errorStatus, &errorIndex))
                {
                // The API is indicating an error.

                printf("error on SnmpMgrRequest %d\n", GetLastError());

                break;
                }
            else
                {
                // The API succeeded, errors may be indicated from the remote
                // agent.


                // Test for end of subtree or end of MIB.

                if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
                    SnmpUtilOidNCmp(&variableBindings.list[0].name,
                                    &root, root.idLength))
                    {
                    printf("End of MIB subtree.\n\n");

                    break;
                    }


                // Test for general error conditions or sucesss.

                if (errorStatus > 0)
                    {
                    printf("Error: errorStatus=%d, errorIndex=%d \n",
                           errorStatus, errorIndex);

                    break;
                    }
                else
                    {
                    // Display resulting variable binding for this iteration.

                    char *string = NULL;

                    SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
                    printf("Variable = %s\n", string);
                    if (string) SNMP_free(string);

                    printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[0].value);

                    printf("\n");
                    }
                } // end if()


            // Prepare for the next iteration.  Make sure returned oid is
            // preserved and the returned value is freed.

            SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);

            SnmpUtilVarBindFree(&variableBindings.list[0]);

            SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
            variableBindings.list[0].value.asnType = ASN_NULL;

            SnmpUtilOidFree(&tempOid);

            } // end while()


        // Free the variable bindings that have been allocated.

        SnmpUtilVarBindListFree(&variableBindings);

        SnmpUtilOidFree(&root);


        }
    else if (operation == TRAP)
        {
        // Trap handling can be done two different ways: event driven or
        // polled.  The following code illustrates the steps to use event
        // driven trap reception in a management application.


        HANDLE hNewTraps = NULL;


        if (!SnmpMgrTrapListen(&hNewTraps))
            {
            printf("error on SnmpMgrTrapListen %d\n", GetLastError());
            }
        else
            {
            printf("snmputil: listening for traps...\n");
            }


        while(1)
            {
            DWORD dwResult;

            if ((dwResult = WaitForSingleObject(hNewTraps, 0xffffffff))
                == 0xffffffff)
                {
                printf("error on WaitForSingleObject %d\n",
                       GetLastError());
                }
            else if (!ResetEvent(hNewTraps))
                {
                printf("error on ResetEvent %d\n", GetLastError());
                }
            else
                {
                AsnObjectIdentifier enterprise;
                AsnNetworkAddress   IPAddress;
                AsnInteger          genericTrap;
                AsnInteger          specificTrap;
                AsnTimeticks        timeStamp;
                RFC1157VarBindList  variableBindings;

                UINT i;
                char *string = NULL;

                while(SnmpMgrGetTrap(&enterprise, &IPAddress, &genericTrap,
                                     &specificTrap, &timeStamp, &variableBindings))
                    {
                    printf("snmputil: trap generic=%d specific=%d\n",
                           genericTrap, specificTrap);
                    if (IPAddress.length == 4) {
                        printf("  from -> %d.%d.%d.%d\n",
                             (int)IPAddress.stream[0], (int)IPAddress.stream[1],
                             (int)IPAddress.stream[2], (int)IPAddress.stream[3]);

                    }
                    if (IPAddress.dynamic) {
                        SNMP_free(IPAddress.stream);
                    }

                    for(i=0; i < variableBindings.len; i++)
                        {
                        SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
                        printf("Variable = %s\n", string);
                        if (string) SNMP_free(string);

                        printf("Value    = ");
                        SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
                        } // end for()
                    printf("\n");


                    SnmpUtilOidFree(&enterprise);

                    SnmpUtilVarBindListFree(&variableBindings);
                    }
                }
            } // end while()


        } // end if(operation)


    if (operation != TRAP)
        {
        // Close SNMP session with the remote agent.

        if (!SnmpMgrClose(session))
            {
            printf("error on SnmpMgrClose %d\n", GetLastError());

            return 1;
            }
        }


    // Let the command interpreter know things went ok.

    return 0;

    } // end main()

Hope this will help.
0
 
LVL 10

Accepted Solution

by:
kiranghag earned 300 total points
Comment Utility
{ enterprises 23 }
      mibDoc              OBJECT IDENTIFIER ::= { novell 2 }

      nwHostExtensions    OBJECT IDENTIFIER ::= { mibDoc 27 }

      nwhrStorage         OBJECT IDENTIFIER ::= { nwHostExtensions 2 }
      nwhrDevice          OBJECT IDENTIFIER ::= { nwHostExtensions 3 }
      nwhrOdi             OBJECT IDENTIFIER ::= { nwHostExtensions 10 }

you may need to parse the file to filter all the object identifiers. eg. in above para - oid are enterprises, novell, mibdoc....
then u shuld maintain a mapping for names to numbers ( eg novell may be 2) and convert the created alphabetic string into SNMP string...

to be more clear, suppose after parsing a para from mib file you get netware.mibdoc.something and the mapping file gives netware = 1, mibdoc = 2, and something = 3 then you can finally construct snmp id as 1.2.3

is it enough, u will need to follow how ASN notations are used into mib files and the mapping can be obtained from RFCs.
and u'll also need to to write a code for this.

BTW, may i know why u need to do this?

HTH
Kiran - http://kiran7.freeservers.com

     
0
 

Author Comment

by:miauw
Comment Utility
Tnx for your comment lsmgms. Probably somewhere hidden in your algoritme lies the answer I am after. This could be very usefull to some, but personally I wasn't planning on programming and/or learning to use C in order to understand SNMP. And if I was to write a parser properly I would have to understand ASN and the MIB syntaxis first.

Furthermore I can hardly believe that I am unique in wanting to be able to convert MIBs to OIDs, so there should be some appz out there (no luck finding yet something except for Solaris which I do not like to run (yet) ).

Tnx kiranghag I was just hoping someone could give me an example of how a human parser would go and start the translation. Your example is simple enough, but is it such that:
layerX+1 OBJECT IDENTIFIER ::= { LayerX ValueofX+1 }
layerX+2 OBJECT IDENTIFIER ::= { layerX+1 ValueofLayerX+2 }
layerX+3a OBJECT IDENTIFIER ::= { layerX+2 ValueofLayerX+3a }
layerX+3b OBJECT IDENTIFIER ::= { layerX+2 ValueofLayerX+3b }

such that
layerx.layerx+1.layerx+2.layerx+3a translates to
    ????????????.ValueofX+1.valueofLayerx+2.valueofLayerx+3
If so: then it is not obvious to me where I can find the info to find the correct values for ??????????????.
They are probably either imported from another MIB or includes in an standard RFC-MIB which is supported by the software (e.g. 1212).

Could you expand on this?


BTW: I want to know this stuff because of 2 reasons
1) In networkmanagementsoftware it is easier to find the MIBs than the OIDs (if available) and you sometimes need the OIDs to add an counter or you might want to query a lot of separate things for which you would need to a load of possible conflicting MIBs.
2) For the sake of understanding it a bit
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:miauw
Comment Utility
Well I had a spare 15 minutes and took another look at some MIBs - OIDs. It is getting a little bit more clear to me. Below I post what I understand now. Please eloborate on this.

I am somewhat futher in reading MIBs. Let me share this info for those
struggleling at the same basic level.

Suppose you needs the SNMP OIDS (e.g. 1.3.2.43.4.4) for your managementsoftware
and you only have the MIBs. Then you will have the same problem as I have ;-))
This is how I figured you can translate some (or most/all???) symbolical names into OIDs.


Somewhere in the MIB, a Netware MIB in this case, I find a Description of something which
sounds interesting enough to monitor like:

       nwSysServerName OBJECT-TYPE
          SYNTAX InternationalDisplayString (SIZE(0..48))
          ACCESS read-only
          STATUS mandatory
          DESCRIPTION
                 "The physical name of this NetWare server."
          ::= { nwSystem 1 }

=> name = ?.nwSystem.nwSysServerName
=> OID = ?.?.1

Now search for nwSystem from the top of the MIB:

nwSystem       OBJECT IDENTIFIER ::= { nwServer 1 }

=> name = ?.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.1.1

Now search for nwServer from the top of the MIB:

nwServer       OBJECT IDENTIFIER ::= { mibDoc 28 }

=> name = ?.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.28.1.1

Now search for mibDoc from the top of the MIB:

mibDoc         OBJECT IDENTIFIER ::= { novell 2 }

=> name = ?.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.2.28.1.1

It get boring now: search for novell from the top of the MIB:

novell         OBJECT IDENTIFIER ::= { enterprises 23 }

=> name = ?.enterprises.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.23.2.28.1.1

Now search for enterprises from the top of the MIB:

IMPORTS
  enterprises, Counter, TimeTicks
  FROM RFC1155-SMI

Now open RFC1115-SMI and search for enterprises:

enterprises   OBJECT IDENTIFIER ::= { private 1 }

=> name = ?.private.enterprises.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.1.23.2.28.1.1

Now search for private (ofcourse in RFC1155-SMI):

private       OBJECT IDENTIFIER ::= { internet 4 }

=> name = ?.internet.private.enterprises.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.4.1.23.2.28.1.1

Now search for internet:

internet      OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }

Hmmm, this is another syntax, buth it suggests that
 org.dod.internet = .3.6.1
 which is actually right.

=> name = ?.org.dod.internet.private.enterprises.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = ?.?.3.6.1.4.1.23.2.28.1.1

Now we are close: what the hell does iso stand for?
I know this is 1. Guess you have to know this???

so:
=> name = iso.org.dod.internet.private.enterprises.novell.mibDoc.nwServer.nwSystem.nwSysServerName
=> OID = 1.3.6.1.4.1.23.2.28.1.1


I hope this helps someone. Still trying to get a firm grip on this stuff. I feel my question is not yet answered satisfatory.
0
 

Author Comment

by:miauw
Comment Utility
Well, my "not getting stopped by any lack of knowledge" approach in translating the MIBs into OID seems to work out very well, that is for a sample of MIBs I am interested in.

So I humbly think that I gave the best answer.
However, who helped me the most to overcome this blind spot is kiranghag so I will give them to him.

Tnx guys,

 Miauw
0
 

Author Comment

by:miauw
Comment Utility
It was between good and excellent. Hate to give low marks.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This is the first one of a series of articles I’ll be writing to address technical issues that are always referred to as network problems. The network boundaries have changed, therefore having an understanding of how each piece in the network  puzzl…
If your business is like most, chances are you still need to maintain a fax infrastructure for your staff. It’s hard to believe that a communication technology that was thriving in the mid-80s could still be an essential part of your team’s modern I…
After creating this article (http://www.experts-exchange.com/articles/23699/Setup-Mikrotik-routers-with-OSPF.html), I decided to make a video (no audio) to show you how to configure the routers and run some trace routes and pings between the 7 sites…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now