|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
routing\ip\mcastmib\mibfuncs.c
Abstract:
IP Multicast MIB instrumentation callbacks
Revision history:
Dave Thaler 4/17/98 Created
--*/
#include "precomp.h"
#pragma hdrstop
//
// Define this to report a dummy MFE
//
#undef SAMPLE_MFE
#define ROWSTATUS_ACTIVE 1
DWORD ConnectToRouter();
DWORD SetGlobalInfo( IN AsnAny * objectArray );
DWORD GetMibInfo( IN UINT actionId, IN PMIB_OPAQUE_QUERY pQuery, IN DWORD dwQuerySize, OUT PMIB_OPAQUE_INFO * ppimgod, OUT PDWORD pdwOutSize );
//
// IP Multicast MIB scalar objects
//
UINT get_global( UINT actionId, AsnAny *objectArray, UINT *errorIndex ) { DWORD dwErr = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; PMIB_IPMCAST_GLOBAL pEntry; buf_global *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff, *pQuery = &pQueryBuff; DWORD dwQuerySize;
TraceEnter("get_global"); pOutput = (buf_global*)objectArray;
pQuery->dwVarId = MCAST_GLOBAL; dwQuerySize = sizeof(MIB_OPAQUE_QUERY) - sizeof(DWORD);
dwErr = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwErr != NO_ERROR) { TraceError(dwErr); return dwErr; }
pEntry = (PMIB_IPMCAST_GLOBAL) pRpcInfo->rgbyData;
SetAsnInteger(&(pOutput->ipMRouteEnable), pEntry->dwEnable);
if (pRpcInfo) MprAdminMIBBufferFree(pRpcInfo);
TraceLeave("get_global"); return MIB_S_SUCCESS; }
//
// IP Multicast Interface Table support
//
// We cache the fields which are static config info (such as protocol)
// so that queries that access only these rows can consult the cache
// rather than forcing a call to the router manager, kernel diving, etc.
//
typedef struct { DWORD dwIfIndex; // interface to which this info applies
DWORD dwProtocol; // multicast protocol owning that interface
DWORD dwTimestamp; // time at which above info was obtained
} MCAST_IF_CONFIG;
#define CACHE_SIZE 100 // number of interfaces to cache
MCAST_IF_CONFIG *cacheArray[CACHE_SIZE];
static int GetCacheIdx(dwIfIndex) DWORD dwIfIndex; { register int i;
for (i=0; i<CACHE_SIZE; i++) if (cacheArray[i] && cacheArray[i]->dwIfIndex==dwIfIndex) return i; return -1; }
static void UpdateCacheInterfaceConfig(dwCacheIdx, newIfConfig) DWORD dwCacheIdx; MCAST_IF_CONFIG *newIfConfig; { // Free the old one
if (cacheArray[dwCacheIdx]) MULTICAST_MIB_FREE( cacheArray[dwCacheIdx] );
// Store the new one
cacheArray[dwCacheIdx] = newIfConfig; }
static void AddCacheInterfaceConfig(pIfConfig) MCAST_IF_CONFIG *pIfConfig; { register int i, best = -1;
// Find empty or oldest spot
for (i=0; i<CACHE_SIZE; i++) { if (!cacheArray[i]) { best=i; break; } if (best<0 || cacheArray[i]->dwTimestamp < cacheArray[best]->dwTimestamp) best=i; } UpdateCacheInterfaceConfig(best, pIfConfig); }
static MCAST_IF_CONFIG * SaveInterfaceConfig(pEntry) PMIB_IPMCAST_IF_ENTRY pEntry; { MCAST_IF_CONFIG *pIfConfig; int iCacheIdx;
TRACE1("SaveInterfaceConfig %d\n", pEntry->dwIfIndex);
pIfConfig= MULTICAST_MIB_ALLOC(sizeof(MCAST_IF_CONFIG)); if (!pIfConfig) { return NULL; } pIfConfig->dwIfIndex = pEntry->dwIfIndex; pIfConfig->dwProtocol = pEntry->dwProtocol; pIfConfig->dwTimestamp = GetCurrentTime();
iCacheIdx = GetCacheIdx(pEntry->dwIfIndex); if (iCacheIdx >= 0) UpdateCacheInterfaceConfig((DWORD)iCacheIdx, pIfConfig); else AddCacheInterfaceConfig(pIfConfig);
return pIfConfig; }
MCAST_IF_CONFIG * GetInterfaceConfig(dwIfIndex) DWORD dwIfIndex; { MCAST_IF_CONFIG *outIfConfig = NULL; MCAST_IF_CONFIG *pIfConfig; DWORD dwQuerySize; MIB_OPAQUE_QUERY pQueryBuff, *pQuery = &pQueryBuff; DWORD dwErr = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; PMIB_IPMCAST_IF_ENTRY pEntry; buf_ipMRouteInterfaceEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0;
TRACE1("GetInterfaceConfig %d\n", dwIfIndex);
// Do a MIB lookup
pQuery->dwVarId = MCAST_IF_ENTRY; pQuery->rgdwVarIndex[0] = dwIfIndex; dwQuerySize = sizeof(MIB_OPAQUE_QUERY);
dwErr = GetMibInfo(MIB_ACTION_GET, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); // Save each entry returned
if (dwErr == NO_ERROR) { pEntry = (PMIB_IPMCAST_IF_ENTRY) pRpcInfo->rgbyData; pIfConfig = SaveInterfaceConfig(pEntry);
if (pEntry->dwIfIndex == dwIfIndex) outIfConfig = pIfConfig; }
// Return the saved entry which was asked for
if (pRpcInfo) MprAdminMIBBufferFree(pRpcInfo); return outIfConfig; }
MCAST_IF_CONFIG * ForceGetCacheInterfaceConfig(dwIfIndex) DWORD dwIfIndex; { MCAST_IF_CONFIG *tmpIfConfig; int iCacheIdx = GetCacheIdx(dwIfIndex);
TRACE2("ForceGetCacheInterfaceConfig ifIndex=%d ci=%d\n", dwIfIndex, iCacheIdx);
if (iCacheIdx >= 0 && GetCurrentTime() - cacheArray[iCacheIdx]->dwTimestamp < IPMULTI_IF_CACHE_TIMEOUT) return cacheArray[iCacheIdx];
// Service a cache miss
tmpIfConfig = GetInterfaceConfig(dwIfIndex); return tmpIfConfig; }
static DWORD GetInterfaceProtocol(dwIfIndex) DWORD dwIfIndex; { // Look up interface config in interface config cache
MCAST_IF_CONFIG *pIfConfig = ForceGetCacheInterfaceConfig(dwIfIndex);
return (pIfConfig)? pIfConfig->dwProtocol : 0; }
UINT get_ipMRouteInterfaceEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) /*++
Routine Description: Get the InterfaceEntry for IP Multicast. Have to get the InterfaceConfig and InterfaceStats for the interface from the router. --*/ { DWORD dwErr = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; PMIB_IPMCAST_IF_ENTRY pEntry; buf_ipMRouteInterfaceEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff, *pQuery = &pQueryBuff; DWORD dwQuerySize;
TraceEnter("get_ipMRouteInterfaceEntry"); pOutput = (buf_ipMRouteInterfaceEntry*)objectArray;
pQuery->dwVarId = MCAST_IF_ENTRY; pQuery->rgdwVarIndex[0] = GetAsnInteger( &( pOutput->ipMRouteInterfaceIfIndex ), 0 ); dwQuerySize = sizeof(MIB_OPAQUE_QUERY);
dwErr = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwErr != NO_ERROR) { TraceError(dwErr); return ERROR_NO_MORE_ITEMS; }
pEntry = (PMIB_IPMCAST_IF_ENTRY) pRpcInfo->rgbyData;
SaveInterfaceConfig(pEntry);
// Set index values
ForceSetAsnInteger(&(pOutput->ipMRouteInterfaceIfIndex), pEntry->dwIfIndex);
// Set other values
SetAsnInteger(&(pOutput->ipMRouteInterfaceTtl), pEntry->dwTtl); SetAsnInteger(&(pOutput->ipMRouteInterfaceProtocol), pEntry->dwProtocol); SetAsnInteger(&(pOutput->ipMRouteInterfaceRateLimit), pEntry->dwRateLimit);
SetAsnCounter(&(pOutput->ipMRouteInterfaceInMcastOctets), pEntry->ulInMcastOctets); SetAsnCounter(&(pOutput->ipMRouteInterfaceOutMcastOctets), pEntry->ulOutMcastOctets);
if (pRpcInfo) MprAdminMIBBufferFree(pRpcInfo);
TraceLeave("get_ipMRouteInterfaceEntry"); return MIB_S_SUCCESS; }
//
// Multicast Forwarding Table (ipMRouteTable) support
//
UINT get_ipMRouteEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) /*++
Routine Description: Get the MFE information based on the input criteria. --*/ { DWORD dwResult = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; IPMCAST_MFE mfe; IPMCAST_MFE_STATS mfeStats; #ifdef SAMPLE_MFE
MIB_IPMCAST_MFE_STATS sampledata; #endif
PMIB_IPMCAST_MFE_STATS pEntry; PMIB_MFE_STATS_TABLE pTable = NULL; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; buf_ipMRouteEntry *pOutput; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize; BOOL bPart;
TraceEnter("get_ipMRouteEntry"); pOutput = (buf_ipMRouteEntry*)objectArray;
pQuery->dwVarId = MCAST_MFE_STATS;
// Extract the instance info
pQuery->rgdwVarIndex[0] = GetAsnIPAddress( &pOutput->ipMRouteGroup, 0 ); pQuery->rgdwVarIndex[1] = GetAsnIPAddress( &pOutput->ipMRouteSource, 0xFFFFFFFF ); pQuery->rgdwVarIndex[2] = GetAsnIPAddress( &pOutput->ipMRouteSourceMask, 0xFFFFFFFF);
//
// Fix up query if instance was partially-specified.
// This section can go away if the SNMP API does this for us.
//
if (!pOutput->ipMRouteGroup.asnType || !pOutput->ipMRouteGroup.asnValue.string.length) { actionId = MIB_ACTION_GETFIRST; } else { if (!pOutput->ipMRouteSource.asnType || !pOutput->ipMRouteSource.asnValue.string.length) { if (pQuery->rgdwVarIndex[0]) { pQuery->rgdwVarIndex[0]--; } else { actionId = MIB_ACTION_GETFIRST; } } else { if (!pOutput->ipMRouteSourceMask.asnType || !pOutput->ipMRouteSourceMask.asnValue.string.length) { if (pQuery->rgdwVarIndex[1]) { pQuery->rgdwVarIndex[1]--; } else { if (pQuery->rgdwVarIndex[0]) { pQuery->rgdwVarIndex[0]--; pQuery->rgdwVarIndex[1] = 0xFFFFFFFF; } else { actionId = MIB_ACTION_GETFIRST; } } } } }
dwQuerySize = sizeof(MIB_OPAQUE_QUERY) + 2*sizeof(DWORD);
#ifndef SAMPLE_MFE
dwResult = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwResult != NO_ERROR) { TraceError(dwResult); return dwResult; }
pTable = (PMIB_MFE_STATS_TABLE)( pRpcInfo->rgbyData); if (pTable->dwNumEntries == 0) { MprAdminMIBBufferFree( pRpcInfo ); return MIB_S_NO_MORE_ENTRIES; } pEntry = pTable->table; // use first entry returned
#else
pEntry = &sampledata; if (pQuery->rgdwVarIndex[0] >= 0x01010101) return MIB_S_NO_MORE_ENTRIES; sampledata.dwGroup = 0x01010101; /* (*,G) Entry */ sampledata.dwSource = 0x00000000; sampledata.dwSrcMask = 0x00000000; // don't care what the other values are for this test
#endif
// Save index terms
ForceSetAsnIPAddress(&(pOutput->ipMRouteGroup), &(pOutput->dwIpMRouteGroupInfo), pEntry->dwGroup); ForceSetAsnIPAddress(&(pOutput->ipMRouteSource), &(pOutput->dwIpMRouteSourceInfo), pEntry->dwSource); ForceSetAsnIPAddress(&(pOutput->ipMRouteSourceMask), &(pOutput->dwIpMRouteSourceMaskInfo), pEntry->dwSrcMask);
// Save other terms
SetAsnIPAddress(&pOutput->ipMRouteUpstreamNeighbor, &pOutput->dwIpMRouteUpstreamNeighborInfo, pEntry->dwUpStrmNgbr); SetAsnInteger(&(pOutput->ipMRouteInIfIndex), pEntry->dwInIfIndex); SetAsnTimeTicks(&(pOutput->ipMRouteUpTime), pEntry->ulUpTime); SetAsnTimeTicks(&(pOutput->ipMRouteExpiryTime), pEntry->ulExpiryTime); SetAsnCounter(&(pOutput->ipMRoutePkts), pEntry->ulInPkts); SetAsnCounter(&(pOutput->ipMRouteDifferentInIfPackets), pEntry->ulPktsDifferentIf); SetAsnCounter(&(pOutput->ipMRouteOctets), pEntry->ulInOctets);
// For protocol, we'll just report the protocol owning the iif
SetAsnInteger(&(pOutput->ipMRouteProtocol), GetInterfaceProtocol(pEntry->dwInIfIndex));
SetAsnInteger(&pOutput->ipMRouteRtProto, pEntry->dwRouteProtocol); SetAsnIPAddress(&pOutput->ipMRouteRtAddress, &pOutput->dwIpMRouteRtAddressInfo, pEntry->dwRouteNetwork); SetAsnIPAddress(&pOutput->ipMRouteRtMask, &pOutput->dwIpMRouteRtMaskInfo, pEntry->dwRouteMask);
if ( pRpcInfo ) { MprAdminMIBBufferFree( pRpcInfo ); }
TraceLeave("get_ipMRouteEntry"); return MIB_S_SUCCESS; }
//
// Multicast Forwarding Next Hop table (ipMRouteNextHopTable) support
//
static DWORD LocateMfeOif(actionId, pQuery, oifIndex, oifAddress, ppEntry, ppOif, ppRpcInfo) UINT actionId; MIB_OPAQUE_QUERY *pQuery; DWORD oifIndex; DWORD oifAddress; PMIB_IPMCAST_MFE_STATS *ppEntry; PMIB_IPMCAST_OIF_STATS *ppOif; PMIB_OPAQUE_INFO *ppRpcInfo; /*++
Routine Description: Get the exact/next/first oif entry based on the input criteria. --*/ { DWORD dwResult = MIB_S_SUCCESS; DWORD dwQuerySize = sizeof(MIB_OPAQUE_QUERY) + 2*sizeof(DWORD); DWORD dwOutBufferSize = 0; PMIB_MFE_STATS_TABLE pTable = NULL; PMIB_IPMCAST_MFE_STATS pEntry = NULL; PMIB_IPMCAST_OIF_STATS pOif = NULL; PMIB_OPAQUE_INFO pRpcInfo = NULL; BOOL oifIndexAny = FALSE; BOOL oifAddressAny = FALSE; DWORD idx; BOOL bFound;
do {
// Get the first MFE which applies (if any)
dwResult = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwResult != NO_ERROR) { TraceError(dwResult); return dwResult; } pTable = (PMIB_MFE_STATS_TABLE)( pRpcInfo->rgbyData); if (pTable->dwNumEntries == 0) { MprAdminMIBBufferFree( pRpcInfo ); return MIB_S_NO_MORE_ENTRIES; } pEntry = pTable->table; // use first entry returned
// Get the first OIF which applies (if any)
bFound=FALSE; for (idx=0; !bFound && idx < pEntry->ulNumOutIf; idx++) { pOif = &pEntry->rgmiosOutStats[idx];
// Do processing for GET
if (actionId==MIB_ACTION_GET) { if (oifIndex == pOif->dwOutIfIndex && oifAddress == pOif->dwNextHopAddr) { bFound=TRUE; break; } else continue; }
// Do processing for GET-NEXT
if ( oifIndexAny == TRUE || oifIndex < pOif->dwOutIfIndex || (oifIndex == pOif->dwOutIfIndex && (oifAddressAny == TRUE || oifAddress < pOif->dwNextHopAddr))) { bFound=TRUE; break; } } if (bFound) break;
// else continue and get a new entry
pQuery->rgdwVarIndex[0] = pEntry->dwGroup; pQuery->rgdwVarIndex[1] = pEntry->dwSource; pQuery->rgdwVarIndex[2] = pEntry->dwSrcMask; oifAddressAny = oifIndexAny = TRUE;
MprAdminMIBBufferFree( pRpcInfo ); } while (actionId != MIB_ACTION_GET); // once for GET, "forever" for others
*ppEntry = pEntry; *ppOif = pOif; *ppRpcInfo = pRpcInfo; return dwResult; }
UINT get_ipMRouteNextHopEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwResult = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; IPMCAST_MFE mfe; IPMCAST_MFE_STATS mfeStats; #ifdef SAMPLE_MFE
MIB_IPMCAST_MFE_STATS sampledata; #endif
PMIB_IPMCAST_MFE_STATS pEntry; PMIB_IPMCAST_OIF_STATS pOif; PMIB_MFE_STATS_TABLE pTable = NULL; DWORD dwOutBufferSize = 0; buf_ipMRouteNextHopEntry *pOutput; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize; DWORD oifIndex, oifAddress; PMIB_OPAQUE_INFO pRpcInfo = NULL;
TraceEnter("get_ipMRouteNextHopEntry"); pOutput = (buf_ipMRouteNextHopEntry*)objectArray;
pQuery->dwVarId = MCAST_MFE_STATS;
//
// XXX Note that the 3 lines below aren't quite right, since
// 0-value instances will be missed. That is (*,G) entries
// will be skipped!!
//
// Should call for a GET-FIRST if an incomplete length is given.
// Maybe the Sfx API does this already.
//
// XXX hold off on changing this until Florin changes the SNMP
// api to cover the out-of-range index case.
//
pQuery->rgdwVarIndex[0] = GetAsnIPAddress( &( pOutput->ipMRouteNextHopGroup ), 0 ); pQuery->rgdwVarIndex[1] = GetAsnIPAddress( &( pOutput->ipMRouteNextHopSource), 0 ); pQuery->rgdwVarIndex[2] = GetAsnIPAddress( &( pOutput->ipMRouteNextHopSourceMask ), 0 ); oifIndex = GetAsnInteger( &(pOutput->ipMRouteNextHopIfIndex), 0); oifAddress = GetAsnIPAddress( &(pOutput->ipMRouteNextHopAddress), 0);
#ifndef SAMPLE_MFE
{ dwResult = LocateMfeOif(actionId, pQuery, oifIndex, oifAddress, &pEntry, &pOif, &pRpcInfo); if (dwResult != NO_ERROR) { TraceError(dwResult); return dwResult; } } #else
{ pEntry = &sampledata; pOif = &pEntry->rgmiosOutStats[0]; if (pQuery->rgdwVarIndex[0] >= 0x01010101) return MIB_S_NO_MORE_ENTRIES; pEntry->dwGroup = 0x01010101; pEntry->dwSource = 0x02020202; pEntry->dwSrcMask = 0x03030303; pEntry->ulNumOutIf = 1; pOif->dwOutIfIndex = 11; pOif->dwNextHopAddr = 0x04040404; pOif->ulOutPackets = 22; // don't care what the other values are for this test
} #endif
// Save index terms
ForceSetAsnIPAddress(&(pOutput->ipMRouteNextHopGroup), &(pOutput->dwIpMRouteNextHopGroupInfo), pEntry->dwGroup); ForceSetAsnIPAddress(&(pOutput->ipMRouteNextHopSource), &(pOutput->dwIpMRouteNextHopSourceInfo), pEntry->dwSource); ForceSetAsnIPAddress(&(pOutput->ipMRouteNextHopSourceMask), &(pOutput->dwIpMRouteNextHopSourceMaskInfo), pEntry->dwSrcMask); ForceSetAsnInteger (&(pOutput->ipMRouteNextHopIfIndex), pOif->dwOutIfIndex); ForceSetAsnIPAddress(&(pOutput->ipMRouteNextHopAddress), &(pOutput->dwIpMRouteNextHopAddressInfo), pOif->dwNextHopAddr);
// Save other terms
SetAsnInteger(&(pOutput->ipMRouteNextHopState), 2); // "forwarding"
SetAsnTimeTicks(&(pOutput->ipMRouteNextHopUpTime), pEntry->ulUpTime); // XXX
SetAsnTimeTicks(&(pOutput->ipMRouteNextHopExpiryTime), pEntry->ulExpiryTime); // XXX
#ifdef CLOSEST_MEMBER_HOPS
SetAsnInteger(&(pOutput->ipMRouteNextHopClosestMemberHops), 1); #endif
SetAsnCounter(&(pOutput->ipMRouteNextHopPkts), pOif->ulOutPackets); // For protocol, we'll just report the protocol owning the interface
SetAsnInteger(&(pOutput->ipMRouteNextHopProtocol), GetInterfaceProtocol(pOif->dwOutIfIndex));
if ( pRpcInfo ) { MprAdminMIBBufferFree( pRpcInfo ); }
TraceLeave("get_ipMRouteNextHopEntry"); return MIB_S_SUCCESS; }
DWORD SetMibInfo( IN UINT actionId, // SET, CLEANUP
IN PMIB_OPAQUE_INFO pInfo, // value info
IN DWORD dwInfoSize // size of above
) { DWORD dwRes = NO_ERROR; switch ( actionId ) {
#ifdef THREE_PHASE
case MIB_ACTION_VALIDATE :
MULTICAST_MIB_VALIDATE( pInfo, dwInfoSize, dwRes ); // ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
//
if ( dwRes == ERROR_INVALID_PARAMETER ) { dwRes = MIB_S_INVALID_PARAMETER; }
break; #endif
case MIB_ACTION_SET :
#if 1
dwRes = ( g_hMIBServer ) ? NO_ERROR : ConnectToRouter();
if ( dwRes == NO_ERROR ) { dwRes = MprAdminMIBEntrySet( g_hMIBServer, PID_IP, IPRTRMGR_PID, (LPVOID) (pInfo), (dwInfoSize) ); } #else
MULTICAST_MIB_COMMIT( pInfo, dwInfoSize, dwRes ); #endif
// ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
//
if ( dwRes == ERROR_INVALID_PARAMETER || dwRes == ERROR_INVALID_INDEX ) { dwRes = MIB_S_INVALID_PARAMETER; } break;
#ifdef THREE_PHASE
case MIB_ACTION_CLEANUP :
MULTICAST_MIB_CLEANUP( pInfo, dwInfoSize, dwRes ); // ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
//
if ( dwRes == ERROR_INVALID_PARAMETER ) { dwRes = MIB_S_INVALID_PARAMETER; }
break; #endif
default :
dwRes = MIB_S_INVALID_PARAMETER; break; }
return dwRes; }
DWORD GetMibInfo( IN UINT actionId, // GET, GET-NEXT, SET
IN PMIB_OPAQUE_QUERY pQuery, // instance info
IN DWORD dwQuerySize, // size of above
OUT PMIB_OPAQUE_INFO *ppimgod, // value info
OUT PDWORD pdwOutSize // size of above
) { DWORD dwRes = (DWORD) -1; PMIB_OPAQUE_INFO pimgodOutData = NULL; *ppimgod = NULL;
switch ( actionId ) { case MIB_ACTION_GET :
MULTICAST_MIB_GET( pQuery, dwQuerySize, &pimgodOutData, pdwOutSize, dwRes ); //
// ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
// RPC_S_SERVER_UNAVAILABLE is returned when the router
// isn't running.
//
if ( dwRes == ERROR_INVALID_PARAMETER || dwRes == RPC_S_SERVER_UNAVAILABLE || dwRes == RPC_S_UNKNOWN_IF ) { dwRes = MIB_S_ENTRY_NOT_FOUND; }
break;
case MIB_ACTION_GETFIRST :
MULTICAST_MIB_GETFIRST( pQuery, dwQuerySize, &pimgodOutData, pdwOutSize, dwRes ); //
// ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
// RPC_S_SERVER_UNAVAILABLE is returned when the router
// isn't running.
//
if ( dwRes == ERROR_INVALID_PARAMETER || dwRes == RPC_S_SERVER_UNAVAILABLE || dwRes == RPC_S_UNKNOWN_IF ) { dwRes = MIB_S_NO_MORE_ENTRIES; }
break;
case MIB_ACTION_GETNEXT : MULTICAST_MIB_GETNEXT( pQuery, dwQuerySize, &pimgodOutData, pdwOutSize, dwRes ); //
// ERROR_INVALID_PARAMETER is returned when there is
// no interface for the specified index.
// RPC_S_SERVER_UNAVAILABLE is returned when the router
// isn't running.
//
if ( dwRes == ERROR_INVALID_PARAMETER || dwRes == ERROR_NO_MORE_ITEMS || dwRes == RPC_S_SERVER_UNAVAILABLE || dwRes == RPC_S_UNKNOWN_IF ) { 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 ( pQuery->dwVarId != pQuery->dwVarId ) { dwRes = MIB_S_NO_MORE_ENTRIES; }
break;
default :
dwRes = MIB_S_INVALID_PARAMETER; break; }
if ( dwRes == NO_ERROR ) { *ppimgod = pimgodOutData; } else if ( pimgodOutData ) { MprAdminMIBBufferFree( pimgodOutData ); }
return dwRes; }
UINT set_ipMRouteScopeEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = MIB_S_SUCCESS; DWORD dwNumEntries = 1; PMIB_IPMCAST_SCOPE pEntry; sav_ipMRouteScopeEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize; DWORD dwIfIndex; DWORD dwAddr; DWORD dwMask;
TraceEnter("set_ipMRouteScopeEntry"); pOutput = (sav_ipMRouteScopeEntry*)objectArray;
dwAddr = GetAsnIPAddress( &pOutput->ipMRouteScopeAddress, 0 ); dwMask = GetAsnIPAddress( &pOutput->ipMRouteScopeAddressMask, 0 );
switch(actionId) { case MIB_ACTION_VALIDATE: //
// Verify that the specified ifIndex, address, and mask are valid.
//
if ((dwAddr & dwMask) != dwAddr) { TRACE0( "set_ipMRouteScopeEntry: address/mask mismatch" ); dwRes = MIB_S_INVALID_PARAMETER; } else if (!IN_MULTICAST(ntohl(dwAddr))) { TRACE0( "set_ipMRouteScopeEntry: non-multicast address" ); dwRes = MIB_S_INVALID_PARAMETER; } break; case MIB_ACTION_SET: { BYTE pScopeName[MAX_SCOPE_NAME_LEN+1]; DWORD dwInfoSize; MIB_IPMCAST_SCOPE pScopeBuff[2]; // big enough to hold 1 + mib hdr
// so we don't have to malloc
MIB_OPAQUE_INFO *pInfo = (PMIB_OPAQUE_INFO)&pScopeBuff[0]; PMIB_IPMCAST_SCOPE pScope = (MIB_IPMCAST_SCOPE *)(pInfo->rgbyData);
pInfo->dwId = MCAST_SCOPE; pScope->dwGroupAddress = dwAddr; pScope->dwGroupMask = dwMask;
//
// Copy the scope name.
//
pScopeName[0] = '\0'; GetAsnOctetString( pScopeName, &pOutput->ipMRouteScopeName );
MultiByteToWideChar( CP_UTF8, 0, pScopeName, strlen(pScopeName), pScope->snNameBuffer, MAX_SCOPE_NAME_LEN+1 );
pScope->dwStatus = GetAsnInteger( &pOutput->ipMRouteScopeStatus, 0 ); dwInfoSize = MIB_INFO_SIZE(MIB_IPMCAST_SCOPE); //
// Passing a name of "" or a status of 0 tells the router
// not to change the existing value.
//
dwRes = SetMibInfo(actionId, pInfo, dwInfoSize); break; }
case MIB_ACTION_CLEANUP: dwRes = MIB_S_SUCCESS; break;
default: dwRes = MIB_S_INVALID_PARAMETER; TRACE0(" set_ipMRouteScopeEntry - Wrong Action "); break; }
TraceLeave("set_ipMRouteScopeEntry");
return dwRes; }
UINT set_ipMRouteBoundaryEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwRes = MIB_S_SUCCESS; DWORD dwNumEntries = 1; PMIB_IPMCAST_BOUNDARY pEntry; sav_ipMRouteBoundaryEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize; DWORD dwIfIndex; DWORD dwAddr; DWORD dwMask;
TraceEnter("set_ipMRouteBoundaryEntry"); pOutput = (sav_ipMRouteBoundaryEntry*)objectArray;
dwIfIndex = GetAsnInteger( &( pOutput->ipMRouteBoundaryIfIndex ), 0 ); dwAddr = GetAsnIPAddress( &pOutput->ipMRouteBoundaryAddress, 0 ); dwMask = GetAsnIPAddress( &pOutput->ipMRouteBoundaryAddressMask, 0 );
switch(actionId) { case MIB_ACTION_VALIDATE: //
// Verify that the specified ifIndex, address, and mask are valid.
//
if ((dwAddr & dwMask) != dwAddr) { TRACE0( "set_ipMRouteBoundaryEntry: address/mask mismatch" ); dwRes = MIB_S_INVALID_PARAMETER; } else if (!IN_MULTICAST(ntohl(dwAddr))) { TRACE0( "set_ipMRouteBoundaryEntry: non-multicast address" ); dwRes = MIB_S_INVALID_PARAMETER; } break; case MIB_ACTION_SET: { DWORD dwInfoSize; MIB_OPAQUE_INFO pInfoBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_INFO *pInfo = &pInfoBuff[0]; PMIB_IPMCAST_BOUNDARY pBound = (MIB_IPMCAST_BOUNDARY *)(pInfo->rgbyData);
pInfo->dwId = MCAST_BOUNDARY; pBound->dwIfIndex = dwIfIndex; pBound->dwGroupAddress = dwAddr; pBound->dwGroupMask = dwMask; pBound->dwStatus = GetAsnInteger( &pOutput->ipMRouteBoundaryStatus, 0 ); dwInfoSize = sizeof(MIB_OPAQUE_INFO) + 3*sizeof(DWORD); dwRes = SetMibInfo(actionId, pInfo, dwInfoSize); break; }
case MIB_ACTION_CLEANUP: dwRes = MIB_S_SUCCESS; break;
default: dwRes = MIB_S_INVALID_PARAMETER; TRACE0(" set_ipMRouteBoundaryEntry - Wrong Action "); break; }
TraceLeave("set_ipMRouteBoundaryEntry");
return dwRes; }
UINT get_ipMRouteScopeEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwErr = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; PMIB_IPMCAST_SCOPE pEntry; buf_ipMRouteScopeEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize; BYTE pScopeName[MAX_SCOPE_NAME_LEN+1];
TraceEnter("get_ipMRouteScopeEntry"); pOutput = (buf_ipMRouteScopeEntry*)objectArray;
pQuery->dwVarId = MCAST_SCOPE; pQuery->rgdwVarIndex[0] = GetAsnIPAddress( &pOutput->ipMRouteScopeAddress, 0 ); pQuery->rgdwVarIndex[1] = GetAsnIPAddress( &pOutput->ipMRouteScopeAddressMask, 0 ); dwQuerySize = sizeof(MIB_OPAQUE_QUERY) + sizeof(DWORD);
dwErr = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwErr != NO_ERROR) { TraceError(dwErr); TraceLeave("get_ipMRouteScopeEntry");
if (dwErr == ERROR_NOT_FOUND) return MIB_S_ENTRY_NOT_FOUND;
return dwErr; }
pEntry = (PMIB_IPMCAST_SCOPE) pRpcInfo->rgbyData;
// Set index values
ForceSetAsnIPAddress(&(pOutput->ipMRouteScopeAddress), &(pOutput->dwIpMRouteScopeAddressInfo), pEntry->dwGroupAddress); ForceSetAsnIPAddress(&(pOutput->ipMRouteScopeAddressMask), &(pOutput->dwIpMRouteScopeAddressMaskInfo), pEntry->dwGroupMask);
// Set other values.
WideCharToMultiByte( CP_UTF8, 0, pEntry->snNameBuffer, wcslen(pEntry->snNameBuffer)+1, pScopeName, MAX_SCOPE_NAME_LEN+1, NULL, NULL );
SetAsnOctetString(&( pOutput->ipMRouteScopeName), pOutput->rgbyScopeNameInfo, pScopeName, min(strlen(pScopeName),MAX_SCOPE_NAME_LEN));
SetAsnInteger(&(pOutput->ipMRouteScopeStatus), ROWSTATUS_ACTIVE);
if (pRpcInfo) MprAdminMIBBufferFree(pRpcInfo);
TraceLeave("get_ipMRouteScopeEntry"); return MIB_S_SUCCESS; }
UINT get_ipMRouteBoundaryEntry( UINT actionId, AsnAny * objectArray, UINT * errorIndex ) { DWORD dwErr = ERROR_NOT_FOUND; DWORD dwNumEntries = 1; PMIB_IPMCAST_BOUNDARY pEntry; buf_ipMRouteBoundaryEntry *pOutput; PMIB_OPAQUE_INFO pRpcInfo = NULL; DWORD dwOutBufferSize = 0; MIB_OPAQUE_QUERY pQueryBuff[2]; // big enough to hold 1 + extra index
// fields, so we don't have to malloc
MIB_OPAQUE_QUERY *pQuery = &pQueryBuff[0]; DWORD dwQuerySize;
TraceEnter("get_ipMRouteBoundaryEntry"); pOutput = (buf_ipMRouteBoundaryEntry*)objectArray;
pQuery->dwVarId = MCAST_BOUNDARY; pQuery->rgdwVarIndex[0] = GetAsnInteger( &( pOutput->ipMRouteBoundaryIfIndex ), 0 ); pQuery->rgdwVarIndex[1] = GetAsnIPAddress( &pOutput->ipMRouteBoundaryAddress, 0 ); pQuery->rgdwVarIndex[2] = GetAsnIPAddress( &pOutput->ipMRouteBoundaryAddressMask, 0 ); dwQuerySize = sizeof(MIB_OPAQUE_QUERY) + 2*sizeof(DWORD);
dwErr = GetMibInfo(actionId, pQuery, dwQuerySize, &pRpcInfo, &dwOutBufferSize); if (dwErr != NO_ERROR) { TraceError(dwErr); TraceLeave("get_ipMRouteBoundaryEntry");
if (dwErr == ERROR_NOT_FOUND) return MIB_S_ENTRY_NOT_FOUND;
return dwErr; }
pEntry = (PMIB_IPMCAST_BOUNDARY) pRpcInfo->rgbyData;
// Set index values
ForceSetAsnInteger(&(pOutput->ipMRouteBoundaryIfIndex), pEntry->dwIfIndex); ForceSetAsnIPAddress(&(pOutput->ipMRouteBoundaryAddress), &(pOutput->dwIpMRouteBoundaryAddressInfo), pEntry->dwGroupAddress); ForceSetAsnIPAddress(&(pOutput->ipMRouteBoundaryAddressMask), &(pOutput->dwIpMRouteBoundaryAddressMaskInfo), pEntry->dwGroupMask);
// Set other values
SetAsnInteger(&(pOutput->ipMRouteBoundaryStatus), ROWSTATUS_ACTIVE);
if (pRpcInfo) MprAdminMIBBufferFree(pRpcInfo);
TraceLeave("get_ipMRouteBoundaryEntry"); return MIB_S_SUCCESS; }
DWORD ConnectToRouter() { DWORD dwRes = (DWORD) -1;
TraceEnter("ConnectToRouter");
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 );
TraceLeave("ConnectToRouter");
return dwRes; }
|