Exemple #1
0
void addq(SnmpMgmtQuery *q, RFC1157VarBind *vb, UINT i, UINT v)
    {

    SNMPDBG((SNMP_LOG_TRACE, "SNMP: PDU: adding variable %d to query 0x%08lx (%s).\n", i+1, q->addr, SnmpUtilOidToA(&vb->name)));

    q->vbl.len++; // add varbind to end of list
    q->vbl.list = (RFC1157VarBind *)SnmpUtilMemReAlloc(q->vbl.list, (q->vbl.len * sizeof(RFC1157VarBind)));
    q->xlat = (RFC1157VarBindXlat *)SnmpUtilMemReAlloc(q->xlat, (q->vbl.len * sizeof(RFC1157VarBindXlat)));

    q->xlat[q->vbl.len-1].view  = v;
    q->xlat[q->vbl.len-1].index = i;

    SnmpUtilVarBindCpy(&q->vbl.list[q->vbl.len-1], vb);

    } // end addq()
Exemple #2
0
void addql(SnmpMgmtQueryList *ql, RFC1157VarBindList *vbl, UINT vb, UINT v)
    {
    UINT q; // index into query list

    // make sure that the type is correct
    if ((ql->type != ASN_RFC1157_SETREQUEST) && 
        (vbl->list[vb].value.asnType != ASN_NULL)) {
        
        SNMPDBG((
            SNMP_LOG_TRACE,
            "SNMP: PDU: forcing asnType to NULL (asnType=%d).\n",
            (DWORD)(BYTE)vbl->list[vb].value.asnType
            ));

        // force the asn type to be null
        vbl->list[vb].value.asnType = ASN_NULL;        
    }     

    // process existing queries
    for (q=0; q < ql->len; q++)
        {
        // compare existing extension agent addresses 
        if (ql->query[q].addr == extAgents[vl[v]].queryAddr)
            {
            // add to existing query
            addq(&ql->query[q], &vbl->list[vb], vb, v);
            return;
            }
        }

    SNMPDBG((SNMP_LOG_TRACE, "SNMP: PDU: creating query for %s (0x%08lx).\n", extAgents[vl[v]].pathName, extAgents[vl[v]].queryAddr));

    ql->len++; // add new query to end of list
    ql->query = (SnmpMgmtQuery *)SnmpUtilMemReAlloc(ql->query, (ql->len * sizeof(SnmpMgmtQuery)));

    ql->query[q].xlat = NULL;
    ql->query[q].addr = extAgents[vl[v]].queryAddr;

    ql->query[q].vbl.len = 0;
    ql->query[q].vbl.list = NULL;

    // add to newly created query
    addq(&ql->query[q], &vbl->list[vb], vb, v);

    } // end addql()
