|
|
#include "inc.h"
CMD_ENTRY g_rgRouteCmdTable[] = { {TOKEN_ADD, AddRoute}, {TOKEN_DELETE, DeleteRoute}, {TOKEN_PRINT, PrintRoute}, {TOKEN_MATCH, MatchRoute}, {TOKEN_ENABLE, EnableRoute}, };
VOID HandleRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { LONG lIndex;
if(lNumArgs < 2) { DisplayMessage(HMSG_ROUTE_USAGE);
return; }
lIndex = ParseCommand(g_rgRouteCmdTable, sizeof(g_rgRouteCmdTable)/sizeof(CMD_ENTRY), rgpwszArgs[1]);
if(lIndex is -1) { DisplayMessage(HMSG_ROUTE_USAGE);
return; }
g_rgRouteCmdTable[lIndex].pfnHandler(lNumArgs - 1, &rgpwszArgs[1]);
return; }
VOID PrintRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { DWORD dwResult; PMIB_IPFORWARDTABLE pTable; ULONG i;
dwResult = AllocateAndGetIpForwardTableFromStack(&pTable, TRUE, GetProcessHeap(), HEAP_NO_SERIALIZE);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_RTTABLE);
if(pwszEntry) { DisplayMessage(EMSG_RETRIEVAL_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_RETRIEVAL_ERROR2, dwResult); }
return; }
if(pTable->dwNumEntries is 0) { PWCHAR pwszEntryType;
pwszEntryType = MakeString(TOKEN_ROUTE);
if(pwszEntryType) { DisplayMessage(EMSG_NO_ENTRIES1, pwszEntryType); FreeString(pwszEntryType); } else { DisplayMessage(EMSG_NO_ENTRIES2); }
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable);
return; } DisplayMessage(MSG_RTTABLE_HDR);
for(i = 0; i < pTable->dwNumEntries; i++) { ADDR_STRING rgwcDest, rgwcMask, rgwcNHop;
NetworkToUnicode(pTable->table[i].dwForwardDest, rgwcDest);
NetworkToUnicode(pTable->table[i].dwForwardMask, rgwcMask);
NetworkToUnicode(pTable->table[i].dwForwardNextHop, rgwcNHop);
wprintf(L"%-15s\t%-15s\t%-15s\t%8d\t%4d\t%4d\n", rgwcDest, rgwcMask, rgwcNHop, pTable->table[i].dwForwardIfIndex, pTable->table[i].dwForwardMetric1, pTable->table[i].dwForwardProto); } HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable); }
VOID AddRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { DWORD dwResult, dwMask, dwDest, dwNHop, dwMetric, dwIfIndex; BOOL bValid; ULONG i;
PMIB_IPADDRTABLE pTable; MIB_IPFORWARDROW Route;
//
// Parse the rest of the arguments
// The command line at this point should read:
// ADD <dest> MASK <mask> <nhop> [IF <ifIndex>] [METRIC <metric>]
//
if(lNumArgs < 5) { DisplayMessage(HMSG_ROUTE_ADD_USAGE);
return; }
if(!MatchToken(rgpwszArgs[2], TOKEN_MASK)) { DisplayMessage(HMSG_ROUTE_ADD_USAGE); return; } dwDest = UnicodeToNetwork(rgpwszArgs[1]); dwMask = UnicodeToNetwork(rgpwszArgs[3]); dwNHop = UnicodeToNetwork(rgpwszArgs[4]);
do { DWORD dwTestMask, i, dwNMask;
dwTestMask = 0;
if(dwMask is 0) { bValid = TRUE;
break; }
bValid = FALSE;
for(i = 0; bValid or (i < 32); i++) { dwTestMask = 0x80000000 | (dwTestMask >> 1);
dwNMask = RtlUlongByteSwap(dwTestMask);
if(dwMask is dwNMask) { bValid = TRUE;
break; } }
}while(FALSE);
if(dwDest is INADDR_NONE) { DisplayMessage(EMSG_RT_BAD_DEST);
return; }
if(dwNHop is INADDR_NONE) { DisplayMessage(EMSG_RT_BAD_NHOP);
return; }
if(bValid isnot TRUE) { DisplayMessage(EMSG_RT_BAD_MASK);
return; }
if((dwDest & dwMask) isnot dwDest) { DisplayMessage(EMSG_RT_BAD_DEST);
return; }
//
// See if we have an index or metric
//
dwIfIndex = (DWORD)-1; dwMetric = 1; if(lNumArgs > 5) { if((lNumArgs isnot 7) and (lNumArgs isnot 9)) { DisplayMessage(HMSG_ROUTE_ADD_USAGE);
return; }
if(!MatchToken(rgpwszArgs[5], TOKEN_INTERFACE)) { DisplayMessage(HMSG_ROUTE_ADD_USAGE);
return; }
dwIfIndex = wcstoul(rgpwszArgs[6], NULL, 10);
if(lNumArgs is 9) { if(!MatchToken(rgpwszArgs[7], TOKEN_METRIC)) { DisplayMessage(HMSG_ROUTE_ADD_USAGE);
return; }
dwMetric = wcstoul(rgpwszArgs[8], NULL, 10); }
if((dwIfIndex && dwMetric) is 0) { DisplayMessage(EMSG_RT_ZERO_IF_METRIC);
return; } }
//
// Get the address table
//
dwResult = AllocateAndGetIpAddrTableFromStack(&pTable, FALSE, GetProcessHeap(), HEAP_NO_SERIALIZE);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_ADDRTABLE);
if(pwszEntry) { DisplayMessage(EMSG_RETRIEVAL_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_RETRIEVAL_ERROR2, dwResult); }
return; }
bValid = FALSE;
for(i = 0; i < pTable->dwNumEntries; i++) { DWORD dwNet;
if((pTable->table[i].dwAddr is 0) or (pTable->table[i].dwMask is 0)) { continue; }
if(dwIfIndex isnot (DWORD)-1) { if(pTable->table[i].dwIndex is dwIfIndex) { if(pTable->table[i].dwMask is 0xFFFFFFFF) { //
// cant do a next hop check
//
bValid = TRUE;
break; }
dwNet = pTable->table[i].dwAddr & pTable->table[i].dwMask;
if((dwNHop & pTable->table[i].dwMask) is dwNet) { bValid = TRUE;
break; } } } else { //
// Dont have an interface index
// See if we can find an network on which the next hop lies
//
dwNet = pTable->table[i].dwAddr & pTable->table[i].dwMask;
if((dwNHop & pTable->table[i].dwMask) is dwNet) { bValid = TRUE;
dwIfIndex = pTable->table[i].dwIndex;
break; } } }
if(!bValid) { DisplayMessage(EMSG_RT_BAD_IF_NHOP);
return; }
ZeroMemory(&Route, sizeof(MIB_IPFORWARDROW));
Route.dwForwardDest = dwDest; Route.dwForwardMask = dwMask; Route.dwForwardNextHop = dwNHop; Route.dwForwardIfIndex = dwIfIndex; Route.dwForwardMetric1 = dwMetric; Route.dwForwardProto = MIB_IPPROTO_LOCAL;
if((dwDest is pTable->table[i].dwAddr) or (dwDest is dwNHop)) { Route.dwForwardType = MIB_IPROUTE_TYPE_DIRECT; } else { Route.dwForwardType = MIB_IPROUTE_TYPE_INDIRECT; }
dwResult = SetIpForwardEntryToStack(&Route);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_RTENTRY);
if(pwszEntry) { DisplayMessage(EMSG_SET_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_SET_ERROR2, dwResult); } } HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable); }
VOID DeleteRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { DWORD dwResult, dwMask, dwDest, dwNHop, dwIfIndex; BOOL bAny; ULONG i;
PMIB_IPFORWARDTABLE pTable; PMIB_IPFORWARDROW pRoute;
//
// Parse the rest of the arguments
// The command line at this point should read:
// DELETE <dest> [MASK <mask>] [<nhop>] [IF <ifIndex>]
//
if(lNumArgs < 2) { DisplayMessage(HMSG_ROUTE_DELETE_USAGE);
return; }
dwDest = UnicodeToNetwork(rgpwszArgs[1]);
if((lNumArgs > 2) and (lNumArgs isnot 7)) { DisplayMessage(HMSG_ROUTE_DELETE_USAGE);
return; }
bAny = TRUE;
if(lNumArgs is 7) { if(!MatchToken(rgpwszArgs[2], TOKEN_MASK)) { DisplayMessage(HMSG_ROUTE_DELETE_USAGE);
return; }
if(!MatchToken(rgpwszArgs[5], TOKEN_INTERFACE)) { DisplayMessage(HMSG_ROUTE_DELETE_USAGE);
return; }
dwMask = UnicodeToNetwork(rgpwszArgs[3]); dwNHop = UnicodeToNetwork(rgpwszArgs[4]); dwIfIndex = wcstoul(rgpwszArgs[6], NULL, 10);
if((dwNHop is INADDR_NONE) or (dwIfIndex is 0)) { DisplayMessage(HMSG_ROUTE_DELETE_USAGE);
return; }
bAny = FALSE; }
//
// Get the route table and see if such a route exists
//
dwResult = AllocateAndGetIpForwardTableFromStack(&pTable, TRUE, GetProcessHeap(), HEAP_NO_SERIALIZE);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_RTTABLE);
if(pwszEntry) { DisplayMessage(EMSG_RETRIEVAL_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_RETRIEVAL_ERROR2, dwResult); }
return; }
if(pTable->dwNumEntries is 0) { PWCHAR pwszEntryType;
pwszEntryType = MakeString(TOKEN_ROUTE);
if(pwszEntryType) { DisplayMessage(EMSG_NO_ENTRIES1, pwszEntryType);
FreeString(pwszEntryType); } else { DisplayMessage(EMSG_NO_ENTRIES2); }
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable);
return; }
pRoute = NULL;
for(i = 0; i < pTable->dwNumEntries; i++) { if(pTable->table[i].dwForwardDest is dwDest) { if(bAny) { if((i is (pTable->dwNumEntries - 1)) or (pTable->table[i + 1].dwForwardDest isnot dwDest)) { //
// Unique entry
//
pRoute = &(pTable->table[i]); }
break; } else { //
// Do an exact match
//
if((pTable->table[i].dwForwardMask is dwMask) and (pTable->table[i].dwForwardNextHop is dwNHop) and (pTable->table[i].dwForwardIfIndex is dwIfIndex)) { pRoute = &(pTable->table[i]);
break; } } } }
if(pRoute is NULL) { DisplayMessage(EMSG_UNIQUE_ROUTE_ABSENT);
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable);
return; }
pRoute->dwForwardType = MIB_IPROUTE_TYPE_INVALID;
dwResult = SetIpForwardEntryToStack(pRoute);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_RTENTRY);
if(pwszEntry) { DisplayMessage(EMSG_SET_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_SET_ERROR2, dwResult); } }
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pTable);
}
VOID MatchRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { DWORD dwResult, dwDest, dwSrc;
ADDR_STRING rgwcDest, rgwcMask, rgwcNHop; MIB_IPFORWARDROW Route;
//
// Command line should be MATCH <dest> [SRC <srcAddr>]
//
if(lNumArgs < 2) { DisplayMessage(HMSG_ROUTE_MATCH_USAGE);
return; }
dwSrc = 0;
if(lNumArgs > 2) { if(lNumArgs isnot 4) { DisplayMessage(HMSG_ROUTE_MATCH_USAGE);
return; }
if(!MatchToken(rgpwszArgs[2], TOKEN_SRC)) { DisplayMessage(HMSG_ROUTE_MATCH_USAGE);
return; }
dwSrc = UnicodeToNetwork(rgpwszArgs[3]); }
dwDest = UnicodeToNetwork(rgpwszArgs[1]);
dwResult = GetBestRouteFromStack(dwDest, dwSrc, &Route);
if(dwResult isnot NO_ERROR) { PWCHAR pwszEntry;
pwszEntry = MakeString(STR_RTENTRY);
if(pwszEntry) { DisplayMessage(EMSG_RETRIEVAL_ERROR1, dwResult, pwszEntry);
FreeString(pwszEntry); } else { DisplayMessage(EMSG_RETRIEVAL_ERROR2, dwResult); }
return; }
NetworkToUnicode(Route.dwForwardDest, rgwcDest);
NetworkToUnicode(Route.dwForwardMask, rgwcMask);
NetworkToUnicode(Route.dwForwardNextHop, rgwcNHop);
DisplayMessage(MSG_RTTABLE_HDR);
wprintf(L"%-15s\t%-15s\t%-15s\t%-4d\t%d\t%4d\n", rgwcDest, rgwcMask, rgwcNHop, Route.dwForwardIfIndex, Route.dwForwardMetric1, Route.dwForwardProto); }
VOID EnableRoute( LONG lNumArgs, PWCHAR rgpwszArgs[] ) { const WCHAR Empty[] = L""; UNICODE_STRING BindList; HKEY Key; UNICODE_STRING LowerComponent; IP_PNP_RECONFIG_REQUEST Request; UINT status; const WCHAR Tcpip[] = L"Tcpip"; const TCHAR TcpipParameters[] = TEXT("System\\CurrentControlSet\\Services\\Tcpip\\Parameters"); UNICODE_STRING UpperComponent; RtlInitUnicodeString(&BindList, Empty); RtlInitUnicodeString(&LowerComponent, Empty); RtlInitUnicodeString(&UpperComponent, Tcpip); Request.version = IP_PNP_RECONFIG_VERSION; Request.NextEntryOffset = 0; Request.arpConfigOffset = 0; Request.IPEnableRouter = TRUE; Request.Flags = IP_PNP_FLAG_IP_ENABLE_ROUTER; status = NdisHandlePnPEvent(NDIS, RECONFIGURE, &LowerComponent, &UpperComponent, &BindList, &Request, sizeof(Request) ); if (!status) { DisplayMessage(EMSG_ROUTE_ENABLE, GetLastError()); }
if (RegOpenKey(HKEY_LOCAL_MACHINE, TcpipParameters, &Key) == NO_ERROR) { status = TRUE; RegSetValueEx(Key, TEXT("IPEnableRouter"), 0, REG_DWORD, (PBYTE)&status, sizeof(status) ); RegCloseKey(Key); } }
|