|
|
//++
//
// Copyright (C) Microsoft Corporation, 1987 - 1999
//
// Module Name:
//
// route.c
//
// Abstract:
//
// Queries into network drivers
//
// Author:
//
// Anilth - 4-20-1998
//
// Environment:
//
// User mode only.
// Contains NT-specific code.
//
// Revision History:
//
//--
#include "precomp.h"
//
// Rajkumar - Two Functions from iphlpapi.dll
//
DWORD WINAPI GetIpAddrTable( OUT PMIB_IPADDRTABLE pIpAddrTable, IN OUT PULONG pdwSize, IN BOOL bOrder );
DWORD InternalGetIpForwardTable( OUT MIB_IPFORWARDTABLE **ppIpForwardTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ); //--------------------------------------------------------
//functions defined in this file
void MapInterface(char *IPAddr, ULONG IfIndex); BOOLEAN ImprovedInetAddr(char *AddressString, ULONG *AddressValue);
HRESULT PrintRoute( NETDIAG_RESULT *pResults, char *Dest, ULONG DestVal, char *Gate, ULONG GateVal, BOOLEAN Persistent, const char * DestPat );
LPCTSTR PrintRouteEntry( ULONG Dest, ULONG Mask, ULONG Gate, ULONG Interface, ULONG Metric1 );
HRESULT PrintPersistentRoutes( NETDIAG_RESULT *pResults, char* Dest, ULONG DestVal, char* Gate, ULONG GateVal );
BOOL RouteTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) /*++
Routine Description:
Enumerate the static and persistent entries in the routing table
Arguments:
None.
Return Value: TRUE
Author: Rajkumar 06/27/98
--*/ { HRESULT hr = S_OK;
//$REVIEW only perform the test when is really verbose
if (!pParams->fReallyVerbose) return hr;
PrintStatusMessage( pParams, 4, IDS_ROUTE_STATUS_MSG ); //
// Print all static entries in the ip forward table
//
hr = PrintRoute(pResults, "*", WILD_CARD, "*", WILD_CARD, TRUE, "*" );
//
// Print all the persistent route entries
//
if( S_OK == hr ) hr = PrintPersistentRoutes(pResults, "*", WILD_CARD, "*", WILD_CARD );
pResults->Route.hrTestResult = hr; return hr;
}
HRESULT PrintRoute( NETDIAG_RESULT *pResults, char *Dest, ULONG DestVal, char *Gate, ULONG GateVal, BOOLEAN Persistent, const char * DestPat ) /*++
Routine Description: This routine prints all the static entries in then IP forward table. The entry in the routing table is declared static if the type of the entry is MIB_IPPROTO_LOCAL.
Arguments:
char *Dest: pointer to destination IP address string. This is NULL if no value was provided/no filtering desired. ULONG DestVal: value of destination IP address to filter route table with. If Dest is NULL, this is ignored. char *Gate: pointer to gateway IP address string. This is NULL if no value was provided/no filtering desired. ULONG GateVal: value of gateway IP address to filter route table with. If Gate is NULL, this is ignored. BOOL Persistent: set if persistent routes are to be printed. Returns: ULONG
Can also be found in nt\private\net\sockets\tcpcmd\route\route.c --*/ { int printcount = 0; int dwResult, j, k, err, alen; DWORD i; PMIB_IPFORWARDTABLE prifRouteTable = NULL; PMIB_IFTABLE pIfTable = NULL;
// ====================================================================
// Get Route Table.
pResults->Route.dwNumRoutes = 0; InitializeListHead(&pResults->Route.lmsgRoute);
dwResult = InternalGetIpForwardTable(&prifRouteTable, GetProcessHeap(), HEAP_NO_SERIALIZE );
if(dwResult || !prifRouteTable){ DEBUG_PRINT(("GetIpForwardTable/2: err=%d, dwResult=%d\n", GetLastError(), dwResult )); return S_FALSE; }
if( ! prifRouteTable->dwNumEntries ) { return S_OK; }
for(i = 0; i < prifRouteTable->dwNumEntries; i++) { PMIB_IPFORWARDROW pfr = &prifRouteTable->table[i];
// Only print this entry if the destination matches the parameter
if( ( Dest != NULL ) && ( DestVal != WILD_CARD ) && ( pfr->dwForwardDest != DestVal ) && ( DestPat == NULL ) ) continue;
// Only print this entry if the Gateway matches the parameter
if( ( Gate != NULL ) && ( GateVal != WILD_CARD ) && ( pfr->dwForwardNextHop != GateVal ) ) continue;
if( DestPat ) { char DestStr[32]; NetpIpAddressToStr( pfr->dwForwardDest, DestStr ); if( ! match( DestPat, DestStr ) ) { TRACE_PRINT(("PrintRoute: skipping %s !~ %s\n", DestPat, DestStr )); continue; } }
// Either we have a match on Dest/Gateway or they are
// wildcard/don't care.
// Display the header first time.
// We are going to display only static routes
if ( printcount++ < 1 ) //IDS_ROUTE_14203 "Network Destination Netmask Gateway Interface Metric\n"
AddMessageToListId( &pResults->Route.lmsgRoute, Nd_ReallyVerbose, IDS_ROUTE_14203);
//IDS_ROUTE_14204 "%s\n"
AddMessageToList( &pResults->Route.lmsgRoute, Nd_ReallyVerbose, IDS_ROUTE_14204, PrintRouteEntry( pfr->dwForwardDest, pfr->dwForwardMask, pfr->dwForwardNextHop, pfr->dwForwardIfIndex, pfr->dwForwardMetric1) ); }
pResults->Route.dwNumRoutes = printcount;
HeapFree( GetProcessHeap(), HEAP_NO_SERIALIZE, pIfTable ); HeapFree( GetProcessHeap(), HEAP_NO_SERIALIZE, prifRouteTable);
return ( NO_ERROR ); }
LPCTSTR PrintRouteEntry( ULONG Dest, ULONG Mask, ULONG Gate, ULONG Interface, ULONG Metric1 ) /*++
Description: Formats and displays a single route entry.
Arguments: Dest: The destination address. Mask: The destination netmask. Gate: The first hop gateway address. Interface: The interface address for the gateway net. Metric1: The primary route metric.
Author: 07/01/98 Rajkumar
--*/ { static TCHAR s_szBuffer[512]; TCHAR szFormat[128]; char DestStr[32]; char GateStr[32]; char NetmaskStr[32]; char MetricStr[32]; char IfStr[32];
NetpIpAddressToStr( Dest, DestStr); NetpIpAddressToStr( Gate, GateStr); NetpIpAddressToStr( Mask, NetmaskStr);
MapInterface(IfStr,Interface);
if( Metric1 > MAX_METRIC ) Metric1 = MAX_METRIC;
sprintf( MetricStr, "%u", Metric1 );
//IDS_ROUTE_14205 "%16s %16s %16s %16s %6s"
LoadString(NULL, IDS_ROUTE_14205, szFormat, DimensionOf(szFormat)); assert(szFormat[0]); _stprintf(s_szBuffer, szFormat, DestStr, NetmaskStr, GateStr, IfStr, MetricStr); return s_szBuffer;
}
BOOLEAN ExtractRoute( char *RouteString, ULONG *DestVal, ULONG *MaskVal, ULONG *GateVal, ULONG *MetricVal ) /*++
Description: Extracts the dest, mask, and gateway from a persistent route string, as stored in the registry.
Arguments: RouteString : The string to parse. DestVal : The place to put the extracted destination MaskVal : The place to put the extracted mask GateVal : The place to put the extracted gateway MetricVal : The place to put the extracted metric
Author: 07/01/98 Rajkumar . Created.
--*/ { char *addressPtr = RouteString; char *indexPtr = RouteString; ULONG address; ULONG i; char saveChar; BOOLEAN EndOfString=FALSE;
//
// The route is laid out in the string as "Dest,Mask,Gateway,Mertic".
//
//
// set MetricVal to 1 to take care of persistent routes without the
// metric value
//
*MetricVal = 1;
for (i=0; i<4 && !EndOfString; i++) { //
// Walk the string to the end of the current item.
//
while (1) {
if (*indexPtr == '\0') {
if ((i >= 2) && (indexPtr != addressPtr)) { //
// End of string
//
EndOfString = TRUE; break; }
return(FALSE); }
if (*indexPtr == ROUTE_SEPARATOR) { break; }
indexPtr++; }
//
// NULL terminate the current substring and extract the address value.
//
saveChar = *indexPtr;
*indexPtr = '\0';
if (i==3) { address = atoi (addressPtr); } else if (!ImprovedInetAddr(addressPtr, &address)) { *indexPtr = saveChar; return(FALSE); }
*indexPtr = saveChar;
switch(i) { case 0: *DestVal = address; break; case 1: *MaskVal = address; break; case 2: *GateVal = address; break; case 3: *MetricVal = address; break; default: return FALSE; } addressPtr = ++indexPtr; }
return(TRUE); }
//
// Rajkumar - This function is based on route implementation
//
HRESULT PrintPersistentRoutes( NETDIAG_RESULT *pResults, char* Dest, ULONG DestVal, char* Gate, ULONG GateVal ) /*++
Routine Description: Displays the list of persistent routes
Arguments: Dest : The destination string. (display filter) DestVal : The numeric destination value. (display filter) Gate : The gateway string. (display filter) GateVal : The numeric gateway value. (display filter)
Returns: None
--*/ { //
// Delete this route from the PersistentRoutes list in the
// registry if it is there.
//
DWORD status; HKEY key; char valueString[ROUTE_DATA_STRING_SIZE]; DWORD valueStringSize; DWORD valueType; DWORD index = 0; ULONG dest, mask, gate, metric; BOOLEAN headerPrinted = FALSE; BOOLEAN match;
pResults->Route.dwNumPersistentRoutes = 0; InitializeListHead(&pResults->Route.lmsgPersistentRoute);
status = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\PersistentRoutes", &key);
if (status == ERROR_SUCCESS) {
while(1) {
valueStringSize = ROUTE_DATA_STRING_SIZE - 1;
status = RegEnumValueA( key, index++, valueString, &valueStringSize, NULL, &valueType, NULL, 0 );
if (status != ERROR_SUCCESS) { if ((status == ERROR_BUFFER_OVERFLOW) || (status == ERROR_MORE_DATA) ) { continue; } else break; }
if (valueType != REG_SZ) continue;
valueString[valueStringSize++] = '\0';
if ( !ExtractRoute( valueString, &dest, &mask, &gate, &metric ) ) { continue; }
//IDS_ROUTE_14207 "%s\n"
AddMessageToList( &pResults->Route.lmsgPersistentRoute, Nd_ReallyVerbose, IDS_ROUTE_14207, PrintRouteEntry(dest, mask, gate, 0, metric));
pResults->Route.dwNumPersistentRoutes++;
} // end while
CloseHandle(key); } else { DebugMessage2("RegOpenKeyA %s failed\n","Tcpip\\Parameters\\Persistent"); return S_FALSE; }
return S_OK; }
void MapInterface(char *IPAddr, ULONG IfIndex) {
DWORD IpAddrTableSize=0; PMIB_IPADDRTABLE pIpAddrTable=NULL; char *TempBuf; BOOL bOrder=TRUE; HRESULT hr; DWORD i;
sprintf(IPAddr,"%x",IfIndex);
hr=GetIpAddrTable(NULL, &IpAddrTableSize, bOrder);
if (hr != ERROR_SUCCESS && hr != ERROR_INSUFFICIENT_BUFFER) { DebugMessage("GetIpAddrTable() failed.\n"); return; }
pIpAddrTable=(PMIB_IPADDRTABLE) Malloc(IpAddrTableSize);
if (pIpAddrTable == NULL) { DebugMessage("Out of Memory in RouteTest::MapInterface().\n"); return; }
ZeroMemory( pIpAddrTable, IpAddrTableSize );
hr=GetIpAddrTable(pIpAddrTable, &IpAddrTableSize, bOrder);
if (hr != ERROR_SUCCESS) { DebugMessage("GetIpAddrTable() failed.\n"); Free(pIpAddrTable); return; }
for (i=0; i < pIpAddrTable->dwNumEntries; i++) { if ((pIpAddrTable->table[i].dwIndex == IfIndex) && (pIpAddrTable->table[i].dwAddr != 0) && (pIpAddrTable->table[i].wType & MIB_IPADDR_PRIMARY)) { TempBuf=inet_ntoa(*(struct in_addr*)&pIpAddrTable->table[i].dwAddr); if (!TempBuf) { break;; } strcpy(IPAddr, TempBuf); break; }
}
Free(pIpAddrTable); return; }
BOOLEAN ImprovedInetAddr( char *AddressString, ULONG *AddressValue ) /*++
Description: Converts an IP address string to its numeric equivalent.
Arguments: char *AddressString: The string to convert ULONG AddressValue : The place to store the converted value.
Returns: TRUE
Author: 07/01/98 Rajkumar . Created. --*/ { ULONG address = inet_addr(AddressString);
if (address == 0xFFFFFFFF) { if (strcmp(AddressString, "255.255.255.255") == 0) { *AddressValue = address; return(TRUE); }
return(FALSE); }
*AddressValue = address; return TRUE; }
void RouteGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { if (!pParams->fReallyVerbose) return;
if (pParams->fReallyVerbose || !FHrOK(pResults->Route.hrTestResult)) { PrintNewLine(pParams, 2); PrintTestTitleResult(pParams, IDS_ROUTE_LONG, IDS_ROUTE_SHORT, TRUE, pResults->Route.hrTestResult, 0); }
if( pParams->fReallyVerbose) { if( 0 == pResults->Route.dwNumRoutes) { //IDS_ROUTE_14201 "No Entries in the IP Forward Table\n"
PrintMessage( pParams, IDS_ROUTE_14201); } else { //IDS_ROUTE_14202 "Active Routes :\n"
PrintMessage( pParams, IDS_ROUTE_14202); PrintMessageList(pParams, &pResults->Route.lmsgRoute); }
if( 0 == pResults->Route.dwNumPersistentRoutes) { //IDS_ROUTE_14208 "No persistent route entries.\n"
PrintMessage( pParams, IDS_ROUTE_14208);
} else { //IDS_ROUTE_14206 "\nPersistent Route Entries: \n"
PrintMessage( pParams, IDS_ROUTE_14206); PrintMessageList(pParams, &pResults->Route.lmsgPersistentRoute); } }
}
void RoutePerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults) { if (!pParams->fReallyVerbose) return;
}
void RouteCleanup(IN NETDIAG_PARAMS *pParams, IN OUT NETDIAG_RESULT *pResults) { MessageListCleanUp(&pResults->Route.lmsgRoute); MessageListCleanUp(&pResults->Route.lmsgPersistentRoute); }
|