|
|
/*
Copyright (c) 1998, Microsoft Corporation, all rights reserved
Description:
History:
*/
#include "rastcp_.h"
/*
Returns:
Description:
*/
IPADDR RasTcpDeriveMask( IN IPADDR nboIpAddr ) { IPADDR nboMask = 0; IPADDR hboMask = 0;
if (CLASSA_NBO_ADDR(nboIpAddr)) { hboMask = CLASSA_HBO_ADDR_MASK; } else if (CLASSB_NBO_ADDR(nboIpAddr)) { hboMask = CLASSB_HBO_ADDR_MASK; } else if (CLASSC_NBO_ADDR(nboIpAddr)) { hboMask = CLASSC_HBO_ADDR_MASK; }
nboMask = htonl(hboMask);
return(nboMask); }
/*
Returns: VOID
Description: Sets the ip address for proxy arp"ing" on all lan interfaces.
*/
VOID RasTcpSetProxyArp( IN IPADDR nboIpAddr, IN BOOL fAddAddress ) { MIB_IPADDRTABLE* pIpAddrTable = NULL; HANDLE hHeap = NULL; DWORD dwNboIpAddr; DWORD dwNboMask; DWORD dw; DWORD dwErr = NO_ERROR;
extern IPADDR RasSrvrNboServerIpAddress;
TraceHlp("RasTcpSetProxyArp(IP Addr: 0x%x, fAddAddress: %s)", nboIpAddr, fAddAddress ? "TRUE" : "FALSE");
hHeap = GetProcessHeap();
if (NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetProcessHeap failed and returned %d", dwErr); goto LDone; }
dwErr = PAllocateAndGetIpAddrTableFromStack(&pIpAddrTable, FALSE /* bOrder */, hHeap, LPTR);
if (NO_ERROR != dwErr) { TraceHlp("AllocateAndGetIpAddrTableFromStack failed and returned %d", dwErr); goto LDone; }
for (dw = 0; dw < pIpAddrTable->dwNumEntries; dw++) { dwNboIpAddr = pIpAddrTable->table[dw].dwAddr; dwNboMask = pIpAddrTable->table[dw].dwMask;
if ( (ALL_NETWORKS_ROUTE == dwNboIpAddr) || (HOST_MASK == dwNboIpAddr) || (RasSrvrNboServerIpAddress == dwNboIpAddr)) { continue; }
if ((nboIpAddr & dwNboMask) != (dwNboIpAddr & dwNboMask)) { continue; }
dwErr = PSetProxyArpEntryToStack(nboIpAddr, HOST_MASK, pIpAddrTable->table[dw].dwIndex, fAddAddress, FALSE);
if (NO_ERROR != dwErr) { TraceHlp("SetProxyArpEntryToStack on NIC with address 0x%x failed " "and returned 0x%x", dwNboIpAddr, dwErr);
dwErr = PSetProxyArpEntryToStack(nboIpAddr, HOST_MASK, pIpAddrTable->table[dw].dwIndex, fAddAddress, TRUE);
TraceHlp("SetProxyArpEntryToStack: 0x%x", dwErr); } }
LDone:
if ( (NULL != hHeap) && (NULL != pIpAddrTable)) { HeapFree(hHeap, 0, pIpAddrTable); }
return; }
/*
Returns: VOID
Description:
*/
VOID RasTcpSetRoute( IN IPADDR nboDestAddr, IN IPADDR nboNextHopAddr, IN IPADDR nboIpMask, IN IPADDR nboLocalAddr, IN BOOL fAddAddress, IN DWORD dwMetric, IN BOOL fSetToStack ) { MIB_IPADDRTABLE* pIpAddrTable = NULL; MIB_IPFORWARDROW IpForwardRow; HANDLE hHeap = NULL; DWORD dw; DWORD dwErr = NO_ERROR;
TraceHlp("RasTcpSetRoute(Dest: 0x%x, Mask: 0x%x, NextHop: 0x%x, " "Intf: 0x%x, %d, %s, %s)", nboDestAddr, nboIpMask, nboNextHopAddr, nboLocalAddr, dwMetric, fAddAddress ? "Add" : "Del", fSetToStack ? "Stack" : "Rtr");
ZeroMemory(&IpForwardRow, sizeof(IpForwardRow));
hHeap = GetProcessHeap();
if (NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetProcessHeap failed and returned %d", dwErr); goto LDone; }
dwErr = PAllocateAndGetIpAddrTableFromStack(&pIpAddrTable, FALSE /* bOrder */, hHeap, LPTR);
if (NO_ERROR != dwErr) { TraceHlp("AllocateAndGetIpAddrTableFromStack failed and returned %d", dwErr); goto LDone; }
for (dw = 0; dw < pIpAddrTable->dwNumEntries; dw++) { if (nboLocalAddr == pIpAddrTable->table[dw].dwAddr) { IpForwardRow.dwForwardDest = nboDestAddr; IpForwardRow.dwForwardMask = nboIpMask; IpForwardRow.dwForwardPolicy = 0; IpForwardRow.dwForwardNextHop = nboNextHopAddr; IpForwardRow.dwForwardIfIndex = pIpAddrTable->table[dw].dwIndex; IpForwardRow.dwForwardProto = IRE_PROTO_NETMGMT; IpForwardRow.dwForwardAge = (DWORD)-1; IpForwardRow.dwForwardNextHopAS = 0; IpForwardRow.dwForwardMetric1 = dwMetric; IpForwardRow.dwForwardMetric2 = (DWORD)-1; IpForwardRow.dwForwardMetric3 = (DWORD)-1; IpForwardRow.dwForwardMetric4 = (DWORD)-1; IpForwardRow.dwForwardMetric5 = (DWORD)-1; IpForwardRow.dwForwardType = (fAddAddress ? IRE_TYPE_DIRECT : IRE_TYPE_INVALID);
if (fSetToStack) { dwErr = PSetIpForwardEntryToStack(&IpForwardRow); } else { if (fAddAddress) { dwErr = PSetIpForwardEntry(&IpForwardRow); } else { dwErr = PDeleteIpForwardEntry(&IpForwardRow); } }
if (NO_ERROR != dwErr) { TraceHlp("SetIpForwardEntry%s failed and returned 0x%x", fSetToStack ? "ToStack" : "", dwErr); }
break; } }
LDone:
if ( (NULL != hHeap) && (NULL != pIpAddrTable)) { HeapFree(hHeap, 0, pIpAddrTable); }
return; }
VOID RasTcpSetRouteEx( IN IPADDR nboDestAddr, IN IPADDR nboNextHopAddr, IN IPADDR nboIpMask, IN IPADDR nboLocalAddr, IN BOOL fAddAddress, IN DWORD dwMetric, IN BOOL fSetToStack, IN GUID *pIfGuid ) { DWORD dwErr = NO_ERROR; HANDLE hHeap = NULL; IP_INTERFACE_NAME_INFO *pTable = NULL; DWORD dw; DWORD dwCount; MIB_IPFORWARDROW IpForwardRow; TraceHlp("RasTcpSetRouteEx(Dest: 0x%x, Mask: 0x%x, NextHop: 0x%x, " "Intf: 0x%x, %d, %s, %s)", nboDestAddr, nboIpMask, nboNextHopAddr, nboLocalAddr, dwMetric, fAddAddress ? "Add" : "Del", fSetToStack ? "Stack" : "Rtr");
hHeap = GetProcessHeap();
if(NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetPRocessHeap failed and returned %d", dwErr); goto LDone; }
ZeroMemory(&IpForwardRow, sizeof(MIB_IPFORWARDROW));
dwErr = PNhpAllocateAndGetInterfaceInfoFromStack(&pTable, &dwCount, FALSE /* bOrder */, hHeap, LPTR); for(dw = 0; dw < dwCount; dw++) { if(0 == memcmp(&pTable[dw].DeviceGuid, pIfGuid, sizeof(GUID))) { break; } }
if(dw == dwCount) { dwErr = ERROR_INVALID_PARAMETER; goto LDone; }
IpForwardRow.dwForwardDest = nboDestAddr; IpForwardRow.dwForwardMask = nboIpMask; IpForwardRow.dwForwardPolicy = 0;
if(nboDestAddr != ALL_NETWORKS_ROUTE) { IpForwardRow.dwForwardNextHop = nboNextHopAddr; } else { IpForwardRow.dwForwardNextHop = 0; } IpForwardRow.dwForwardIfIndex = pTable[dw].Index; IpForwardRow.dwForwardProto = IRE_PROTO_NETMGMT; IpForwardRow.dwForwardAge = (DWORD)-1; IpForwardRow.dwForwardNextHopAS = 0; IpForwardRow.dwForwardMetric1 = dwMetric; IpForwardRow.dwForwardMetric2 = (DWORD)-1; IpForwardRow.dwForwardMetric3 = (DWORD)-1; IpForwardRow.dwForwardMetric4 = (DWORD)-1; IpForwardRow.dwForwardMetric5 = (DWORD)-1; IpForwardRow.dwForwardType = (fAddAddress ? IRE_TYPE_DIRECT : IRE_TYPE_INVALID);
if (fSetToStack) { dwErr = PSetIpForwardEntryToStack(&IpForwardRow); } else { if (fAddAddress) { dwErr = PSetIpForwardEntry(&IpForwardRow); } else { dwErr = PDeleteIpForwardEntry(&IpForwardRow); } }
if (NO_ERROR != dwErr) { TraceHlp("SetIpForwardEntry%s failed and returned 0x%x", fSetToStack ? "ToStack" : "", dwErr); }
LDone:
if(NULL != pTable) { HeapFree(hHeap, 0, pTable); } }
/*
Returns: VOID
Description:
*/ #if 0
VOID RasTcpSetRoutesForNameServers( BOOL fSet ) { HANDLE hHeap = NULL; IP_INTERFACE_NAME_INFO* pTable = NULL; DWORD dw; DWORD dwCount; IPADDR nboIpAddress; IPADDR nboDNS1; IPADDR nboDNS2; IPADDR nboWINS1; IPADDR nboWINS2; IPADDR nboGateway; DWORD dwErr = NO_ERROR;
TraceHlp("RasTcpSetRoutesForNameServers. fSet=%d", fSet);
hHeap = GetProcessHeap();
if (NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetProcessHeap failed and returned %d", dwErr); goto LDone; }
dwErr = PNhpAllocateAndGetInterfaceInfoFromStack(&pTable, &dwCount, FALSE /* bOrder */, hHeap, LPTR);
if (NO_ERROR != dwErr) { TraceHlp("NhpAllocateAndGetInterfaceInfoFromStack failed and " "returned %d", dwErr); goto LDone; }
for (dw = 0; dw < dwCount; dw++) { dwErr = GetAdapterInfo( pTable[dw].Index, &nboIpAddress, &nboDNS1, &nboDNS2, &nboWINS1, &nboWINS2, &nboGateway, NULL);
if (NO_ERROR != dwErr) { dwErr = NO_ERROR; continue; }
if (0 != nboDNS1) { RasTcpSetRoute(nboDNS1, nboGateway, HOST_MASK, nboIpAddress, fSet, 1, TRUE); }
if (0 != nboDNS2) { RasTcpSetRoute(nboDNS2, nboGateway, HOST_MASK, nboIpAddress, fSet, 1, TRUE); }
if (0 != nboWINS1) { RasTcpSetRoute(nboWINS1, nboGateway, HOST_MASK, nboIpAddress, fSet, 1, TRUE); }
if (0 != nboWINS2) { RasTcpSetRoute(nboWINS2, nboGateway, HOST_MASK, nboIpAddress, fSet, 1, TRUE); } }
LDone:
if (NULL != pTable) { HeapFree(hHeap, 0, pTable); } }
#endif
//
//Bump up the metric of all the routes or reduce the metric
//of all multicase routes by 1
//
DWORD RasTcpAdjustMulticastRouteMetric ( IN IPADDR nboIpAddr, IN BOOL fSet ) { MIB_IPFORWARDTABLE* pIpForwardTable = NULL; MIB_IPFORWARDROW* pIpForwardRow; HANDLE hHeap = NULL; DWORD dw; DWORD dwErr = NO_ERROR;
TraceHlp("RasTcpAdjustMulticastRouteMetric(IP Addr: 0x%x, Set: %s)", nboIpAddr, fSet ? "TRUE" : "FALSE");
hHeap = GetProcessHeap();
if (NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetProcessHeap failed and returned %d", dwErr); goto LDone; }
dwErr = PAllocateAndGetIpForwardTableFromStack(&pIpForwardTable, FALSE /* bOrder */, hHeap, LPTR);
if (NO_ERROR != dwErr) { TraceHlp("AllocateAndGetIpAddrTableFromStack failed and returned %d", dwErr); goto LDone; } //
//Steps to follow:
// 1. Check to see if we have a default route for the interface with
// the ip address passed in.
// 2. If we do then bump up the metric for all interfaces with 0xE0
// as the forward dest.
// Else
// we have nothing to do.
// 3. Add an E0 route with a metric of 1.
for (dw = 0; dw < pIpForwardTable->dwNumEntries; dw++) { pIpForwardRow = pIpForwardTable->table + dw; if ( 0 == pIpForwardRow->dwForwardDest ) //default route
{ IPADDR nboIpIfIpAddr; //
//get the adapter information
//to see if the ip address matches
//
dwErr = GetAdapterInfo ( pIpForwardRow->dwForwardIfIndex, &nboIpIfIpAddr, NULL, NULL, NULL, NULL, NULL, NULL ); if ( NO_ERROR != dwErr ) { TraceHlp("GetAdapterInfo failed and returned %d", dwErr); goto LDone; } if ( nboIpAddr == nboIpIfIpAddr ) { DWORD dw1 = 0; MIB_IPFORWARDROW * pIpForwardRow1 = NULL; //
//This means that we have a default route. So we need to bump up the metric of
//all the E0 by 1
for ( dw1 = 0; dw1 < pIpForwardTable->dwNumEntries; dw1 ++ ) { pIpForwardRow1 = pIpForwardTable->table + dw1; if (0xE0 == pIpForwardRow1->dwForwardDest /* multicast route */) { if (fSet) { // Bump up metric (hop count)
pIpForwardRow1->dwForwardMetric1++; } else if (pIpForwardRow1->dwForwardMetric1 > 1) // Never make it 0!
{ // Bump down metric
pIpForwardRow1->dwForwardMetric1--; }
dwErr = PSetIpForwardEntryToStack(pIpForwardRow1);
if (NO_ERROR != dwErr) { TraceHlp("SetIpForwardEntryToStack failed and returned 0x%x" "dest=0x%x, nexthop=0x%x, mask=0x%x", dwErr, pIpForwardRow->dwForwardDest, pIpForwardRow->dwForwardNextHop, pIpForwardRow->dwForwardMask);
dwErr = NO_ERROR; } } } if ( fSet ) { //
//Set the multicast route metric on this interface
//to 1
RasTcpSetRoute( 0xE0, nboIpAddr, 0xF0, nboIpAddr, TRUE, 1, TRUE );
} break; }
}
}
LDone:
if ( (NULL != hHeap) && (NULL != pIpForwardTable)) { HeapFree(hHeap, 0, pIpForwardTable); }
return(dwErr);
} /*
Returns: Error codes from TCPConfig (your basic nt codes)
Description: fSet: If TRUE means set existing routes to higher metrics and add OVERRIDE routes. If FALSE means mark existing routes to lower metrics. */
DWORD RasTcpAdjustRouteMetrics( IN IPADDR nboIpAddr, IN BOOL fSet ) { MIB_IPFORWARDTABLE* pIpForwardTable = NULL; MIB_IPFORWARDROW* pIpForwardRow; HANDLE hHeap = NULL; DWORD dw; DWORD dwErr = NO_ERROR;
TraceHlp("RasTcpAdjustRouteMetrics(IP Addr: 0x%x, Set: %s)", nboIpAddr, fSet ? "TRUE" : "FALSE");
hHeap = GetProcessHeap();
if (NULL == hHeap) { dwErr = GetLastError(); TraceHlp("GetProcessHeap failed and returned %d", dwErr); goto LDone; }
dwErr = PAllocateAndGetIpForwardTableFromStack(&pIpForwardTable, FALSE /* bOrder */, hHeap, LPTR);
if (NO_ERROR != dwErr) { TraceHlp("AllocateAndGetIpAddrTableFromStack failed and returned %d", dwErr); goto LDone; }
for (dw = 0; dw < pIpForwardTable->dwNumEntries; dw++) { pIpForwardRow = pIpForwardTable->table + dw;
if (0 == pIpForwardRow->dwForwardDest /* default route */) { if (fSet) { // Bump up metric (hop count)
pIpForwardRow->dwForwardMetric1++; } else if (pIpForwardRow->dwForwardMetric1 > 1) // Never make it 0!
{ // Bump down metric
pIpForwardRow->dwForwardMetric1--; }
dwErr = PSetIpForwardEntryToStack(pIpForwardRow);
if (NO_ERROR != dwErr) { TraceHlp("SetIpForwardEntryToStack failed and returned 0x%x" "dest=0x%x, nexthop=0x%x, mask=0x%x", dwErr, pIpForwardRow->dwForwardDest, pIpForwardRow->dwForwardNextHop, pIpForwardRow->dwForwardMask);
dwErr = NO_ERROR; } } }
LDone:
if ( (NULL != hHeap) && (NULL != pIpForwardTable)) { HeapFree(hHeap, 0, pIpForwardTable); }
return(dwErr); }
/*
Returns:
Description:
Plumbs routes based on the information returned by Dhcp option OPTION_VENDOR_ROUTE_PLUMB (249). Information has the following format: +------------------------------------------------------------------------------------ + Len | d1 | ... | dn | r1 | r2 | r3 | r4 | d1 | ... | dn | r1 | r2 | r3 | r4 | +------------------------------------------------------------------------------------
length of Len = 4 octet Length of each d1 ... dn - 1 octet Length of each r1 - r4 = 1 octet. */ VOID RasTcpSetDhcpRoutes ( IN PBYTE pbRouteInfo, IN IPADDR ipAddrLocal, IN BOOL fSet ) { BYTE dwAddrMaskLookup [] = {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF };
PBYTE pbRover = pbRouteInfo + sizeof(DWORD); DWORD dwLen = *((DWORD *)pbRouteInfo); TraceHlp ( "RasTcpSetDhcpRoutes Begin"); while ( pbRover < pbRouteInfo + 1 + dwLen ) { unsigned char ipszdest[5]; unsigned char ipszsnetmask[5]; unsigned char ipsznexthop[5]; IPADDR ipdest = 0; IPADDR ipmask = 0; IPADDR ipnexthop = 0;
ZeroMemory(ipszdest, 5 * sizeof(unsigned char)); ZeroMemory(ipszsnetmask, 5 * sizeof(unsigned char)); ZeroMemory(ipsznexthop, 5 * sizeof(unsigned char)); if ( *pbRover > 32 ) { //
// Error. We cannot have more than 32 1's in the mask
//
TraceHlp("RasTcpSetDhcpRoutes: invalid destination " "descriptor first byte %d", *pbRover); goto done; } else { //
// set the subnet mask first
//
int n1 = (int)((*pbRover) / 8); int n2 = (int)((*pbRover) % 8 ); int i;
for ( i = 0; i < n1; i++) { ipszsnetmask[i] = (BYTE)0xFF; }
//
// set the final byte
//
if ( n2 ) { ipszsnetmask[3] = dwAddrMaskLookup[n2]; }
pbRover ++;
//
// now for the ip address
//
if ( n2 ) n1 ++;
for ( i = 0; i < n1; i ++ ) { ipszdest[i] = *pbRover; pbRover++; }
TraceHlp ( "RasTcpSetDhcpRoutes: Got route dest addr = ""%d.%d.%d.%d" " subnet mask = %d.%d.%d.%d " "route = %d.%d.%d.%d\n", ipszdest[0], ipszdest[1], ipszdest[2], ipszdest[3], ipszsnetmask[0], ipszsnetmask[1], ipszsnetmask[2], ipszsnetmask[3], *pbRover, *(pbRover+1),*(pbRover+2),*(pbRover+3) );
CopyMemory ( ipsznexthop, pbRover, 4 );
ipdest = *((ULONG *)ipszdest); ipmask = *((ULONG *)ipszsnetmask); ipnexthop = *((ULONG *)ipsznexthop);
RasTcpSetRoute( ipdest, ipAddrLocal, ipmask, ipAddrLocal, fSet, 1, TRUE ); pbRover +=4; } } done:
TraceHlp ( "RasTcpSetDhcpRoutes End"); return; }
|