void initvl() { UINT i; UINT j; UINT temp; // allocate an index for each registered subagent vl = (INT *)SnmpUtilMemAlloc(extAgentsLen * sizeof(INT)); // flag only if properly initialized for(i=0, vlLen=0; i < (UINT)extAgentsLen; i++) { if (extAgents[i].fInitedOk) { vl[vlLen++] = i; } } // sort these indexes... for(i=0; i < vlLen; i++) { for(j=i + 1; j < vlLen; j++) { // if item[i] > item[j] if (0 < SnmpUtilOidCmp( &(extAgents[vl[i]].supportedView), &(extAgents[vl[j]].supportedView))) { temp = vl[i]; vl[i] = vl[j]; vl[j] = temp; } } } } // end initvl()
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()
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()
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()
// // MIB_odom_lmget // Retrieve print queue table information from Lan Manager. // If not cached, sort it and then // cache it. // // Notes: // // Return Codes: // SNMPAPI_NOERROR // SNMPAPI_ERROR // // Error Codes: // None. // SNMPAPI MIB_odoms_lmget( ) { DWORD totalentries; LPBYTE bufptr; unsigned lmCode; WKSTA_USER_INFO_1 *DataTable; DOM_OTHER_ENTRY *MIB_DomOtherDomainTableElement ; char *p; char *next; time_t curr_time ; unsigned i; SNMPAPI nResult = SNMPAPI_NOERROR; time(&curr_time); // get the time // // // If cached, return piece of info. // // if((NULL != cache_table[C_ODOM_TABLE].bufptr) && (curr_time < (cache_table[C_ODOM_TABLE].acquisition_time + cache_expire[C_ODOM_TABLE] ) ) ) { // it has NOT expired! goto Exit; // the global table is valid } // // // Do network call to gather information and put it in a nice array // // // // remember to free the existing data // MIB_DomOtherDomainTableElement = MIB_DomOtherDomainTable.Table ; // iterate over the whole table for(i=0; i<MIB_DomOtherDomainTable.Len ;i++) { // free any alloc'ed elements of the structure SnmpUtilOidFree(&(MIB_DomOtherDomainTableElement->Oid)); SafeFree(MIB_DomOtherDomainTableElement->domOtherName.stream); MIB_DomOtherDomainTableElement ++ ; // increment table entry } SafeFree(MIB_DomOtherDomainTable.Table) ; // free the base Table MIB_DomOtherDomainTable.Table = NULL ; // just for safety MIB_DomOtherDomainTable.Len = 0 ; // just for safety lmCode = NetWkstaUserGetInfo( 0, // required 1, // level 0, &bufptr // data structure to return ); DataTable = (WKSTA_USER_INFO_1 *) bufptr ; if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode)) { // valid so process it, otherwise error if(NULL==DataTable->wkui1_oth_domains) { totalentries = 0; // alloc the table space MIB_DomOtherDomainTable.Table = SnmpUtilMemAlloc(totalentries * sizeof(DOM_OTHER_ENTRY) ); } else { // compute it totalentries = chrcount((char *)DataTable->wkui1_oth_domains); if(0 == MIB_DomOtherDomainTable.Len) { // 1st time, alloc the whole table // alloc the table space MIB_DomOtherDomainTable.Table = SnmpUtilMemAlloc(totalentries * sizeof(DOM_OTHER_ENTRY) ); } MIB_DomOtherDomainTableElement = MIB_DomOtherDomainTable.Table ; // make a pointer to the beginning of the string field #ifdef UNICODE SnmpUtilUnicodeToAnsi( &p, DataTable->wkui1_oth_domains, TRUE); #else p = DataTable->wkui1_oth_domains ; #endif // scan through the field, making an entry for each space // separated domain while( (NULL != p ) & ('\0' != *p) ) { // once for each entry in the buffer // increment the entry number MIB_DomOtherDomainTable.Len ++; // find the end of this one next = strchr(p,' '); // if more to come, ready next pointer and mark end of this one if(NULL != next) { *next='\0' ; // replace space with EOS next++ ; // point to beginning of next domain } MIB_DomOtherDomainTableElement->domOtherName.stream = SnmpUtilMemAlloc ( strlen( p ) ) ; MIB_DomOtherDomainTableElement->domOtherName.length = strlen( p ) ; MIB_DomOtherDomainTableElement->domOtherName.dynamic = TRUE; memcpy( MIB_DomOtherDomainTableElement->domOtherName.stream, p, strlen( p ) ) ; MIB_DomOtherDomainTableElement ++ ; // and table entry DataTable ++ ; // advance pointer to next sess entry in buffer } // while still more to do } // if there really were entries } // if data is valid to process else { // Signal error nResult = SNMPAPI_ERROR; goto Exit; } // free all of the lan man data SafeBufferFree( bufptr ) ; // iterate over the table populating the Oid field build_odom_entry_oids(); // Sort the table information using MSC QuickSort routine qsort( (void *)&MIB_DomOtherDomainTable.Table[0], (size_t)MIB_DomOtherDomainTable.Len, (size_t)sizeof(DOM_OTHER_ENTRY), odom_entry_cmp ); // // // Cache table // // if(0 != MIB_DomOtherDomainTable.Len) { cache_table[C_ODOM_TABLE].acquisition_time = curr_time ; cache_table[C_ODOM_TABLE].bufptr = bufptr ; } // // // Return piece of information requested // // Exit: return nResult; } // MIB_odom_get
// // MIB_odoms_lmset // Perform the necessary actions to set an entry in the Other Domain Table. // // Notes: // // Return Codes: // // Error Codes: // None. // UINT MIB_odoms_lmset( IN AsnObjectIdentifier *Index, IN UINT Field, IN AsnAny *Value ) { LPBYTE bufptr = NULL; WKSTA_USER_INFO_1101 ODom; LPBYTE Temp; UINT Entry; UINT I; UINT ErrStat = SNMP_ERRORSTATUS_NOERROR; #ifdef UNICODE LPWSTR unitemp ; #endif // Must make sure the table is in memory if ( SNMPAPI_ERROR == MIB_odoms_lmget() ) { ErrStat = SNMP_ERRORSTATUS_GENERR; goto Exit; } // See if match in table if ( MIB_TBL_POS_FOUND == MIB_odoms_match(Index, &Entry) ) { // If empty string then delete entry if ( Value->asnValue.string.length == 0 ) { // Alloc memory for buffer bufptr = SnmpUtilMemAlloc( DNLEN * sizeof(char) * (MIB_DomOtherDomainTable.Len-1) + MIB_DomOtherDomainTable.Len-1 ); // Create the other domain string Temp = bufptr; for ( I=0;I < MIB_DomOtherDomainTable.Len;I++ ) { if ( I+1 != Entry ) { memcpy( Temp, MIB_DomOtherDomainTable.Table[I].domOtherName.stream, MIB_DomOtherDomainTable.Table[I].domOtherName.length ); Temp[MIB_DomOtherDomainTable.Table[I].domOtherName.length] = ' '; Temp += MIB_DomOtherDomainTable.Table[I].domOtherName.length + 1; } } *(Temp-1) = '\0'; } else { // Cannot modify the domain entries, so bad value ErrStat = SNMP_ERRORSTATUS_BADVALUE; goto Exit; } } else { // Check for addition of NULL string, bad value if ( Value->asnValue.string.length == 0 ) { ErrStat = SNMP_ERRORSTATUS_BADVALUE; goto Exit; } // // Entry doesn't exist so add it to the list // // Alloc memory for buffer bufptr = SnmpUtilMemAlloc( DNLEN * sizeof(char) * (MIB_DomOtherDomainTable.Len+1) + MIB_DomOtherDomainTable.Len+1 ); // Create the other domain string Temp = bufptr; for ( I=0;I < MIB_DomOtherDomainTable.Len;I++ ) { memcpy( Temp, MIB_DomOtherDomainTable.Table[I].domOtherName.stream, MIB_DomOtherDomainTable.Table[I].domOtherName.length ); Temp[MIB_DomOtherDomainTable.Table[I].domOtherName.length] = ' '; Temp += MIB_DomOtherDomainTable.Table[I].domOtherName.length + 1; } // Add new entry memcpy( Temp, Value->asnValue.string.stream, Value->asnValue.string.length ); // Add NULL terminator Temp[Value->asnValue.string.length] = '\0'; } // Set table and check return codes #ifdef UNICODE SnmpUtilAnsiToUnicode( &unitemp, bufptr, TRUE ); ODom.wkui1101_oth_domains = unitemp; #else ODom.wkui1101_oth_domains = bufptr; #endif #if 0 if ( NERR_Success == NetWkstaUserSetInfo(NULL, 1101, (LPBYTE)&ODom, NULL) ) { // Make cache be reloaded next time cache_table[C_ODOM_TABLE].bufptr = NULL; } else { ErrStat = SNMP_ERRORSTATUS_GENERR; } #else ErrStat = SNMP_ERRORSTATUS_GENERR; #endif Exit: SnmpUtilMemFree( bufptr ); return ErrStat; } // MIB_odoms_lmset
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; }
// // MIB_user_lmget // Retrieve print queue table information from Lan Manager. // If not cached, sort it and then // cache it. // // Notes: // // Return Codes: // SNMPAPI_NOERROR // SNMPAPI_ERROR // // Error Codes: // None. // SNMPAPI MIB_users_lmget( ) { DWORD entriesread; DWORD totalentries; LPBYTE bufptr; unsigned lmCode; unsigned i; USER_INFO_0 *DataTable; USER_ENTRY *MIB_UserTableElement ; int First_of_this_block; LPSTR ansi_string; time_t curr_time ; SNMPAPI nResult = SNMPAPI_NOERROR; DWORD resumehandle=0; time(&curr_time); // get the time // // // If cached, return piece of info. // // if((NULL != cache_table[C_USER_TABLE].bufptr) && (curr_time < (cache_table[C_USER_TABLE].acquisition_time + cache_expire[C_USER_TABLE] ) ) ) { // it has NOT expired! goto Exit ; // the global table is valid } // // // Do network call to gather information and put it in a nice array // // // // remember to free the existing data // MIB_UserTableElement = MIB_UserTable.Table ; // iterate over the whole table for(i=0; i<MIB_UserTable.Len ;i++) { // free any alloc'ed elements of the structure SnmpUtilOidFree(&(MIB_UserTableElement->Oid)); SafeFree(MIB_UserTableElement->svUserName.stream); MIB_UserTableElement ++ ; // increment table entry } SafeFree(MIB_UserTable.Table) ; // free the base Table MIB_UserTable.Table = NULL ; // just for safety MIB_UserTable.Len = 0 ; // just for safety #if 0 // done above // init the length MIB_UserTable.Len = 0; #endif First_of_this_block = 0; do { // as long as there is more data to process lmCode = NetUserEnum( NULL, // local server 0, // level 0, no admin priv. FILTER_NORMAL_ACCOUNT, &bufptr, // data structure to return MAX_PREFERRED_LENGTH, &entriesread, &totalentries, &resumehandle // resume handle ); DataTable = (USER_INFO_0 *) bufptr ; if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode)) { // valid so process it, otherwise error if(0 == MIB_UserTable.Len) { // 1st time, alloc the whole table // alloc the table space MIB_UserTable.Table = SnmpUtilMemAlloc(totalentries * sizeof(USER_ENTRY) ); } MIB_UserTableElement = MIB_UserTable.Table + First_of_this_block ; for(i=0; i<entriesread; i++) { // once for each entry in the buffer // increment the entry number MIB_UserTable.Len ++; // Stuff the data into each item in the table // convert the undocumented unicode to something readable SnmpUtilUnicodeToAnsi( &ansi_string, DataTable->usri0_name, TRUE ); // auto alloc the space for ansi // client name MIB_UserTableElement->svUserName.stream = ansi_string; MIB_UserTableElement->svUserName.length = strlen( ansi_string ) ; MIB_UserTableElement->svUserName.dynamic = TRUE; ansi_string = NULL; MIB_UserTableElement ++ ; // and table entry DataTable ++ ; // advance pointer to next sess entry in buffer } // for each entry in the data table // free all of the lan man data SafeBufferFree( bufptr ) ; // indicate where to start adding on next pass, if any First_of_this_block = i ; } // if data is valid to process else { // Signal error nResult = SNMPAPI_ERROR; goto Exit; } } while (ERROR_MORE_DATA == lmCode) ; // iterate over the table populating the Oid field build_user_entry_oids(); // Sort the table information using MSC QuickSort routine qsort( &MIB_UserTable.Table[0], MIB_UserTable.Len, sizeof(USER_ENTRY), user_entry_cmp ); // // // Cache table // // if(0 != MIB_UserTable.Len) { cache_table[C_USER_TABLE].acquisition_time = curr_time ; cache_table[C_USER_TABLE].bufptr = bufptr ; } // // // Return piece of information requested // // Exit: return nResult; } // MIB_user_get
BOOL SnmpExtensionTrap( OUT AsnObjectIdentifier *enterprise, OUT AsnInteger *genericTrap, OUT AsnInteger *specificTrap, OUT AsnTimeticks *timeStamp, OUT RFC1157VarBindList *variableBindings) { // The body of this routine is an extremely simple example/simulation of // the trap functionality. A real implementation will be more complex. // The following define data inserted into the trap below. The Lan Manager // bytesAvailAlert from the Lan Manager Alerts-2 MIB is generated with an // empty variable bindings list. static UINT OidList[] = { 1, 3, 6, 1, 4, 1, 311, 2 }; static UINT OidListLen = 8; // The following variable is used for the simulation, it allows a single // trap to be generated and then causes FALSE to be returned indicating // no more traps. static whichTime = 0; // The following if/else support the simulation. if (whichTime == 0) { whichTime = 1; // Supports the simulation. // Communicate the trap data to the Extendible Agent. enterprise->idLength = OidListLen; enterprise->ids = (UINT *)SnmpUtilMemAlloc(sizeof(UINT) * OidListLen); memcpy(enterprise->ids, OidList, sizeof(UINT) * OidListLen); *genericTrap = SNMP_GENERICTRAP_ENTERSPECIFIC; *specificTrap = 1; // the bytesAvailAlert trap *timeStamp = GetCurrentTime() - dwTimeZero; variableBindings->list = NULL; variableBindings->len = 0; // Indicate that valid trap data exists in the parameters. return TRUE; } else { whichTime = 0; // Supports the simulation. // Indicate that no more traps are available and parameters do not // refer to any valid data. return FALSE; } } // end SnmpExtensionTrap()
// // MIB_sess_copyfromtable // Copy requested data from table structure into Var Bind. // // Notes: // // Return Codes: // None. // // Error Codes: // None. // UINT MIB_sess_copyfromtable( IN UINT Entry, IN UINT Field, OUT RFC1157VarBind *VarBind ) { UINT ErrStat; // Get the requested field and save in var bind switch( Field ) { case SESS_CLIENT_FIELD: // Alloc space for string VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char) * MIB_SessionTable.Table[Entry].svSesClientName.length ); if ( VarBind->value.asnValue.string.stream == NULL ) { ErrStat = SNMP_ERRORSTATUS_GENERR; goto Exit; } // Copy string into return position memcpy( VarBind->value.asnValue.string.stream, MIB_SessionTable.Table[Entry].svSesClientName.stream, MIB_SessionTable.Table[Entry].svSesClientName.length ); // Set string length VarBind->value.asnValue.string.length = MIB_SessionTable.Table[Entry].svSesClientName.length; VarBind->value.asnValue.string.dynamic = TRUE; // Set type of var bind VarBind->value.asnType = ASN_RFC1213_DISPSTRING; break; case SESS_USER_FIELD: // Alloc space for string VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char) * MIB_SessionTable.Table[Entry].svSesUserName.length ); if ( VarBind->value.asnValue.string.stream == NULL ) { ErrStat = SNMP_ERRORSTATUS_GENERR; goto Exit; } // Copy string into return position memcpy( VarBind->value.asnValue.string.stream, MIB_SessionTable.Table[Entry].svSesUserName.stream, MIB_SessionTable.Table[Entry].svSesUserName.length ); // Set string length VarBind->value.asnValue.string.length = MIB_SessionTable.Table[Entry].svSesUserName.length; VarBind->value.asnValue.string.dynamic = TRUE; // Set type of var bind VarBind->value.asnType = ASN_RFC1213_DISPSTRING; break; case SESS_NUMCONS_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesNumConns; VarBind->value.asnType = ASN_INTEGER; break; case SESS_NUMOPENS_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesNumOpens; VarBind->value.asnType = ASN_INTEGER; break; case SESS_TIME_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesTime; VarBind->value.asnType = ASN_RFC1155_COUNTER; break; case SESS_IDLETIME_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesIdleTime; VarBind->value.asnType = ASN_RFC1155_COUNTER; break; case SESS_CLIENTTYPE_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesClientType; VarBind->value.asnType = ASN_INTEGER; break; case SESS_STATE_FIELD: VarBind->value.asnValue.number = MIB_SessionTable.Table[Entry].svSesState; VarBind->value.asnType = ASN_INTEGER; break; default: SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Internal Error Session Table\n" )); ErrStat = SNMP_ERRORSTATUS_GENERR; goto Exit; } ErrStat = SNMP_ERRORSTATUS_NOERROR; Exit: return ErrStat; } // MIB_sess_copyfromtable
// // MIB_dlog_lmget // Retrieve dlogion table information from Lan Manager. // If not cached, sort it and then // cache it. // // Notes: // // Return Codes: // SNMPAPI_NOERROR // SNMPAPI_ERROR // // Error Codes: // None. // SNMPAPI MIB_dlogons_lmget( ) { SNMPAPI nResult = SNMPAPI_NOERROR; #if 0 DWORD entriesread; DWORD totalentries; LPBYTE bufptr; unsigned lmCode; unsigned i; SHARE_INFO_2 *DataTable; DOM_LOGON_ENTRY *MIB_DomLogonTableElement ; int First_of_this_block; DWORD resumehandle=0; // // // If cached, return piece of info. // // // // // Do network call to gather information and put it in a nice array // // // free the old table LOOK OUT!! // init the length MIB_DomLogonTable.Len = 0; First_of_this_block = 0; do { // as long as there is more data to process lmCode = NetShareEnum(NULL, // local server 2, // level 2, &bufptr, // data structure to return MAX_PREFERRED_LENGTH, &entriesread, &totalentries, &resumehandle // resume handle ); // // Filter out all the Admin shares (name ending with $). // AdminFilter(2,&entriesread,bufptr); DataTable = (SHARE_INFO_2 *) bufptr ; if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode)) { // valid so process it, otherwise error if(0 == MIB_DomLogonTable.Len) { // 1st time, alloc the whole table // alloc the table space MIB_DomLogonTable.Table = SnmpUtilMemAlloc(totalentries * sizeof(DOM_LOGON_ENTRY) ); } MIB_DomLogonTableElement = MIB_DomLogonTable.Table + First_of_this_block ; for(i=0; i<entriesread; i++) { // once for each entry in the buffer // increment the entry number MIB_DomLogonTable.Len ++; // Stuff the data into each item in the table // dloge name MIB_DomLogonTableElement->svShareName.stream = SnmpUtilMemAlloc ( strlen( DataTable->shi2_netname ) ) ; MIB_DomLogonTableElement->svShareName.length = strlen( DataTable->shi2_netname ) ; MIB_DomLogonTableElement->svShareName.dynamic = TRUE; memcpy( MIB_DomLogonTableElement->svShareName.stream, DataTable->shi2_netname, strlen( DataTable->shi2_netname ) ) ; // Share Path MIB_DomLogonTableElement->svSharePath.stream = SnmpUtilMemAlloc ( strlen( DataTable->shi2_path ) ) ; MIB_DomLogonTableElement->svSharePath.length = strlen( DataTable->shi2_path ) ; MIB_DomLogonTableElement->svSharePath.dynamic = TRUE; memcpy( MIB_DomLogonTableElement->svSharePath.stream, DataTable->shi2_path, strlen( DataTable->shi2_path ) ) ; // Share Comment/Remark MIB_DomLogonTableElement->svShareComment.stream = SnmpUtilMemAlloc ( strlen( DataTable->shi2_remark ) ) ; MIB_DomLogonTableElement->svShareComment.length = strlen( DataTable->shi2_remark ) ; MIB_DomLogonTableElement->svShareComment.dynamic = TRUE; memcpy( MIB_DomLogonTableElement->svShareComment.stream, DataTable->shi2_remark, strlen( DataTable->shi2_remark ) ) ; DataTable ++ ; // advance pointer to next dlog entry in buffer MIB_DomLogonTableElement ++ ; // and table entry } // for each entry in the data table // indicate where to start adding on next pass, if any First_of_this_block = i ; } // if data is valid to process else { // Signal error nResult = SNMPAPI_ERROR; goto Exit; } } while (ERROR_MORE_DATA == lmCode) ; // iterate over the table populating the Oid field build_dlog_entry_oids(); // Sort the table information using MSC QuickSort routine qsort( &MIB_DomLogonTable.Table[0], MIB_DomLogonTable.Len, sizeof(DOM_LOGON_ENTRY), dlog_entry_cmp ); // // // Cache table // // // // // Return piece of information requested // // Exit: #endif return nResult; } // MIB_dlog_get
// 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()