void delql(SnmpMgmtQueryList *ql) { UINT q; // index into query list // process queries for (q=0; q < ql->len; q++) { SNMPDBG((SNMP_LOG_TRACE, "SNMP: PDU: deleting query 0x%08lx.\n", ql->query[q].addr)); // free translation info SnmpUtilMemFree(ql->query[q].xlat); // free query varbind list (and variables) SnmpUtilVarBindListFree(&ql->query[q].vbl); } // free query list SnmpUtilMemFree(ql->query); } // end delql()
int _cdecl main( IN int argumentCount, IN char *argumentVector[]) { HANDLE hExtension; FARPROC initAddr; FARPROC queryAddr; FARPROC trapAddr; DWORD timeZeroReference; HANDLE hPollForTrapEvent; View supportedView; INT numQueries = 10; // avoid compiler warning... UNREFERENCED_PARAMETER(argumentCount); UNREFERENCED_PARAMETER(argumentVector); timeZeroReference = GetCurrentTime(); // load the extension agent dll and resolve the entry points... if (GetModuleHandle("testdll.dll") == NULL) { if ((hExtension = LoadLibrary("testdll.dll")) == NULL) { dbgprintf(1, "error on LoadLibrary %d\n", GetLastError()); } else if ((initAddr = GetProcAddress(hExtension, "SnmpExtensionInit")) == NULL) { dbgprintf(1, "error on GetProcAddress %d\n", GetLastError()); } else if ((queryAddr = GetProcAddress(hExtension, "SnmpExtensionQuery")) == NULL) { dbgprintf(1, "error on GetProcAddress %d\n", GetLastError()); } else if ((trapAddr = GetProcAddress(hExtension, "SnmpExtensionTrap")) == NULL) { dbgprintf(1, "error on GetProcAddress %d\n", GetLastError()); } else { // initialize the extension agent via its init entry point... (*initAddr)( timeZeroReference, &hPollForTrapEvent, &supportedView); } } // end if (Already loaded) // create a trap thread to respond to traps from the extension agent... //rather than oomplicate this test routine, will poll for these events //below. normally this would be done by another thread in the extendible //agent. // loop here doing repetitive extension agent get queries... // poll for potential traps each iteration (see note above)... //block... printf( "SET on toasterManufacturer - shouldn't work\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 1, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_OCTETSTRING; varBinds.list[0].value.asnValue.string.length = 0; varBinds.list[0].value.asnValue.string.stream = NULL; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterControl with invalid value\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 500; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterControl with invalid type\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_NULL; varBinds.list[0].value.asnValue.number = 500; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterControl\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 2; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterDoneness with invalid value\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 1000; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterDoneness with invalid type\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_NULL; varBinds.list[0].value.asnValue.number = 1000; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterDoneness\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 10; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterToastType with invalid value\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 10; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterToastType with invalid type\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_NULL; varBinds.list[0].value.asnValue.number = 10; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } printf( "SET on toasterToastType\n" ); { UINT itemn[] = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 }; RFC1157VarBindList varBinds; AsnInteger errorStatus = 0; AsnInteger errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT); varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)* varBinds.list[0].name.idLength ); memcpy( varBinds.list[0].name.ids, &itemn, sizeof(UINT)*varBinds.list[0].name.idLength ); varBinds.list[0].value.asnType = ASN_INTEGER; varBinds.list[0].value.asnValue.number = 7; printf( "SET: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " to " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); (*queryAddr)( ASN_RFC1157_SETREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\nSET Errorstatus: %lu\n\n", errorStatus ); (*queryAddr)( ASN_RFC1157_GETREQUEST, &varBinds, &errorStatus, &errorIndex ); if ( errorStatus == SNMP_ERRORSTATUS_NOERROR ) { printf( "New Value: " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); putchar( '\n' ); } printf( "\nGET Errorstatus: %lu\n\n", errorStatus ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); printf( "\n\n" ); } { RFC1157VarBindList varBinds; AsnInteger errorStatus; AsnInteger errorIndex; UINT OID_Prefix[] = { 1, 3, 6, 1, 4, 1, 12 }; AsnObjectIdentifier MIB_OidPrefix = { OID_SIZEOF(OID_Prefix), OID_Prefix }; errorStatus = 0; errorIndex = 0; varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) ); varBinds.len = 1; SnmpUtilOidCpy( &varBinds.list[0].name, &MIB_OidPrefix ); varBinds.list[0].value.asnType = ASN_NULL; do { printf( "GET-NEXT of: " ); SnmpUtilPrintOid( &varBinds.list[0].name ); printf( " " ); (*queryAddr)( (AsnInteger)ASN_RFC1157_GETNEXTREQUEST, &varBinds, &errorStatus, &errorIndex ); printf( "\n is " ); SnmpUtilPrintOid( &varBinds.list[0].name ); if ( errorStatus ) { printf( "\nErrorstatus: %lu\n\n", errorStatus ); } else { printf( "\n = " ); SnmpUtilPrintAsnAny( &varBinds.list[0].value ); } putchar( '\n' ); // query potential traps (see notes above) if ( NULL != hPollForTrapEvent ) { DWORD dwResult; if ( 0xffffffff == (dwResult = WaitForSingleObject(hPollForTrapEvent, 1000)) ) { dbgprintf(1, "error on WaitForSingleObject %d\n", GetLastError()); } else { if ( dwResult == 0 /*signaled*/ ) { AsnObjectIdentifier enterprise; AsnInteger genericTrap; AsnInteger specificTrap; AsnTimeticks timeStamp; RFC1157VarBindList variableBindings; while( (*trapAddr)(&enterprise, &genericTrap, &specificTrap, &timeStamp, &variableBindings) ) { printf("trap: gen=%d spec=%d time=%d\n", genericTrap, specificTrap, timeStamp); //also print data } // end while () } // end if (trap ready) } } // end if (handling traps) } while ( varBinds.list[0].name.ids[MIB_PREFIX_LEN-1] == 12 ); // Free the memory SnmpUtilVarBindListFree( &varBinds ); } // block return 0; } // end main()
BOOL CSNMP::SnmpQueryTable( LPCTSTR apColumnOidList[], UINT nListLen, std::vector<std::pair<CString, std::vector<AsnAny>>> *pTable ) { if (!apColumnOidList || !pTable) { m_strLastError = L"[SnmpQueryTable] : Verify the arguments failed. "; return FALSE; } pTable->clear(); if (!nListLen) return TRUE; typedef std::map<CString, AsnAny> RELATIVE_OID_TO_VALUE_MAP; std::vector<RELATIVE_OID_TO_VALUE_MAP> vColumnRelativeOidToValue(nListLen); SnmpVarBindList CurrentVarBindList; CurrentVarBindList.len = 0; CurrentVarBindList.list = NULL; AsnObjectIdentifier TargetObjectIdentifier; TargetObjectIdentifier.idLength = 0; TargetObjectIdentifier.ids = NULL; BOOL bRes = FALSE; do { UINT i = 0; for (; i < nListLen; i++) { SnmpUtilVarBindListFree(&CurrentVarBindList); CurrentVarBindList.len = 1; CurrentVarBindList.list = (SnmpVarBind *)SnmpUtilMemAlloc(sizeof(SnmpVarBind)); CurrentVarBindList.list->name.idLength = 0; CurrentVarBindList.list->name.ids = NULL; CurrentVarBindList.list->value.asnType = ASN_NULL; #ifdef _UNICODE CStringA strOIDA = XLibS::StringCode::ConvertWideStrToAnsiStr(apColumnOidList[i]); #else CStringA strOIDA = apColumnOidList[i]; #endif if(!::SnmpMgrStrToOid(strOIDA.GetBuffer(), &CurrentVarBindList.list->name) || !CurrentVarBindList.list->name.ids || !CurrentVarBindList.list->name.idLength) { #ifdef _UNICODE CStringW strOIDW = apColumnOidList[i]; #else CStringW strOIDW = XLibS::StringCode::ConvertAnsiStrToWideStr(apColumnOidList[i]); #endif m_strLastError.Format(L"[SnmpQueryTable] : Bad OID string \"%s\". ", (LPCWSTR)strOIDW); strOIDA.ReleaseBuffer(); break; } strOIDA.ReleaseBuffer(); SnmpUtilOidFree(&TargetObjectIdentifier); TargetObjectIdentifier.idLength = 0; TargetObjectIdentifier.ids = NULL; if (!SnmpUtilOidCpy(&TargetObjectIdentifier, &CurrentVarBindList.list->name) || !TargetObjectIdentifier.ids || !TargetObjectIdentifier.idLength) { m_strLastError.Format(L"[SnmpQueryTable] : Copy OID failed. "); break; } BOOL bFailFlag = FALSE; while(1) { AsnInteger nSNMPErrorCode = 0; AsnInteger nSNMPErrorIndex = 0; if(!::SnmpMgrRequest(m_SnmpSession, SNMP_PDU_GETNEXT, &CurrentVarBindList, &nSNMPErrorCode, &nSNMPErrorIndex)) { DWORD dwLastWinError = ::GetLastError(); assert(nSNMPErrorIndex == 0); const WCHAR * SNMP_ERROR_MESSAGE[] = { L"The agent reports that no errors occurred during transmission. ", L"The agent could not place the results of the requested operation into a single SNMP message. ", L"The requested operation identified an unknown variable. ", L"The requested operation tried to change a variable but it specified either a syntax or value error. ", L"The requested operation tried to change a variable that was not allowed to change according to the community profile of the variable. " }; const WCHAR * WIN_ERROR_MESSAGE[] = {L"The request timed-out.", L"Unexpected error file descriptors indicated by the Windows Sockets select function." }; const WCHAR *pSNMPError = NULL; if (nSNMPErrorIndex < ARRAYSIZE(SNMP_ERROR_MESSAGE)) pSNMPError = SNMP_ERROR_MESSAGE[nSNMPErrorIndex]; else pSNMPError = L"Unknown error. "; const WCHAR *pWinError = NULL; if (dwLastWinError - 40 < ARRAYSIZE(WIN_ERROR_MESSAGE)) pWinError = WIN_ERROR_MESSAGE[dwLastWinError - 40]; else pWinError = L"Unknown error. "; m_strLastError.Format(L"SNMP requesting failed. SNMP ERROR : %s (%ld). WIN ERROR : %s (%lu). ", pSNMPError, nSNMPErrorIndex, pWinError, dwLastWinError); // LPCWSTR pSysError = NULL; // m_strLastError.Format(L"SNMP requesting failed. SNMP ERROR : %s (%ld). ", pError, nErrorIndex); // if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, // NULL, dwLastError, 0, (LPTSTR)&pSysError, 0, NULL) && pSysError) // { // m_strLastError.AppendFormat(L"Windows ERROR: %s (%lu). ", pSysError, dwLastError); // // ::LocalFree((HLOCAL)pSysError); // pSysError = NULL; // } bFailFlag = TRUE; break; } assert(SNMP_ERRORSTATUS_NOERROR == nSNMPErrorCode); if (!CurrentVarBindList.list || (!CurrentVarBindList.list->name.ids && CurrentVarBindList.list->name.idLength)) { #ifdef _UNICODE CStringW strOIDW = apColumnOidList[i]; #else CStringW strOIDW = XLibS::StringCode::ConvertAnsiStrToWideStr(apColumnOidList[i]); #endif m_strLastError.Format(L"[SnmpQueryTable] : GetNext returned a bad OID during the request for %s. ", (LPCWSTR)strOIDW); bFailFlag = TRUE; break; } if (CurrentVarBindList.list->name.idLength < TargetObjectIdentifier.idLength) break; if (SnmpUtilOidNCmp(&CurrentVarBindList.list->name, &TargetObjectIdentifier, TargetObjectIdentifier.idLength)) break; CStringA strOIDTarget = ThreadSafeSnmpUtilOidToA(&TargetObjectIdentifier); CStringA strOIDCurrent = ThreadSafeSnmpUtilOidToA(&CurrentVarBindList.list->name); assert(strOIDCurrent.Find(strOIDTarget) == 0); AsnAny value; SnmpUtilAsnAnyCpy(&value, &CurrentVarBindList.list->value); #ifdef _UNICODE CString strRelativeOID = XLibS::StringCode::ConvertAnsiStrToWideStr(strOIDCurrent.Mid(strOIDTarget.GetLength())); #else CString strRelativeOID = strOIDCurrent.Mid(strOIDTarget.GetLength()); #endif vColumnRelativeOidToValue[i].insert(std::make_pair(strRelativeOID, value)); } if (bFailFlag) break; } if (i < nListLen) break; const RELATIVE_OID_TO_VALUE_MAP & FirstCol = vColumnRelativeOidToValue[0]; for (RELATIVE_OID_TO_VALUE_MAP::const_iterator itFirstCol = FirstCol.begin(); itFirstCol != FirstCol.end(); itFirstCol++) { std::vector<RELATIVE_OID_TO_VALUE_MAP::const_iterator> vItFind; UINT i = 1; for (; i < nListLen; i++) { const RELATIVE_OID_TO_VALUE_MAP & CurrentCol = vColumnRelativeOidToValue[i]; RELATIVE_OID_TO_VALUE_MAP::const_iterator itFind = CurrentCol.find(itFirstCol->first); if (itFind == CurrentCol.end()) break; vItFind.push_back(itFind); } if (i < nListLen) continue; pTable->push_back(make_pair(itFirstCol->first, std::vector<AsnAny>(1, itFirstCol->second))); for (std::vector<RELATIVE_OID_TO_VALUE_MAP::const_iterator>::size_type i = 0; i < vItFind.size(); i++) { pTable->back().second.push_back(vItFind[i]->second); } } bRes = TRUE; } while (FALSE); SnmpUtilOidFree(&TargetObjectIdentifier); SnmpUtilVarBindListFree(&CurrentVarBindList); if (!bRes) { ClearQueryTableResult(*pTable); pTable->clear(); } return bRes; }
SNMPAPI SNMP_FUNC_TYPE SnmpSvcGenerateTrap( IN AsnObjectIdentifier * enterprise, IN AsnInteger genericTrap, IN AsnInteger specificTrap, IN AsnTimeticks timeStamp, IN RFC1157VarBindList * variableBindings) { static BOOL fFirstTime = TRUE; static HANDLE hGenerateTrapMutex; static char myname[128]; static struct sockaddr mysocket; static SnmpMgmtCom request; static SOCKET fd_inet, fd_ipx, fd; static unsigned long nul_s_addr = 0L; struct sockaddr dest; BYTE *pBuf; UINT length; INT i, j; if (fFirstTime) { struct sockaddr localAddress; BOOL fSuccess; fFirstTime = FALSE; fSuccess = FALSE; // initialize trap destinations if (!tdConfig(&trapDests, &trapDestsLen)) { SnmpUtilVarBindListFree(variableBindings); return FALSE; } // setup 2 trap generation sockets, one for inet, one for ipx // block... { struct sockaddr_in localAddress_in; localAddress_in.sin_family = AF_INET; localAddress_in.sin_port = htons(0); localAddress_in.sin_addr.s_addr = ntohl(INADDR_ANY); bcopy(&localAddress_in, &localAddress, sizeof(localAddress_in)); } // end block. if ((fd_inet = socket(AF_INET, SOCK_DGRAM, 0)) == (SOCKET)-1) { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error %d creating udp trap generation socket.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); } else if (bind(fd_inet, &localAddress, sizeof(localAddress)) != 0) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d binding udp trap generation socket.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); } else { fSuccess = TRUE; } { struct sockaddr_ipx localAddress_ipx; bzero(&localAddress_ipx,sizeof(localAddress_ipx)); localAddress_ipx.sa_family = AF_IPX; bcopy(&localAddress_ipx, &localAddress, sizeof(localAddress_ipx)); } if ((fd_ipx = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == (SOCKET)-1) { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error %d creating ipx trap generation socket.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); } else if (bind(fd_ipx, &localAddress, sizeof(localAddress)) != 0) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d binding ipx trap generation socket.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); } else { fSuccess = TRUE; } if (!fSuccess) return FALSE; // create mutex... if ((hGenerateTrapMutex = CreateMutex(NULL, FALSE, NULL)) == NULL) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d creating trap generaion mutex.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); return FALSE; } // other one-time initialization... request.pdu.pduType = ASN_RFC1157_TRAP; if (fd_inet != (SOCKET)-1) { if (gethostname(myname, sizeof(myname)) == -1) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error on gethostname %d.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); return FALSE; } if (!SnmpSvcAddrToSocket(myname, &mysocket) == -1) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error on SnmpSvcAddrToSocket %d.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); return FALSE; } } } // end if (fFirstTime) // take mutex if (WaitForSingleObject(hGenerateTrapMutex, SGTTimeout) == 0xffffffff) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d waiting for trap generation mutex.\n", GetLastError())); SnmpUtilVarBindListFree(variableBindings); return FALSE; } // build pdu request.pdu.pduValue.trap.genericTrap = genericTrap; request.pdu.pduValue.trap.specificTrap = specificTrap; request.pdu.pduValue.trap.timeStamp = timeStamp; request.pdu.pduValue.trap.varBinds.list = variableBindings->list; request.pdu.pduValue.trap.varBinds.len = variableBindings->len; // check if default enterprise oid has been overridden if (enterprise && enterprise->idLength && enterprise->ids) { request.pdu.pduValue.trap.enterprise.idLength = enterprise->idLength; request.pdu.pduValue.trap.enterprise.ids = enterprise->ids; } else { request.pdu.pduValue.trap.enterprise.idLength = g_enterprise->idLength; request.pdu.pduValue.trap.enterprise.ids = g_enterprise->ids; } for (i=0; i<trapDestsLen; i++) { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: processing trap destinations for community %s.\n", trapDests[i].communityName)); for (j=0; j<trapDests[i].addrLen; j++) { request.community.stream = trapDests[i].communityName; request.community.length = strlen(trapDests[i].communityName); request.community.dynamic = FALSE; switch (trapDests[i].addrList[j].addrEncoding.sa_family) { case AF_INET: { struct sockaddr_in destAddress_in; struct servent *serv; if (fd_inet == (SOCKET)-1) // don't have an IP socket { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send udp trap because no socket available.\n")); continue; } destAddress_in.sin_family = AF_INET; if ((serv = getservbyname( "snmp-trap", "udp" )) == NULL) { destAddress_in.sin_port = htons(162); } else { destAddress_in.sin_port = (SHORT)serv->s_port; } destAddress_in.sin_addr.s_addr = ((struct sockaddr_in *)(&trapDests[i].addrList[j].addrEncoding))->sin_addr.s_addr; SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: processing ip trap destination %u.%u.%u.%u.\n", destAddress_in.sin_addr.S_un.S_un_b.s_b1, destAddress_in.sin_addr.S_un.S_un_b.s_b2, destAddress_in.sin_addr.S_un.S_un_b.s_b3, destAddress_in.sin_addr.S_un.S_un_b.s_b4)); bcopy(&destAddress_in, &dest, sizeof(destAddress_in)); } // include local agent addr in pdu (ip only) request.pdu.pduValue.trap.agentAddr.stream = (BYTE *)&((struct sockaddr_in *)(&mysocket))->sin_addr.s_addr; request.pdu.pduValue.trap.agentAddr.length = 4; fd = fd_inet; break; case AF_IPX: { SOCKADDR_IPX *pdest = (SOCKADDR_IPX *) &dest; if (fd_ipx == (SOCKET)-1) // don't have an IPX socket { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send ipx trap because no socket available.\n")); continue; } // sa_family, sa_netnum, and sa_nodenum are already set bcopy(&trapDests[i].addrList[j].addrEncoding, &dest, sizeof(SOCKADDR_IPX)); pdest->sa_socket = htons(WKSN_IPX_TRAP); dp_ipx(SNMP_LOG_TRACE, "SNMP: TRAP: processing ipx trap destination ", pdest, ".\n"); } // include empty agent addr in pdu (ipx only) request.pdu.pduValue.trap.agentAddr.stream = (BYTE *)&nul_s_addr; request.pdu.pduValue.trap.agentAddr.length = 4; fd = fd_ipx; break; default: { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send trap because sa_family invalid.\n")); continue; } } pBuf = NULL; length = 0; if (!SnmpSvcEncodeMessage(ASN_SEQUENCE, &request, &pBuf, &length)) { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpSvcEncodeMessage %d.\n", GetLastError())); SnmpUtilMemFree(pBuf); continue; } // transmit trap pdu if ((length = sendto(fd, pBuf, length, 0, &dest, sizeof(dest))) == -1) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d sending trap.\n", GetLastError())); //a serious error? } else { SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: trap sent successfully.\n")); } SnmpUtilMemFree(pBuf); } // end for () } // end for () SnmpUtilVarBindListFree(variableBindings); // release mutex if (!ReleaseMutex(hGenerateTrapMutex)) { SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d releasing trap generation mutex.\n", GetLastError())); return FALSE; } return TRUE; } // end SnmpSvcGenerateTrap()
// 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()
void _php3_snmp(INTERNAL_FUNCTION_PARAMETERS, int st) { pval *a1, *a2, *a3; INT operation; LPSTR agent; LPSTR community; RFC1157VarBindList variableBindings; LPSNMP_MGR_SESSION session; INT timeout = TIMEOUT; INT retries = RETRIES; BYTE requestType; AsnInteger errorStatus; AsnInteger errorIndex; AsnObjectIdentifier oid; char *chkPtr = NULL; if (getParameters(ht, 3, &a1, &a2, &a3) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(a1); convert_to_string(a2); convert_to_string(a3); agent=a1->value.str.val; community=a2->value.str.val; operation=st; SnmpMgrStrToOid(a3->value.str.val, &oid); /* I've limited this to only one oid, but we can create a list of oid's here, and expand the function to take multiple oid's */ variableBindings.list->name = oid; variableBindings.list->value.asnType = ASN_NULL; variableBindings.len = 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){ php_error(E_WARNING,"error on SnmpMgrOpen %d\n", GetLastError()); } /* 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. */ php_error(E_WARNING,"error on SnmpMgrRequest %d\n", GetLastError()); } else { /* The API succeeded, errors may be indicated from the remote agent. */ if (errorStatus > 0){ php_error(E_WARNING,"Error: errorStatus=%d, errorIndex=%d\n", errorStatus, errorIndex); } else { /* Display the resulting variable bindings.*/ UINT i; char *str = NULL; for(i=0; i < variableBindings.len; i++) { SnmpMgrOidToStr(&variableBindings.list[i].name, &str); php_printf("Variable = %s\n", str); if (str) SNMP_free(str); php_printf("Value = "); SnmpUtilPrintAsnAny(&variableBindings.list[i].value); php_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.*/ php_error(E_WARNING,"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)) { PUTS("End of MIB subtree.\n\n"); break; } /* Test for general error conditions or sucesss. */ if (errorStatus > 0){ php_error(E_ERROR,"Error: errorStatus=%d, errorIndex=%d \n", errorStatus, errorIndex); break; } else { /* Display resulting variable binding for this iteration. */ char *str = NULL; SnmpMgrOidToStr(&variableBindings.list[0].name, &str); php_printf("Variable = %s\n", str); if (str) SNMP_free(str); php_printf("Value = "); SnmpUtilPrintAsnAny(&variableBindings.list[0].value); php_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); } /* end if (operation) */ /* Close SNMP session with the remote agent.*/ if (!SnmpMgrClose(session)){ php_error(E_WARNING,"error on SnmpMgrClose %d\n", GetLastError()); } }