Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

822 lines
20 KiB

/*
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;
}