Exemple #3
0
BOOL eaConfig(
    OUT CfgExtensionAgents   **extAgents,
    OUT INT *extAgentsLen)
    {
    LONG  status;
    HKEY  hkResult;
    HKEY  hkResult2;
    DWORD iValue;
    DWORD iValue2;
//    DWORD dwTitle;
    DWORD dwType;
    TCHAR dummy[MAX_PATH+1];
    DWORD dummySize;
    TCHAR value[MAX_PATH+1];
    DWORD valueSize;
    LPSTR pTemp;
    DWORD valueReqSize;
    LPSTR pTempExp;

    *extAgents = NULL;
    *extAgentsLen = 0;

    SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: loading extension agents.\n"));

    if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszSnmpSrvEaKey,
                               0, (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
                               KEY_TRAVERSE), &hkResult)) != ERROR_SUCCESS)
        {
        SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d opening ExtensionAgents subkey.\n", status));
        SnmpSvcReportEvent(SNMP_EVENT_INVALID_REGISTRY_KEY, 1, &pszSnmpSrvEaKey, status);
        return FALSE;
        }

    iValue = 0;

    dummySize = MAX_PATH;
    valueSize = MAX_PATH;


    while((status = RegEnumValue(hkResult, iValue, dummy, &dummySize,
                                 NULL, &dwType, (LPBYTE)value, &valueSize))
          != ERROR_NO_MORE_ITEMS)
        {
        if (status != ERROR_SUCCESS)
            {
            SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d enumerating ExtensionAgents subkey.\n", status));
            SnmpSvcReportEvent(SNMP_EVENT_INVALID_REGISTRY_KEY, 1, &pszSnmpSrvEaKey, status);
            RegCloseKey(hkResult);
            return FALSE;
            }

        SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: processing %s.\n", value));
        if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, value, 0,
                                   (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS
                              | KEY_TRAVERSE), &hkResult2)) != ERROR_SUCCESS)
            {
            SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d opening registy key %s.\n", status, value));
            pTemp = value; // make pointer for event api
            SnmpSvcReportEvent(SNMP_EVENT_INVALID_EXTENSION_AGENT_KEY, 1, &pTemp, status);
            goto process_next; // ignore bogus registry key and process next one...
            }

        iValue2 = 0;

        dummySize = MAX_PATH;
        valueSize = MAX_PATH;

        while((status = RegEnumValue(hkResult2, iValue2, dummy, &dummySize,
                                     NULL, &dwType, (LPBYTE)value, &valueSize))
              != ERROR_NO_MORE_ITEMS)
            {
            if (status != ERROR_SUCCESS)
                {
                SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d enumerating registry key %s.\n", status, value));
                pTemp = value; // make pointer for event api
                SnmpSvcReportEvent(SNMP_EVENT_INVALID_EXTENSION_AGENT_KEY, 1, &pTemp, status);
                break; // ignore bogus registry key and process next one...
                }

            if (!lstrcmpi(dummy, TEXT("Pathname")))
                {
                (*extAgentsLen)++;
                *extAgents = (CfgExtensionAgents *) SnmpUtilMemReAlloc(*extAgents,
                    (*extAgentsLen * sizeof(CfgExtensionAgents)));

                pTemp = (LPSTR)SnmpUtilMemAlloc(valueSize+1);
#ifdef UNICODE
                SnmpUtilUnicodeToAnsi(&pTemp, value, FALSE);
#else
                memcpy(pTemp, value, valueSize+1);
#endif

                valueReqSize = valueSize + 10;
                pTempExp = NULL;
                do {
                    pTempExp = (LPSTR)SnmpUtilMemReAlloc(pTempExp, valueReqSize);
                    valueSize = valueReqSize;
                    valueReqSize = ExpandEnvironmentStringsA(
                                          pTemp,
                                          pTempExp,
                                          valueSize);

                } while (valueReqSize > valueSize );
                if (valueReqSize == 0) {
                    SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: error %d expanding %s.\n", GetLastError(), value));
                    (*extAgents)[(*extAgentsLen)-1].pathName = pTemp;
                } else {
                    SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: processing %s.\n", pTempExp));
                    (*extAgents)[(*extAgentsLen)-1].pathName = pTempExp;
                    SnmpUtilMemFree(pTemp);
                }

                break;
                }

            dummySize = MAX_PATH;
            valueSize = MAX_PATH;

            iValue2++;
            } // end while()

        RegCloseKey(hkResult2);

process_next:

        dummySize = MAX_PATH;
        valueSize = MAX_PATH;

        iValue++;
        } // end while()

    RegCloseKey(hkResult);

    return TRUE;

    } // end eaConfig()
Exemple #4
0
BOOL pmConfig(
    OUT CfgPermittedManagers **permitMgrs,
    OUT INT *permitMgrsLen)
    {
    LONG  status;
    HKEY  hkResult;
    DWORD iValue;
//    DWORD dwTitle;
    DWORD dwType;
    TCHAR dummy[MAX_PATH+1];
    DWORD dummySize;
    TCHAR value[MAX_PATH+1];
    DWORD valueSize;
    LPSTR pTemp;

    *permitMgrs = NULL;
    *permitMgrsLen = 0;

    SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: loading permitted managers.\n"));

    if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszSnmpSrvPmKey,
                               0, (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
                               KEY_TRAVERSE), &hkResult)) != ERROR_SUCCESS)
        {
        SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d opening PermittedManagers subkey.\n", status));
        SnmpSvcReportEvent(SNMP_EVENT_INVALID_REGISTRY_KEY, 1, &pszSnmpSrvPmKey, status);
        return FALSE;
        }

    iValue = 0;

    dummySize = MAX_PATH;
    valueSize = MAX_PATH;

    while((status = RegEnumValue(hkResult, iValue, dummy, &dummySize,
                                 NULL, &dwType, (LPBYTE)value, &valueSize))
          != ERROR_NO_MORE_ITEMS)
        {
        if (status != ERROR_SUCCESS)
            {
            SNMPDBG((SNMP_LOG_ERROR, "SNMP: INIT: error %d enumerating PermittedManagers subkey.\n", status));
            SnmpSvcReportEvent(SNMP_EVENT_INVALID_REGISTRY_KEY, 1, &pszSnmpSrvPmKey, status);
            RegCloseKey(hkResult);
            return FALSE;
            }

        SNMPDBG((SNMP_LOG_TRACE, "SNMP: INIT: processing permitted manager %s\n", value));
        (*permitMgrsLen)++;
        *permitMgrs = (CfgPermittedManagers *)SnmpUtilMemReAlloc(*permitMgrs,
            (*permitMgrsLen * sizeof(CfgPermittedManagers)));

        pTemp = (LPSTR)SnmpUtilMemAlloc(valueSize+1);
        value[valueSize] = TEXT('\0');
#ifdef UNICODE
        SnmpUtilUnicodeToAnsi(&pTemp, value, FALSE);
#else
        memcpy(pTemp, value, valueSize+1);
#endif

        (*permitMgrs)[iValue].addrText = pTemp;
        SnmpSvcAddrToSocket((*permitMgrs)[iValue].addrText,
                     &((*permitMgrs)[iValue].addrEncoding));

        dummySize = MAX_PATH;
        valueSize = MAX_PATH;

        iValue++;
        }

    RegCloseKey(hkResult);

    return TRUE;

    } // end pmConfig()
