/*++ Copyright (c) 1996 Microsoft Corporation Module Name: mibfuncs.c Abstract: Sample subagent instrumentation callbacks. --*/ #include "precomp.h" #pragma hdrstop DWORD ConnectToRouter(); DWORD UpdateGlobalInfo( IN AsnAny * objectArray ); DWORD GetGlobalConfigInfo( OUT PIPBOOTP_MIB_GET_OUTPUT_DATA * ppimgod, OUT PDWORD pdwSize ); DWORD UpdateBOOTPServerTable( IN sav_globalBOOTPServerEntry * psgbse ); DWORD AddBOOTPServerEntry( IN DWORD dwServerAddr, IN PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData ); DWORD DeleteBOOTPServerEntry( IN DWORD dwIndex, IN PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData ); DWORD GetInterfaceInfo( IN UINT actionId, IN PIPBOOTP_MIB_GET_INPUT_DATA pimgidInData, OUT PIPBOOTP_MIB_GET_OUTPUT_DATA* ppimgod, OUT PDWORD pdwOutSize ); DWORD ValidateInterfaceConfig( IN AsnAny * objectArray ); DWORD SetInterfaceConfig( IN AsnAny * objectArray ); /////////////////////////////////////////////////////////////////////////////// // // // global group (1.3.6.1.4.1.311.1.12.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_global( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwConfigSize = 0; buf_global* pbgBuffer = NULL; PIPBOOTP_GLOBAL_CONFIG pigcGlbConfig = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodConfigData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( "get_global" ); switch ( actionId ) { case MIB_ACTION_GET: case MIB_ACTION_GETFIRST: // // Retrieve global config. // imgidInData.IMGID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; BOOTP_MIB_GET( &imgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodConfigData, &dwConfigSize, dwRes ); break; case MIB_ACTION_GETNEXT: default: TRACE1( "Wrong Action", actionId ); return MIB_S_INVALID_PARAMETER; } // // if error print error message and free allocations // if ( dwRes != NO_ERROR ) { TraceError( dwRes ); if ( pimgodConfigData ) { MprAdminMIBBufferFree ( pimgodConfigData ); } return dwRes; } // // Set the return data. // pbgBuffer = (buf_global*) objectArray; // // Global config Data // pigcGlbConfig = (PIPBOOTP_GLOBAL_CONFIG) pimgodConfigData-> IMGOD_Buffer; SetAsnInteger( &( pbgBuffer-> globalMaxRecQueueSize ), pigcGlbConfig-> GC_MaxRecvQueueSize ); SetAsnInteger( &( pbgBuffer-> globalServerCount ), pigcGlbConfig-> GC_ServerCount ); // // +1 added to adjust value to enumeration values in asn. // Enumeration in asn cannot have a value of 0. Causes a warning // to be generated by the asn compiler. // SetAsnInteger( &(pbgBuffer-> globalLoggingLevel), pigcGlbConfig-> GC_LoggingLevel + 1 ); if ( pimgodConfigData ) { MprAdminMIBBufferFree ( pimgodConfigData ); } TraceLeave( "get_global" ); return MIB_S_SUCCESS; } UINT set_global( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = MIB_S_SUCCESS, dwLogLevel = 0; sav_global* psgBuffer = NULL; TraceEnter( "set_global" ); dwRes = MIB_S_SUCCESS; switch ( actionId ) { case MIB_ACTION_VALIDATE : psgBuffer = (sav_global *) objectArray; // // verify log level setting // dwLogLevel = GetAsnInteger( &( psgBuffer-> globalLoggingLevel ), 0 ); if ( dwLogLevel < d_globalLoggingLevel_none || dwLogLevel > d_globalLoggingLevel_information ) { dwRes = MIB_S_INVALID_PARAMETER; TRACE1( "Invalid logging level value : %d", dwLogLevel ); } break; case MIB_ACTION_SET : dwRes = UpdateGlobalInfo( objectArray ); break; case MIB_ACTION_CLEANUP : dwRes = MIB_S_SUCCESS; break; default : dwRes = MIB_S_INVALID_PARAMETER; TRACE1( "Invalid action specified : %d", actionId ); break; } TraceEnter( "set_global" ); return dwRes; } /////////////////////////////////////////////////////////////////////////////// // // // globalBOOTPServerEntry table (1.3.6.1.4.1.311.1.12.1.4.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_globalBOOTPServerEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwCurrentAddr = INADDR_NONE, dwIndex = 0, dwGetSize = 0, dwSetSize = 0; PDWORD pdwAddrTable= NULL; buf_globalBOOTPServerEntry * pbgbse = NULL; PIPBOOTP_GLOBAL_CONFIG pigc = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsidInData= NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( "get_globalBOOTPServerEntry" ); pbgbse = (buf_globalBOOTPServerEntry *) objectArray; // // retrive the BOOTP server table // imgidInData.IMGID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; BOOTP_MIB_GET( &imgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodOutData, &dwGetSize, dwRes ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); return dwRes; } pigc = (PIPBOOTP_GLOBAL_CONFIG) pimgodOutData-> IMGOD_Buffer; if ( !pigc-> GC_ServerCount ) { TRACE0( "No BOOTP Server Entries" ); return MIB_S_NO_MORE_ENTRIES; } pdwAddrTable = IPBOOTP_GLOBAL_SERVER_TABLE( pigc ); // // Locate current entry in global server table // dwCurrentAddr = GetAsnIPAddress( &( pbgbse-> globalBOOTPServerAddr ), 0 ); FIND_SERVER_ENTRY( dwCurrentAddr, pigc-> GC_ServerCount, pdwAddrTable, dwIndex ); // // get requested entry // dwRes = MIB_S_SUCCESS; switch ( actionId ) { case MIB_ACTION_GET : // // This is an idempotent case, since retieving a server address // requires the server address as index. // It is only useful to verify the presence of a particular server. // if ( dwIndex >= pigc-> GC_ServerCount ) { dwRes = MIB_S_ENTRY_NOT_FOUND; TRACE0( "BOOTP Server Entry not found" ); } break; case MIB_ACTION_GETFIRST : // // get entry at index 0 (if available ) // dwIndex = 0; if ( !pigc-> GC_ServerCount ) { dwRes = MIB_S_ENTRY_NOT_FOUND; TRACE0( "BOOTP Server Entry not found" ); } break; case MIB_ACTION_GETNEXT : // // check if entry was found. // dwCurrentAddr == 0 is taken to mean that the next server entry // starting from the beginning of the table is requested. // if ( ( dwIndex >= pigc-> GC_ServerCount ) && ( dwCurrentAddr != 0 ) ) { dwRes = MIB_S_ENTRY_NOT_FOUND; TRACE0( "BOOTP Server Entry not found" ); break; } // // try and get next // dwIndex = ( dwCurrentAddr ) ? dwIndex++ : 0; TRACE3( "GET_NEXT : Current addr : %x, server index : %d, Server count : %d", dwCurrentAddr, dwIndex, pigc-> GC_ServerCount ); if ( dwIndex >= pigc-> GC_ServerCount ) { dwRes = MIB_S_NO_MORE_ENTRIES; TRACE0( "No more BOOTP Server Entries" ); break; } break; default : TRACE0( " get_globalServerEntry - Wrong Action " ); dwRes = MIB_S_INVALID_PARAMETER; break; } // // set index for next retrieval // if ( dwRes == MIB_S_SUCCESS ) { ForceSetAsnIPAddress( &( pbgbse-> globalBOOTPServerAddr ), &( pbgbse-> dwServerAddr ), pdwAddrTable[ dwIndex ] ); } if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } TraceLeave( "get_globalBOOTPServerCount" ); return dwRes; } UINT set_globalBOOTPServerEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwAddr = INADDR_NONE, dwOp = 0; sav_globalBOOTPServerEntry * psgbse = NULL; TraceEnter( "set_globalBOOTPServerEntry" ); psgbse = (sav_globalBOOTPServerEntry *) objectArray; switch ( actionId ) { case MIB_ACTION_VALIDATE : // // Verify if the specified IP address is valid. // dwAddr = GetAsnIPAddress( &( psgbse-> globalBOOTPServerAddr ), INADDR_NONE ); if ( !dwAddr || dwAddr == INADDR_NONE ) { dwRes = MIB_S_INVALID_PARAMETER; TRACE0( " Invalid Server address specified" ); } // // Verify operation tag // dwRes = GetAsnInteger( &( psgbse-> globalBOOTPServerTag ), 0 ); if ( dwRes != d_globalBOOTPServerTag_create && dwRes != d_globalBOOTPServerTag_delete ) { dwRes = MIB_S_INVALID_PARAMETER; TRACE0( " Invalid Operation specified" ); break; } dwRes = MIB_S_SUCCESS; break; case MIB_ACTION_SET : dwRes = UpdateBOOTPServerTable( psgbse ); break; case MIB_ACTION_CLEANUP : dwRes = MIB_S_SUCCESS; break; default : dwRes = MIB_S_INVALID_PARAMETER; TRACE0 ( " set_globalBOOTPServerEntry - Wrong Action " ); break; } TraceLeave( " set_globalBOOTPServerEntry " ); return dwRes; } /////////////////////////////////////////////////////////////////////////////// // // // interface group (1.3.6.1.4.1.311.1.12.2) // // // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // // // ifStatsEntry table (1.3.6.1.4.1.311.1.12.2.1.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_ifStatsEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwGetSize = 0, dwSetSize = 0; buf_ifStatsEntry * pbifse = NULL; PIPBOOTP_IF_STATS piis = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( "get_ifStatsEntry" ); // // Retrieve Specified interface info. // pbifse = (buf_ifStatsEntry*) objectArray; imgidInData.IMGID_TypeID = IPBOOTP_IF_STATS_ID; imgidInData.IMGID_IfIndex = GetAsnInteger( &( pbifse-> ifSEIndex ), 0 ); // // When walking the mib using a sequence of getnext operations // the first getnext operation is translated into a getfirst // operation. // if ( actionId == MIB_ACTION_GETNEXT && !imgidInData.IMGID_IfIndex ) { actionId = MIB_ACTION_GETFIRST; } dwRes = GetInterfaceInfo( actionId, &imgidInData, &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); return dwRes; } // // Set interface stats in return buffer // piis = (PIPBOOTP_IF_STATS) (pimgodOutData-> IMGOD_Buffer); SetAsnInteger( &( pbifse-> ifSEState ), piis-> IS_State ); SetAsnCounter( &( pbifse-> ifSESendFailures ), piis-> IS_SendFailures ); SetAsnCounter( &( pbifse-> ifSEReceiveFailures ), piis-> IS_ReceiveFailures ); SetAsnCounter( &( pbifse-> ifSEArpUpdateFailures ), piis-> IS_ArpUpdateFailures ); SetAsnCounter( &( pbifse-> ifSERequestReceiveds ), piis-> IS_RequestsReceived ); SetAsnCounter( &( pbifse-> ifSERequestDiscards ), piis-> IS_RequestsDiscarded ); SetAsnCounter( &( pbifse-> ifSEReplyReceiveds ), piis-> IS_RepliesReceived ); SetAsnCounter( &( pbifse-> ifSEReplyDiscards ), piis-> IS_RepliesDiscarded ); // // set index for following getnext operation, (if any) // ForceSetAsnInteger( &( pbifse-> ifSEIndex ), pimgodOutData-> IMGOD_IfIndex ); if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } TraceLeave( "get_ifStatsEntry" ); return MIB_S_SUCCESS ; } /////////////////////////////////////////////////////////////////////////////// // // // ifConfigEntry table (1.3.6.1.4.1.311.1.12.2.2.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_ifConfigEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwGetSize = 0; buf_ifConfigEntry* pbifce = NULL; PIPBOOTP_IF_CONFIG piic = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( " get_ifConfigEntry " ); // // retrieve interface config. // pbifce = (buf_ifConfigEntry*) objectArray; imgidInData.IMGID_TypeID = IPBOOTP_IF_CONFIG_ID; imgidInData.IMGID_IfIndex = GetAsnInteger( &( pbifce-> ifCEIndex ), 0 ); // // When walking the mib using a sequence of getnext operations // the first getnext operation is translated into a getfirst // operation. // if ( actionId == MIB_ACTION_GETNEXT && !imgidInData.IMGID_IfIndex ) { actionId = MIB_ACTION_GETFIRST; } dwRes = GetInterfaceInfo( actionId, &imgidInData, &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR || pimgodOutData == NULL ) { TraceError( dwRes ); return dwRes; } // // set requiste fields // piic = (PIPBOOTP_IF_CONFIG) (pimgodOutData-> IMGOD_Buffer); SetAsnInteger( &( pbifce-> ifCEState ), piic-> IC_State ); SetAsnInteger( &( pbifce-> ifCERelayMode ), piic-> IC_RelayMode + 1 ); SetAsnInteger( &( pbifce-> ifCEMaxHopCount ), piic-> IC_MaxHopCount ); SetAsnInteger( &( pbifce-> ifCEMinSecondsSinceBoot ), piic-> IC_MinSecondsSinceBoot ); // // set index for following getnext operation, (if any) // ForceSetAsnInteger( &( pbifce-> ifCEIndex ), pimgodOutData-> IMGOD_IfIndex ); if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } TraceLeave( " get_ifConfigEntry " ); return MIB_S_SUCCESS; } UINT set_ifConfigEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1; TraceEnter( " set_ifConfigEntry " ); switch ( actionId ) { case MIB_ACTION_VALIDATE : dwRes = ValidateInterfaceConfig( objectArray ); break; case MIB_ACTION_SET : dwRes = SetInterfaceConfig( objectArray ); break; case MIB_ACTION_CLEANUP : dwRes = MIB_S_SUCCESS; break; default : TRACE0( " set_ifConfigEntry - wrong action " ); dwRes = MIB_S_INVALID_PARAMETER; break; } TraceLeave( "set_ifConfigEntry" ); return dwRes ; } /////////////////////////////////////////////////////////////////////////////// // // // ifBindingEntry table (1.3.6.1.4.1.311.1.12.2.3.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_ifBindingEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwGetSize = 0; buf_ifBindingEntry * pbifb = NULL; PIPBOOTP_IF_BINDING piib = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( " get_ifBindingEntry " ); // // retrieve interface binding info. // pbifb = (buf_ifBindingEntry*) objectArray; imgidInData.IMGID_TypeID = IPBOOTP_IF_BINDING_ID; imgidInData.IMGID_IfIndex = GetAsnInteger( &( pbifb-> ifBindingIndex ), 0 ); if ( actionId == MIB_ACTION_GETNEXT && !imgidInData.IMGID_IfIndex ) { actionId = MIB_ACTION_GETFIRST; } dwRes = GetInterfaceInfo( actionId, &imgidInData, &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR || pimgodOutData == NULL ) { TraceError( dwRes ); return dwRes; } // // set requiste fields // piib = (PIPBOOTP_IF_BINDING) (pimgodOutData-> IMGOD_Buffer); SetAsnInteger( &( pbifb-> ifBindingState ), piib-> IB_State ); SetAsnInteger( &( pbifb-> ifBindingAddrCount ), piib-> IB_AddrCount ); ForceSetAsnInteger( &( pbifb-> ifBindingIndex ), pimgodOutData-> IMGOD_IfIndex ); if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } TraceLeave( " get_ifBindingEntry " ); return MIB_S_SUCCESS ; } /////////////////////////////////////////////////////////////////////////////// // // // ifAddressEntry table (1.3.6.1.4.1.311.1.12.2.4.1) // // // /////////////////////////////////////////////////////////////////////////////// UINT get_ifAddressEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = (DWORD) -1, dwIndex = (DWORD) -1, dwGetSize = 0; buf_ifAddressEntry * pbifae = NULL; PIPBOOTP_IF_BINDING piib = NULL; PIPBOOTP_IP_ADDRESS pia = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_IP_ADDRESS ipa; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; TraceEnter( " get_ifAddressEntry " ); // // retrieve interface binding info. // pbifae = (buf_ifAddressEntry*) objectArray; imgidInData.IMGID_TypeID = IPBOOTP_IF_BINDING_ID; imgidInData.IMGID_IfIndex = GetAsnInteger( &( pbifae-> ifAEIfIndex ), 0 ); if ( actionId == MIB_ACTION_GETNEXT && !imgidInData.IMGID_IfIndex ) { actionId = MIB_ACTION_GETFIRST; } dwRes = GetInterfaceInfo( actionId, &imgidInData, &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); return dwRes; } // // retrieve IPAddress from IP Address table // ipa.IA_Address = GetAsnIPAddress( &( pbifae-> ifAEAddress), INADDR_NONE ); ipa.IA_Netmask = GetAsnIPAddress( &( pbifae-> ifAEMask), INADDR_NONE ); piib = (PIPBOOTP_IF_BINDING) pimgodOutData-> IMGOD_Buffer; pia = (PIPBOOTP_IP_ADDRESS) IPBOOTP_IF_ADDRESS_TABLE( piib ); FIND_IP_ADDRESS( ipa, piib-> IB_AddrCount, pia, dwIndex ); // // set appr fields // dwRes = MIB_S_SUCCESS; switch ( actionId ) { case MIB_ACTION_GET : // // idempotent case. Only possible use is to verify // specific peer present. // if ( dwIndex >= piib-> IB_AddrCount ) { dwRes = MIB_S_ENTRY_NOT_FOUND; TRACE0( "IP address entry not found" ); } break; case MIB_ACTION_GETFIRST : // // get entry at index 0 if available // dwIndex = 0; if ( !piib-> IB_AddrCount ) { dwRes = MIB_S_NO_MORE_ENTRIES; TRACE1( "No more IP address Entries for interface : %d", imgidInData.IMGID_IfIndex ); } break; case MIB_ACTION_GETNEXT : // // check if entry was found // if ( dwIndex >= piib-> IB_AddrCount ) { dwRes = MIB_S_ENTRY_NOT_FOUND; TRACE0( "IP address Entry not found " ); break; } // // try and get next // dwIndex++; if ( dwIndex >= piib-> IB_AddrCount ) { dwRes = MIB_S_NO_MORE_ENTRIES; TRACE1( "No more IP address Entries for interface : %d", imgidInData.IMGID_IfIndex ); break; } dwRes = MIB_S_SUCCESS; break; default : TRACE0( " get_globalPeerFilterEntry - Wrong Action " ); dwRes = MIB_S_INVALID_PARAMETER; break; } // // set index for next retieval // if ( dwRes == MIB_S_SUCCESS ) { ForceSetAsnInteger( &( pbifae-> ifAEIfIndex ), pimgodOutData-> IMGOD_IfIndex ); ForceSetAsnIPAddress( &( pbifae-> ifAEAddress ), &( pbifae-> dwIfAEAddr ), pia[ dwIndex ].IA_Address ); ForceSetAsnIPAddress( &( pbifae-> ifAEMask ), &( pbifae-> dwIfAEMask ), pia[ dwIndex ].IA_Netmask ); } if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } TraceLeave( " get_ifAddressEntry " ); return dwRes; } DWORD UpdateGlobalInfo( IN AsnAny * objectArray ) { DWORD dwRes = (DWORD) -1, dwGetSize = 0, dwSetSize = 0; sav_global* psg = NULL; PIPBOOTP_GLOBAL_CONFIG pigc = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsidInData= NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; do { // // Retrieve the global config Data first // dwRes = GetGlobalConfigInfo( &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR ) { break; } pigc = (PIPBOOTP_GLOBAL_CONFIG) pimgodOutData-> IMGOD_Buffer; psg = (sav_global*) objectArray; // // Allocate set info buffer // dwSetSize = sizeof( IPBOOTP_MIB_SET_INPUT_DATA ) - 1 + IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ); pimsidInData = (PIPBOOTP_MIB_SET_INPUT_DATA) BOOTP_MIB_ALLOC( dwSetSize ); if ( pimsidInData == NULL ) { dwRes = ERROR_NOT_ENOUGH_MEMORY; TRACE0( "SetGlobalData - Mem. alloc failed" ); break; } pimsidInData-> IMSID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; pimsidInData-> IMSID_IfIndex = (DWORD) -1; pimsidInData-> IMSID_BufferSize = IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ); // // Set config info fields. // // // if a variable is not specified, the corresp. value in the // config is left unchanged (by setting it to itself). // pigc-> GC_MaxRecvQueueSize = GetAsnInteger( &( psg-> globalMaxRecQueueSize ), pigc-> GC_MaxRecvQueueSize ); // // -1 is subtracted from the enumerated fields to adjust // the ASN enumeration values to the actual log level values. // This is required since the enumeration cannot have // a zero value as per the ASN compiler. // // as a caveat, if the enumerated field is not specified in // this set operation, to preserve the value of the field // in the config, we first increment it. This way on the // -1 operation the value is restored. // pigc-> GC_LoggingLevel++; pigc-> GC_LoggingLevel = GetAsnInteger( &( psg-> globalLoggingLevel ), pigc-> GC_LoggingLevel ) - 1; CopyMemory( (PVOID) pimsidInData-> IMSID_Buffer, (PVOID*) pigc, IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) ); // // Save the info. in the MIB // BOOTP_MIB_SET( pimsidInData, dwSetSize, dwRes ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); break; } dwRes = MIB_S_SUCCESS; } while ( FALSE ); // // Free allocations // if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } if ( pimsidInData ) { BOOTP_MIB_FREE( pimsidInData ); } return dwRes; } DWORD GetGlobalConfigInfo( OUT PIPBOOTP_MIB_GET_OUTPUT_DATA * ppimgod, OUT PDWORD pdwSize ) { DWORD dwRes = (DWORD) -1; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; do { // // retrieve global config // *ppimgod = NULL; imgidInData.IMGID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; BOOTP_MIB_GET( &imgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodOutData, pdwSize, dwRes ); if (!pimgodOutData) return ERROR_NOT_ENOUGH_MEMORY; if ( dwRes != NO_ERROR ) { TraceError( dwRes ); break; } *ppimgod = pimgodOutData; } while ( FALSE ); return dwRes; } DWORD UpdateBOOTPServerTable( IN sav_globalBOOTPServerEntry * psgbse ) { DWORD dwRes = (DWORD) -1, dwInd = 0, dwOp = 0, dwServerAddr= INADDR_NONE, dwGetSize = 0, dwSetSize = 0; PDWORD pdwAddrTable= 0; PIPBOOTP_GLOBAL_CONFIG pigc = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsid = NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; do { // // Get global info // dwRes = GetGlobalConfigInfo( &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR ) { break; } // // Find server entry // dwServerAddr = GetAsnIPAddress( &( psgbse-> globalBOOTPServerAddr ), 0 ); pigc = (PIPBOOTP_GLOBAL_CONFIG) pimgodOutData-> IMGOD_Buffer; pdwAddrTable= IPBOOTP_GLOBAL_SERVER_TABLE( pigc ); FIND_SERVER_ENTRY( dwServerAddr, pigc-> GC_ServerCount, pdwAddrTable, dwInd ); // // if operation is server add // dwOp = GetAsnInteger( &( psgbse-> globalBOOTPServerTag ), 0 ); switch( dwOp ) { case d_globalBOOTPServerTag_create : // // if server already present, quit // if ( pigc-> GC_ServerCount && dwInd < pigc-> GC_ServerCount ) { dwRes = MIB_S_SUCCESS; break; } else { dwRes = AddBOOTPServerEntry( dwServerAddr, pimgodOutData ); } break; case d_globalBOOTPServerTag_delete : // // operation is server delete // // // if server is not present quit. // if ( !pigc-> GC_ServerCount || dwInd >= pigc-> GC_ServerCount ) { dwRes = MIB_S_SUCCESS; break; } dwRes = DeleteBOOTPServerEntry( dwInd, pimgodOutData ); break; default : dwRes = MIB_S_INVALID_PARAMETER; TRACE0( "Invalid action specified : logic error " ); break; } } while ( FALSE ); if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } return dwRes; } DWORD AddBOOTPServerEntry( IN DWORD dwServerAddr, IN PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData ) { DWORD dwRes = (DWORD) -1, dwSetSize = 0; PDWORD pdwAddrTable= NULL; PIPBOOTP_GLOBAL_CONFIG pigc = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsid = NULL; do { // // BOOTP Server needs to be added. // // // compute buffer size required // pigc = (PIPBOOTP_GLOBAL_CONFIG) pimgodOutData-> IMGOD_Buffer; dwSetSize = sizeof( IPBOOTP_MIB_SET_INPUT_DATA ) - 1 + IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) + sizeof( DWORD ); pimsid = (PIPBOOTP_MIB_SET_INPUT_DATA) BOOTP_MIB_ALLOC( dwSetSize ); if ( !pimsid ) { dwRes = ERROR_NOT_ENOUGH_MEMORY; TRACE0( "AddBOOTPServerEntry - out of memory" ); break; } // // Add server // pimsid-> IMSID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; pimsid-> IMSID_IfIndex = (DWORD) -1; pimsid-> IMSID_BufferSize = IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) + sizeof( DWORD ); CopyMemory( (PVOID) &( pimsid-> IMSID_Buffer ), (VOID *) pigc, IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) ); pigc = (PIPBOOTP_GLOBAL_CONFIG) pimsid-> IMSID_Buffer; pdwAddrTable = IPBOOTP_GLOBAL_SERVER_TABLE( pigc ); pdwAddrTable[ pigc-> GC_ServerCount ] = dwServerAddr; pigc-> GC_ServerCount++; // // Update MIB // BOOTP_MIB_SET( pimsid, dwSetSize, dwRes ); } while ( FALSE ); if ( pimsid ) { BOOTP_MIB_FREE( pimsid ); } return dwRes; } DWORD DeleteBOOTPServerEntry( IN DWORD dwIndex, IN PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData ) { DWORD dwRes = (DWORD) -1, dwSetSize = 0, dwSrc = 0, dwDst = 0; PDWORD pdwSrcTable = NULL, pdwDstTable = NULL; PIPBOOTP_GLOBAL_CONFIG pigc = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsid = NULL; do { // // Server needs to be deleted. // // // compute buffer size required // pigc = (PIPBOOTP_GLOBAL_CONFIG) pimgodOutData-> IMGOD_Buffer; dwSetSize = sizeof( IPBOOTP_MIB_SET_INPUT_DATA ) - 1 + IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) - sizeof( DWORD ); pimsid = (PIPBOOTP_MIB_SET_INPUT_DATA) BOOTP_MIB_ALLOC( dwSetSize ); if ( !pimsid ) { dwRes = ERROR_NOT_ENOUGH_MEMORY; TRACE0( "DeleteBOOTPServerEntry - out of memory" ); break; } // // Delete server // // // Copy base global config structure // pimsid-> IMSID_TypeID = IPBOOTP_GLOBAL_CONFIG_ID; pimsid-> IMSID_IfIndex = (DWORD) -1; pimsid-> IMSID_BufferSize = IPBOOTP_GLOBAL_CONFIG_SIZE( pigc ) - sizeof( DWORD ); CopyMemory( (PVOID) &( pimsid-> IMSID_Buffer ), (VOID *) pigc, sizeof( IPBOOTP_GLOBAL_CONFIG ) ); // // Copy peer table. Skip entry to be deleted // pdwSrcTable = IPBOOTP_GLOBAL_SERVER_TABLE( pigc ); pigc = ( PIPBOOTP_GLOBAL_CONFIG ) pimsid-> IMSID_Buffer; pdwDstTable = IPBOOTP_GLOBAL_SERVER_TABLE( pigc ); DELETE_SERVER_ENTRY( dwIndex, pigc-> GC_ServerCount, pdwSrcTable, pdwDstTable ); pigc-> GC_ServerCount--; // // Update MIB // BOOTP_MIB_SET( pimsid, dwSetSize, dwRes ); } while ( FALSE ); if ( pimsid ) { BOOTP_MIB_FREE( pimsid ); } return dwRes; } DWORD GetInterfaceInfo( IN UINT actionId, IN PIPBOOTP_MIB_GET_INPUT_DATA pimgidInData, OUT PIPBOOTP_MIB_GET_OUTPUT_DATA* ppimgod, OUT PDWORD pdwOutSize ) { DWORD dwRes = (DWORD) -1; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; *ppimgod = NULL; switch ( actionId ) { case MIB_ACTION_GET : BOOTP_MIB_GET( pimgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodOutData, pdwOutSize, dwRes ); // // ERROR_INVALID_PARAMETER is returned when there is // no interface for the specified index. // if ( dwRes == ERROR_INVALID_PARAMETER ) { dwRes = MIB_S_ENTRY_NOT_FOUND; } break; case MIB_ACTION_GETFIRST : BOOTP_MIB_GETFIRST( pimgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodOutData, pdwOutSize, dwRes ); // // ERROR_INVALID_PARAMETER is returned when there is // no interface for the specified index. // if ( dwRes == ERROR_INVALID_PARAMETER ) { dwRes = MIB_S_NO_MORE_ENTRIES; } break; case MIB_ACTION_GETNEXT : BOOTP_MIB_GETNEXT( pimgidInData, sizeof( IPBOOTP_MIB_GET_INPUT_DATA ), &pimgodOutData, pdwOutSize, dwRes ); // // ERROR_INVALID_PARAMETER is returned when there is // no interface for the specified index. // if ( dwRes == ERROR_INVALID_PARAMETER ) { dwRes = MIB_S_NO_MORE_ENTRIES; break; } // // Get Next wraps to the next table at the end of the // entries in the current table. To flag the end of a table, // check the end of the table. // if ( pimgidInData-> IMGID_TypeID != pimgodOutData-> IMGOD_TypeID ) { MprAdminMIBBufferFree( pimgodOutData ); dwRes = MIB_S_NO_MORE_ENTRIES; } break; default : dwRes = MIB_S_INVALID_PARAMETER; break; } if ( dwRes == NO_ERROR ) { *ppimgod = pimgodOutData; } return dwRes; } DWORD ValidateInterfaceConfig( IN AsnAny * objectArray ) { DWORD dwRes = MIB_S_INVALID_PARAMETER, dwCount = (DWORD) -1, dwMode = (DWORD) -1; sav_ifConfigEntry* psifce = (sav_ifConfigEntry*) objectArray; do { // // verify relay mode // dwMode = GetAsnInteger( &( psifce-> ifCERelayMode ), (DWORD) -1 ); if ( dwMode != d_ifCERelayMode_disabled && dwMode != d_ifCERelayMode_enabled ) { TRACE1( " Invalid update mode (%d) specified ", dwMode ); break; } dwRes = MIB_S_SUCCESS; } while ( FALSE ); return dwRes; } DWORD SetInterfaceConfig( IN AsnAny * objectArray ) { DWORD dwRes = (DWORD) -1, dwGetSize = 0, dwSetSize = 0; sav_ifConfigEntry* psifce = NULL; PIPBOOTP_IF_CONFIG piic = NULL; PIPBOOTP_MIB_SET_INPUT_DATA pimsidInData= NULL; PIPBOOTP_MIB_GET_OUTPUT_DATA pimgodOutData = NULL; IPBOOTP_MIB_GET_INPUT_DATA imgidInData; do { // // Retrieve existing interface config // psifce = (sav_ifConfigEntry*) objectArray; imgidInData.IMGID_TypeID = IPBOOTP_IF_CONFIG_ID; imgidInData.IMGID_IfIndex = GetAsnInteger( &( psifce-> ifCEIndex ), (DWORD) -1 ); dwRes = GetInterfaceInfo( MIB_ACTION_GET, &imgidInData, &pimgodOutData, &dwGetSize ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); break; } // // Update fields // piic = (PIPBOOTP_IF_CONFIG) (pimgodOutData-> IMGOD_Buffer); piic-> IC_RelayMode++; piic-> IC_RelayMode = GetAsnInteger( &( psifce-> ifCERelayMode ), piic-> IC_RelayMode ) - 1; piic-> IC_MaxHopCount = GetAsnInteger( &( psifce-> ifCEMaxHopCount ), piic-> IC_MaxHopCount ); piic-> IC_MinSecondsSinceBoot = GetAsnInteger( &( psifce-> ifCEMinSecondsSinceBoot ), piic-> IC_MinSecondsSinceBoot ); BOOTP_MIB_SET( pimsidInData, dwSetSize, dwRes ); if ( dwRes != NO_ERROR ) { TraceError( dwRes ); break; } dwRes = MIB_S_SUCCESS; } while ( FALSE ); if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); } if ( pimsidInData ) { BOOTP_MIB_FREE( pimsidInData ); } return dwRes; } DWORD ConnectToRouter() { DWORD dwRes = (DWORD) -1; EnterCriticalSection( &g_CS ); do { MPR_SERVER_HANDLE hTmp; if ( g_hMIBServer ) { dwRes = NO_ERROR; break; } dwRes = MprAdminMIBServerConnect( NULL, &hTmp ); if ( dwRes == NO_ERROR ) { InterlockedExchangePointer( &g_hMIBServer, hTmp ); } else { TRACE1( "Error %d setting up DIM connection to MIB Server\n", dwRes ); } } while ( FALSE ); LeaveCriticalSection( &g_CS ); return dwRes; }