windows-nt/Source/XPSP1/NT/net/rras/ras/ppp/rasiphlp/rastcp.c

787 lines
19 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
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);
}
VOID
RasTcpSetDhcpRoutes ( PBYTE pbRouteInfo, IPADDR ipAddrLocal, BOOL fSet )
{
//parse the byte stream and decode destination descriptors to get the subnet number and subnet mask.
//The format of the stream is as follows
//+------------------------------------------------------------------------------------
//+Code | Len | d1 | ... | dn | r1 | r2 | r3 | r4 | d1 | ... | dn | r1 | r2 | r3 | r4 |
//+------------------------------------------------------------------------------------
//length of code = 1 octet
//length of Len = 1 octet
//Length of each d1 ... dn - 1 octet
//Length of each r1 - r4 = 1 octet.
BYTE dwAddrMaskLookup [] = {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF };
PBYTE pbRover = pbRouteInfo + 1;
BYTE bLen = pbRouteInfo[0];
TraceHlp ( "RasTcpSetDhcpRoutes Begin");
while ( pbRover < pbRouteInfo + 1 + bLen )
{
unsigned char ipszdest[5] = {0};
unsigned char ipszsnetmask[5] = {0};
unsigned char ipsznexthop[5] = {0};
IPADDR ipdest = 0;
IPADDR ipmask = 0;
IPADDR ipnexthop = 0;
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 );
/*
//now set the route
ipdest = inet_addr ((const char FAR *)ipszdest);
ipmask = inet_addr ((const char FAR *)ipszsnetmask);
ipnexthop = inet_addr ((const char FAR *)ipsznexthop);
*/
ipdest = *((ULONG *)ipszdest);
ipmask = *((ULONG *)ipszsnetmask);
ipnexthop = *((ULONG *)ipsznexthop);
RasTcpSetRoute( ipdest,
ipAddrLocal,
ipmask,
ipAddrLocal,
fSet,
1,
TRUE
);
pbRover +=4;
}
}
done:
TraceHlp ( "RasTcpSetDhcpRoutes End");
return;
}