Solved

SNMP: reading MIB and converting them into OIDs

Posted on 2002-04-16
6
7,547 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
6 Comments
 
LVL 1

Expert Comment

by:lsmgms
ID: 6958925
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
ID: 6958928
{ 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
ID: 6960255
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
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 

Author Comment

by:miauw
ID: 6960482
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
ID: 6963338
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
ID: 6963354
It was between good and excellent. Hate to give low marks.
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For many of us, the  holiday season kindles the natural urge to give back to our friends, family members and communities. While it's easy for friends to notice the impact of such deeds, understanding the contributions of businesses and enterprises i…
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

688 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