Exemple #5
0
VOID trapThread(VOID *threadParam)
    {
    INT    eventListSize      = 0;
    HANDLE *eventList         = NULL;
    INT    *eventListRegIndex = NULL;
    DWORD  status;
    INT    i;

    AsnObjectIdentifier enterprise;
    AsnInteger          genericTrap;
    AsnInteger          specificTrap;
    AsnInteger          timeStamp;
    RFC1157VarBindList  variableBindings;

    UNREFERENCED_PARAMETER(threadParam);


    // create an event to allow this thread to be signaled to terminate

    if ((hExitTrapThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
        {
        SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d creating termination event.\n", GetLastError()));

        goto longBreak;
        }


    // add this thread's terminate event to the list...

    if ((eventList = (HANDLE *)SnmpUtilMemReAlloc(eventList, sizeof(HANDLE))) == NULL)
        {
        SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: out of memory.\n"));

        goto longBreak;
        }

    if ((eventListRegIndex = (INT *)SnmpUtilMemReAlloc(eventListRegIndex, sizeof(INT)))
        == NULL)
        {
        SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: out of memory.\n"));

        goto longBreak;
        }

    eventList[eventListSize]           = hExitTrapThreadEvent;
    eventListRegIndex[eventListSize++] = -1; // not really used


    // add trap events for extension agents that have provided an event...

    for (i=0; i<extAgentsLen; i++)
        {
        if (extAgents[i].trapEvent != NULL &&
            extAgents[i].fInitedOk)
            {
            if ((eventList = (HANDLE *)SnmpUtilMemReAlloc(eventList, (eventListSize+1)*sizeof(HANDLE)))
                == NULL)
                {
                SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: out of memory.\n"));

                goto longBreak;
                }

            if ((eventListRegIndex = (INT *)SnmpUtilMemReAlloc(eventListRegIndex,
                (eventListSize+1)*sizeof(INT))) == NULL)
                {
                SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: out of memory.\n"));

                goto longBreak;
                }

            eventList[eventListSize]           = extAgents[i].trapEvent;
            eventListRegIndex[eventListSize++] = i;
            }
        } // end for()


    // perform normal processing...

    while(1)
        {
        if      ((status = WaitForMultipleObjects(eventListSize, eventList,
                 FALSE, TTWFMOTimeout)) == 0xffffffff)
            {
            SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d waiting for trap event list.\n", GetLastError()));

            goto longBreak;
            }
        else if (status == WAIT_TIMEOUT)
            {
            SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: timeout waiting for trap event list.\n"));

            continue;
            }

        // the service will set event 0 in the event list when it wants
        // this thread to terminate.

        if (status == 0)
            {
            SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: termination event set.\n"));
            break; // if hExitTrapThreadEvent, then exit
            }

        SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: polling %s for traps.\n", extAgents[eventListRegIndex[status]].extPath));

        // call snmpextensiontrap entry of appropriate extension dll...

        while ((*extAgents[eventListRegIndex[status]].trapFunc)(&enterprise,
                &genericTrap, &specificTrap, &timeStamp, &variableBindings))
            {
            if (!SnmpSvcGenerateTrap(&enterprise, genericTrap, specificTrap,
                                         timeStamp, &variableBindings))
                {
                SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error %d generating trap.\n", GetLastError()));

                //not a serious error.
                }
            }

        } // end while()

longBreak:

    if (eventList)         SnmpUtilMemFree(eventList);
    if (eventListRegIndex) SnmpUtilMemFree(eventListRegIndex);

    SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: agentTrapThread exiting.\n"));

    } // end trapThread()
// Main program.
INT _CRTAPI1 main(
    IN int  argumentCount,
    IN char *argumentVector[])
    {
    INT                operation;
    LPSTR              agent = NULL;
    LPSTR              community = NULL;
    RFC1157VarBindList variableBindings;
    LPSNMP_MGR_SESSION session = NULL;

    INT        timeout = TIMEOUT;
    INT        retries = RETRIES;

    BYTE       requestType;
    AsnInteger errorStatus;
    AsnInteger errorIndex;


    // 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)SnmpUtilMemAlloc((UINT)(strlen(*argumentVector) + 1));
        if (agent != NULL)
            StringCchCopyA(agent, strlen(*argumentVector) + 1, *argumentVector);
        else
            {
            printf("Error: SnmpUtilMemAlloc failed to allocate memory.\n");
            return 1;
            }

        // Get agent community...
        argumentVector++;
        argumentCount--;
        community = (LPSTR)SnmpUtilMemAlloc((UINT)(strlen(*argumentVector) + 1));
        if (community != NULL)
            StringCchCopyA(community, strlen(*argumentVector) + 1, *argumentVector);
        else
            {
            printf("Error: SnmpUtilMemAlloc failed to allocate memory.\n");
            SnmpUtilMemFree(agent);
            return 1;
            }

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

        while(--argumentCount)
            {
            AsnObjectIdentifier reqObject;
            RFC1157VarBind * tmpVb;

            argumentVector++;

            // Convert the string representation to an internal representation.
            if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
                {
                printf("Error: Invalid oid, %s, specified.\n", *argumentVector);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            else
                {
                // Since sucessfull, add to the variable bindings list.
                variableBindings.len++;
                if ((tmpVb = (RFC1157VarBind *)SnmpUtilMemReAlloc(
                    variableBindings.list, sizeof(RFC1157VarBind) *
                    variableBindings.len)) == NULL)
                    {
                    printf("Error: Error allocating oid, %s.\n",
                           *argumentVector);
                    SnmpUtilMemFree(agent);
                    SnmpUtilMemFree(community);
                    SnmpUtilOidFree(&reqObject);
                    variableBindings.len--;
                    SnmpUtilVarBindListFree(&variableBindings);

                    return 1;
                    }
                variableBindings.list = tmpVb;

                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");
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);
            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());
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);

            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;
                
                for(i=0; i < variableBindings.len; i++)
                    {
                    char *string = NULL;
                    
                    if (SnmpMgrOidToStr(&variableBindings.list[i].name, &string))
                        {
                        printf("Variable = %s\n", string);
                        if (string) SnmpUtilMemFree(string);
                        }
                    printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[i].value);

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

        // Free the variable bindings that have been allocated.
        
        SnmpUtilVarBindListFree(&variableBindings);
        
        // Free other allocated resources 

        SnmpUtilMemFree(agent);
        SnmpUtilMemFree(community);


        }
    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;
        
        
        if (!SnmpUtilOidCpy(&root, &variableBindings.list[0].name))
            {
            printf("error on SnmpUtilOidCpy\n");
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);
            return 1;
            }
        
        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;
                    
                    if (SnmpMgrOidToStr(&variableBindings.list[0].name, &string))
                        {
                        printf("Variable = %s\n", string);
                        if (string) SnmpUtilMemFree(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.
            
            if (!SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name))
                {
                printf("error on SnmpUtilOidCpy\n");
                SnmpUtilOidFree(&root);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            
            SnmpUtilVarBindFree(&variableBindings.list[0]);
            
            if (!SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid))
                {
                printf("error on SnmpUtilOidCpy\n");
                SnmpUtilOidFree(&tempOid);
                SnmpUtilOidFree(&root);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            variableBindings.list[0].value.asnType = ASN_NULL;
            
            SnmpUtilOidFree(&tempOid);
            
        } // end while()
        
        
        // Free the variable bindings that have been allocated.
        
        SnmpUtilVarBindListFree(&variableBindings);
        
        // Free other allocated resources

        SnmpUtilOidFree(&root);
        SnmpUtilMemFree(agent);
        SnmpUtilMemFree(community);
        
        
    }
    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());
            return 1;
            }
        else
            {
            printf("snmputil: listening for traps...\n");
            }


        while(1)
            {
            DWORD dwResult;

            if ((dwResult = WaitForSingleObject(hNewTraps, INFINITE))
                == WAIT_FAILED)
                {
                printf("error on WaitForSingleObject %d\n",
                       GetLastError());
                }
            else if (dwResult != WAIT_OBJECT_0)
                {
                    printf("hNewTraps is not signaled\n");
                }
            else if (!ResetEvent(hNewTraps))
                {
                printf("error on ResetEvent %d\n", GetLastError());
                }
            else
                {
                AsnObjectIdentifier enterprise;
                AsnNetworkAddress   agentAddress;
                AsnNetworkAddress   sourceAddress;
                AsnInteger          genericTrap;
                AsnInteger          specificTrap;
                AsnOctetString      communityTrap;
                AsnTimeticks        timeStamp;
                RFC1157VarBindList  variableBindingsTrap;

                UINT i;
                
                while(SnmpMgrGetTrapEx(
                        &enterprise,
                        &agentAddress,
                        &sourceAddress,
                        &genericTrap,
                        &specificTrap,
                        &communityTrap,
                        &timeStamp,
                        &variableBindingsTrap))
                    {

                    LPSTR string = NULL;

                    printf("Incoming Trap:\n"
                           "  generic    = %d\n"
                           "  specific   = %d\n"
                           "  timeStamp  = %u\n",
                           genericTrap,
                           specificTrap,
                           timeStamp);

                    if (SnmpMgrOidToStr(&enterprise, &string))
                        {
                        printf ("  enterprise = %s\n", string);
                        if (string) 
                            SnmpUtilMemFree(string);
                        }
                    SnmpUtilOidFree(&enterprise);

                    if (agentAddress.length == 4) 
                        {
                        printf ("  agent      = %d.%d.%d.%d\n",
                             (int)agentAddress.stream[0],
                             (int)agentAddress.stream[1],
                             (int)agentAddress.stream[2],
                             (int)agentAddress.stream[3]);
                        }
                    if (agentAddress.dynamic) 
                        {
                        SnmpUtilMemFree(agentAddress.stream);
                        }

                    if (sourceAddress.length == 4) 
                        {
                        printf ("  source IP  = %d.%d.%d.%d\n",
                             (int)sourceAddress.stream[0],
                             (int)sourceAddress.stream[1],
                             (int)sourceAddress.stream[2],
                             (int)sourceAddress.stream[3]);
                        }
                    else if (sourceAddress.length == 10) 
                        {
                        printf ("  source IPX = %.2x%.2x%.2x%.2x."
                                "%.2x%.2x%.2x%.2x%.2x%.2x\n",
                             (int)sourceAddress.stream[0],
                             (int)sourceAddress.stream[1],
                             (int)sourceAddress.stream[2],
                             (int)sourceAddress.stream[3],
                             (int)sourceAddress.stream[4],
                             (int)sourceAddress.stream[5],
                             (int)sourceAddress.stream[6],
                             (int)sourceAddress.stream[7],
                             (int)sourceAddress.stream[8],
                             (int)sourceAddress.stream[9]);
                        }
                    if (sourceAddress.dynamic) 
                        {
                        SnmpUtilMemFree(sourceAddress.stream);
                        }

                    if (communityTrap.length)
                        {
                        string = (LPSTR)SnmpUtilMemAlloc (communityTrap.length + 1);
                        if (string)
                            {
                            memcpy (string, communityTrap.stream, communityTrap.length);
                            string[communityTrap.length] = '\0';
                            printf ("  community  = %s\n", string);
                            SnmpUtilMemFree(string);
                            }
                        }
                    if (communityTrap.dynamic) 
                        {
                        SnmpUtilMemFree(communityTrap.stream);
                        }

                    for(i=0; i < variableBindingsTrap.len; i++)
                        {

                        string = NULL;
                        if (SnmpMgrOidToStr(&variableBindingsTrap.list[i].name, &string))
                            {
                            printf("  variable   = %s\n", string);
                            if (string) SnmpUtilMemFree(string);
                            }

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


                    SnmpUtilVarBindListFree(&variableBindingsTrap);
                    }

                dwResult = GetLastError(); // check for errors...

                if ((dwResult != NOERROR) && (dwResult != SNMP_MGMTAPI_NOTRAPS))
                    {
                    printf("error on SnmpMgrGetTrap %d\n", dwResult);
                    }
                }

            } // 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()