windows-nt/Source/XPSP1/NT/net/rras/ip/sample/rtmapi.c
2020-09-26 16:20:57 +08:00

207 lines
4.6 KiB
C

/*++
Copyright (c) 1999, Microsoft Corporation
Module Name:
sample\rtmapi.c
Abstract:
The file contains RTMv2 API implementations.
--*/
#include "pchsample.h"
#pragma hdrstop
#ifdef DEBUG
DWORD
RTM_DisplayDestInfo(
IN PRTM_DEST_INFO prdi)
/*++
Routine Description
Displays an RTM_DEST_INFO object.
Locks
None
Arguments
prdi buffer containing the rtm dest info
Return Value
NO_ERROR always
--*/
{
IPADDRESS ip;
if (!prdi)
return NO_ERROR;
RTM_GetAddress(&ip, &(prdi->DestAddress));
TRACE2(NETWORK, "RtmDestInfo Destination %s/%u",
INET_NTOA(ip), (prdi->DestAddress).NumBits);
return NO_ERROR;
}
#else
#define DisplayRtmDestInfo(prdi)
#endif // DEBUG
DWORD
RTM_NextHop (
IN PRTM_DEST_INFO prdiDestination,
OUT PDWORD pdwIfIndex,
OUT PIPADDRESS pipNeighbor)
/*++
Routine Description
Obtain the next hop for a destination (typically a data source or an RP).
Locks
None
Arguments
prdiDestination destination information obtained from rtm
dwIfIndex next hop interface index
pipNeighbor ip address of next hop neighbor
Return Value
NO_ERROR success
Error Code o/w
--*/
{
DWORD dwErr = NO_ERROR;
PRTM_ROUTE_INFO prriRoute;
RTM_NEXTHOP_INFO rniNextHop;
BOOL bRoute, bNextHop;
// flags indicating handles held
bRoute = bNextHop = FALSE;
do // breakout loop
{
// allocate route info structure
MALLOC(&prriRoute,
RTM_SIZE_OF_ROUTE_INFO(g_ce.rrpRtmProfile.MaxNextHopsInRoute),
&dwErr);
if (dwErr != NO_ERROR)
break;
// get route info (best route in mcast view)
dwErr = RtmGetRouteInfo (
g_ce.hRtmHandle,
prdiDestination->ViewInfo[0].Route,
prriRoute,
NULL);
if (dwErr != NO_ERROR)
{
TRACE1(ANY, "Error %u getting route", dwErr);
break;
}
bRoute = TRUE;
// get nexthop info (first next hop for now...)
dwErr = RtmGetNextHopInfo(
g_ce.hRtmHandle,
prriRoute->NextHopsList.NextHops[0],
&rniNextHop);
if (dwErr != NO_ERROR)
{
TRACE1(ANY, "Error %u getting next hop", dwErr);
break;
}
bNextHop = TRUE;
// finally!!! THIS SHOULD NOT BE A REMOTE NEXT HOP!!!
*(pdwIfIndex) = rniNextHop.InterfaceIndex;
RTM_GetAddress(pipNeighbor,
&(rniNextHop.NextHopAddress));
} while (FALSE);
if (dwErr != NO_ERROR)
TRACE1(ANY, "Error %u obtaining next hop", dwErr);
// release the handle to the next hop
if (bNextHop)
{
if (RtmReleaseNextHopInfo(g_ce.hRtmHandle, &rniNextHop) != NO_ERROR)
TRACE0(ANY, "Error releasing next hop, continuing...");
}
// release the handle to the route
if (bRoute)
{
if (RtmReleaseRouteInfo(g_ce.hRtmHandle, prriRoute) != NO_ERROR)
TRACE0(ANY, "Error releasing route, continuing...");
}
// deallocate route info structure
if (prriRoute)
FREE(prriRoute);
return dwErr;
}
////////////////////////////////////////
// CALLBACKFUNCTIONS
////////////////////////////////////////
DWORD
APIENTRY
RTM_CallbackEvent (
IN RTM_ENTITY_HANDLE hRtmHandle, // registration handle
IN RTM_EVENT_TYPE retEvent,
IN PVOID pvContext1,
IN PVOID pvContext2)
/*++
Routine Description
Processes an RTMv2 event. Used to inform entities of new entities
registering, entities deregistering, route expiration, route changes.
Locks
None (for now)
Arguments
retEvent rtmv2 event type
Return Value
NO_ERROR success
Error Code o/w
--*/
{
DWORD dwErr = NO_ERROR;
TRACE1(ENTER, "Entering RTM_CallbackEvent: %u", retEvent);
do // breakout loop
{
UNREFERENCED_PARAMETER(hRtmHandle);
UNREFERENCED_PARAMETER(pvContext1);
UNREFERENCED_PARAMETER(pvContext2);
// only route change notifications are processed
if (retEvent != RTM_CHANGE_NOTIFICATION)
{
dwErr = ERROR_NOT_SUPPORTED;
break;
}
dwErr = NM_ProcessRouteChange();
} while (FALSE);
TRACE0(LEAVE, "Leaving RTM_CallbackEvent");
return dwErr;
}