📄 ip_intf.c
字号:
//
// So, we set the subnet mask so that there is no subnet route added to the route table.
//
dwSubNetMask = 0xFFFFFFFF;
}
RegSetIPAddrMultiSzValue(hKey, TEXT("IpAddress"), &dwIPAddr, NULL);
RegSetIPAddrMultiSzValue(hKey, TEXT("Subnetmask"), &dwSubNetMask, NULL);
RegSetIPAddrMultiSzValue(hKey, TEXT("DefaultGateway"), &dwDefaultGatewayIPAddr, NULL);
RegSetIPAddrMultiSzValue(hKey, TEXT("DNS"), &s_p->rasEntry.ipaddrDns, &s_p->rasEntry.ipaddrDnsAlt, NULL);
RegSetIPAddrMultiSzValue(hKey, TEXT("WINS"), &s_p->rasEntry.ipaddrWins, &s_p->rasEntry.ipaddrWinsAlt, NULL);
RegCloseKey (hKey);
*pdwDefaultGateway = dwDefaultGatewayIPAddr;
return TRUE;
}
int
__stdcall
PPPDynRegister(
PWSTR Adapter,
void *IPContext,
IPRcvRtn RcvRtn,
IPTxCmpltRtn TxCmpltRtn,
IPStatusRtn StatusRtn,
IPTDCmpltRtn TDCmpltRtn,
IPRcvCmpltRtn RcvCmpltRtn,
IPSetNTEAddrRtn IPSetNTEAddrRtn,
struct LLIPBindInfo *Info,
uint NumIFBound)
//
// This function is called back by IP when PPPBindNewAdapter calls IPAddInterface.
//
{
PPP_CONTEXT *pContext = (PPP_CONTEXT *)Info->lip_context;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+PPPDynRegister: %s\n"), Adapter));
pContext->IPContext = IPContext;
pContext->index = NumIFBound;
// Save IP's functions.
IPRcv = RcvRtn;
IPSendComplete = TxCmpltRtn;
IPStatus = StatusRtn;
IPTDComplete = TDCmpltRtn;
IPRcvComplete = RcvCmpltRtn;
IPSetNTEAddr = IPSetNTEAddrRtn;
// TCPTRACE(("Arp Interface %lx ai_context %lx ai_index %lx\n",Interface, Interface->ai_context, Interface->ai_index));
return TRUE;
}
HINSTANCE g_IpHlpApiMod;
typedef DWORD (*pfnGetIpForwardTable) (PMIB_IPFORWARDTABLE pIpForwardTable,PULONG pdwSize,BOOL bOrder);
pfnGetIpForwardTable g_pfnGetIpForwardTable;
typedef DWORD (*pfnSetIpForwardEntry) (PMIB_IPFORWARDROW pRoute);
pfnSetIpForwardEntry g_pfnSetIpForwardEntry;
void
PPPChangeDefaultRoutesMetric(
IN int metricDelta)
//
// Modify the Metric1 for the default routes in the net table by the specified delta.
//
{
int newMetric;
PMIB_IPFORWARDTABLE pTable;
DWORD dwTableSize;
PMIB_IPFORWARDROW pRow;
DWORD numRoutes,
dwResult;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +ChangeDefaultRoutesMetric delta=%d\n"), metricDelta));
if (!g_IpHlpApiMod)
{
dwResult = CXUtilGetProcAddresses(TEXT("iphlpapi.dll"), &g_IpHlpApiMod,
TEXT("GetIpForwardTable"), &g_pfnGetIpForwardTable,
TEXT("SetIpForwardEntry"), &g_pfnSetIpForwardEntry,
NULL);
if (dwResult != NO_ERROR)
{
RETAILMSG(1,(TEXT("!PPPChangeDefaultRoutesMetric could not load IPHlpAPI fcn pointers, RASDefaultGateway option disabled\r\n")));
return;
}
}
dwTableSize = 0;
g_pfnGetIpForwardTable(NULL, &dwTableSize, FALSE);
pTable = pppAllocateMemory(dwTableSize);
if (pTable == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR, unable to allocate %d bytes for route table \n"), dwTableSize));
}
else
{
dwResult = g_pfnGetIpForwardTable(pTable, &dwTableSize, FALSE);
if (dwResult != ERROR_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR %d from GetIpForwardTable\n"), dwResult));
}
else
{
for (pRow = &pTable->table[0], numRoutes = pTable->dwNumEntries;
numRoutes--;
pRow++)
{
// Check to see if the route is a default route
if (pRow->dwForwardDest == 0)
{
newMetric = pRow->dwForwardMetric1 + metricDelta;
// Don't try to reduce a metric below 1.
if (newMetric > 0)
{
pRow->dwForwardMetric1 = (ULONG)newMetric;
if (pRow->dwForwardType == 4 /*IRE_TYPE_INDIRECT*/)
pRow->dwForwardType = 3 /*IRE_TYPE_DIRECT*/;
dwResult = g_pfnSetIpForwardEntry(pRow);
if (dwResult != NO_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR %d from SetIPForwardEntry\n"), dwResult));
}
}
}
}
}
pppFreeMemory(pTable, dwTableSize);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -ChangeDefaultRoutesMetric\n")));
}
#define IPADDROUT(a) (a)>>24, ((a)>>16)&0xFF, ((a)>>8)&0xFF, (a)&0xFF
void
PPPMakeDefaultRoute(
DWORD IPAddrGateway,
DWORD IfIndex)
//
// Set the default route for the interface to have a metric of 1,
// so it becomes the cheapest default route.
//
{
MIB_IPFORWARDROW row;
DWORD dwResult;
if (g_pfnSetIpForwardEntry)
{
memset(&row, 0, sizeof(row));
// row.dwForwardDest = 0.0.0.0
// row.dwForwardMask = 0.0.0.0
// row.dwForwardPolicy = 0;
row.dwForwardNextHop = htonl(IPAddrGateway);
row.dwForwardIfIndex = IfIndex;
row.dwForwardType = 3 /*IRE_TYPE_DIRECT*/;
row.dwForwardProto = PROTO_IP_NETMGMT;
// row.dwForwardAge = 0;
// row.dwForwardNextHopAS = 0;
row.dwForwardMetric1 = 1;
DEBUGMSG(1, (TEXT("PPP: MakeDefaultRoute to %u.%u.%u.%u for IF %u\n"), IPADDROUT(IPAddrGateway), IfIndex));
dwResult = g_pfnSetIpForwardEntry(&row);
if (dwResult != NO_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR %d from SetIPForwardEntry\n"), dwResult));
}
}
}
BOOL
PPPAddInterface(
PPP_CONTEXT *pContext)
//
// This function is called by the ppp protocol driver to notify
// IP that a new wan adapter instance has been created.
//
{
struct LLOldIPBindInfo Info;
IP_STATUS Status;
NDIS_STRING ndsAdapterName,
ndsConfigName;
TCHAR tszKeyName[128];
BOOL bResult;
DWORD dwDefaultGateway;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+PPPAddInterface: %s\n"), &pContext->AdapterName[0]));
// Setup registry info, including NoDhcp, IP address, subnet, DNS, WINS addresses,
// before telling IP about the new adapter.
ndsConfigName.Length = 0;
ndsConfigName.MaximumLength = sizeof(tszKeyName);
ndsConfigName.Buffer = &tszKeyName[0];
PPPSetAdapterIPRegistrySettings(pContext, &ndsConfigName, &dwDefaultGateway);
memset(&Info, 0, sizeof(Info));
Info.lip_context = pContext;
pppMac_GetCallSpeed(pContext->Session->macCntxt, &Info.lip_speed);
DEBUGMSG(ZONE_PPP, (TEXT("PPP: Interface Bit Rate is %u b/s\n"), Info.lip_speed));
Info.lip_transmit = Transmit;
Info.lip_transfer = XferData;
Info.lip_close = Close;
Info.lip_invalidate = Invalidate;
Info.lip_addaddr = AddAddr;
Info.lip_deladdr = DeleteAddr;
Info.lip_open = Open;
Info.lip_qinfo = QueryInfo;
Info.lip_setinfo = SetInfo;
Info.lip_getelist = GetEList;
Info.lip_flags = LIP_P2P_FLAG | LIP_COPY_FLAG ;
if (pContext->Session->Mode == PPPMODE_PPP)
{
// Set the IP MaxSegmentSize (MSS) to the maximum frame size that the PPP peer can
// receive. This usually is 1500, but the adapter (e.g. AsyncMac) may restrict
// the max send size and/or it may be changed during LCP negotiation by the peer sending
// a Maximum-Receive-Unit option.
Info.lip_mss = ((PLCPContext)(pContext->Session->lcpCntxt))->peer.MRU;
}
else // SLIP
{
Info.lip_mss = SLIP_DEFAULT_MTU;
}
Info.lip_addrlen = ARP_802_ADDR_LENGTH ;
Info.lip_addr = pContext->addr; // This never seems to be used.
Info.lip_arpresolveip = NULL;
//
// If the RAS option to make the new PPP connection be the default gateway has been
// set, then increment the cost (metric) of all the current default routes by 1 so
// that the new PPP connection will be chosen.
//
if (pContext->Session->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway)
{
PPPChangeDefaultRoutesMetric(1);
}
RtlInitUnicodeString(&ndsAdapterName, &pContext->AdapterName[0]);
Status = g_pfnIPAddInterface(&ndsAdapterName, &ndsConfigName, NULL, pContext, PPPDynRegister, &Info);
if (Status != IP_SUCCESS)
{
if (pContext->Session->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway)
{
PPPChangeDefaultRoutesMetric(-1);
}
bResult = FALSE;
}
else
{
if (pContext->Session->bIsServer)
{
PPPServerAddRouteToClient(pContext->Session);
}
else if (pContext->Session->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway)
{
// To make the new interface be the default route, set the metric for it to 1
PPPMakeDefaultRoute(dwDefaultGateway, pContext->index);
}
bResult = TRUE;
}
DEBUGMSG(ZONE_FUNCTION || (ZONE_ERROR && bResult == FALSE),
(TEXT("-PPPAddInterface: %s, result=%d\n"), &pContext->AdapterName[0], bResult));
return bResult;
}
void
PPPDeleteInterface(
PPP_CONTEXT *pContext,
pppSession_t *pSession)
//
// This function is called by the ppp protocol driver to notify
// IP that a WAN link is no longer available.
//
{
PVOID pIPContext;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+PPPDeleteInterface: %s\n"), &pContext->AdapterName[0]));
pIPContext = (PVOID)InterlockedExchange((PULONG)&pContext->IPContext, (LONG)NULL);
if (pIPContext)
{
if (pSession->bIsServer)
{
PPPServerDeleteRouteToClient(pSession);
}
//
// If we incremented the default routes when we added this interface, undo it.
//
if (pSession->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway)
{
PPPChangeDefaultRoutesMetric(-1);
}
g_pfnIPDelInterface(pIPContext);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("-PPPDeleteInterface: %s\n"), &pContext->AdapterName[0]));
}
void
SetPPPPeerIPAddress(
PPP_CONTEXT *pppContext)
//
// Set the IP address that the name "ppp_peer" will resolve to.
// Note that this name is only present for internal use.
//
// If pppContext is NULL, then the ppp_peer name is set to
// no longer be resolvable to an IP address.
//
{
char **pppAddr = NULL;
DWORD pAddr[2];
char *ppAddr[2];
if (pppContext != NULL)
{
pppSession_t *s_p = (pppSession_t *)pppContext->Session;
ncpCntxt_t *ncp_p = (ncpCntxt_t *)s_p->ncpCntxt;
ipcpCntxt_t *ipcp_p = (ipcpCntxt_t *)ncp_p->protocol[ NCP_IPCP ].context;
pppAddr = &ppAddr[0];
// Set peer's IP address into hosts file
ppAddr[0] = (char *)&pAddr[0];
ppAddr[1] = NULL;
pAddr[0] = htonl(ipcp_p->peer.ipAddress);
pAddr[1] = 0; // don't actually need this but to be safe
DEBUGMSG(ZONE_PPP, (TEXT("PPP: Setting ppp_peer IPAddr = %x\n"), pAddr[0]));
}
else
{
DEBUGMSG(ZONE_PPP, (TEXT("PPP: Clearing ppp_peer IPAddr\n")));
}
AFDAddIPHostent(TEXT("ppp_peer"), pppAddr, NULL, 0);
}
// LinkUpIndication
//
// Function: Handles link up indication to IP. Called by
// IPCP when link can xfer data.
//
void
LinkUpIndication( PPP_CONTEXT *pppContext )
{
LLIPMTUChange mtuchange;
pppSession_t *s_p = (pppSession_t *)pppContext->Session;
PLCPContext lcp_p = (PLCPContext)s_p->lcpCntxt;
BOOL bAddWorked;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +LinkUpIndication( %s )\n"), pppContext->AdapterName ));
ASSERT( pppContext );
if (s_p->bIsServer)
pppContext->fOpen = TRUE;
// Unlock the session for calls into TCP/IP module
pppUnLock( s_p );
DEBUGCHK( s_p->SesCritSec.OwnerThread != (HANDLE)GetCurrentThreadId());
// Register the new interface with IP
bAddWorked = PPPAddInterface(pppContext);
if (bAddWorked)
{
// Notify upper layer of MTU change according to Mode
switch( s_p->Mode )
{
case PPPMODE_PPP:
SetPPPPeerIPAddress(pppContext);
// Use the negotiated peer MTU
mtuchange.lmc_mtu = lcp_p->peer.MRU;
break;
case PPPMODE_SLIP:
case PPPMODE_CSLIP:
mtuchange.lmc_mtu = SLIP_DEFAULT_MTU;
break;
default: ASSERT( 0 );
}
// Indicate MTU change to IP
if (pppContext->fOpen && pppContext->IPContext)
{
IPStatus( pppContext->IPContext,
LLIP_STATUS_MTU_CHANGE,
&mtuchange,
sizeof( LLIPMTUChange ),
NULL);
}
}
pppLock (s_p);
if (!bAddWorked)
{
// Unable to register with IP!!!
//
// IP may be unable to register the interface because the IP address
// is invalid or in use, or there was insufficient memory.
// If this happens, we need to terminate the PPP connection.
//
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR - Unable to register interface %s with IP\n"), pppContext->AdapterName));
// Request LCP terminate link
pppLcp_Close(lcp_p, NULL, NULL);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -LinkUpIndication( %s )\n"), pppContext->AdapterName ));
}
// LinkDownIndication
//
// Function: Handles link dn indication to IP. Called by
// IPCP and CCP when link can not xfer data,
// or by SLIP when the MAC layer is down.
//
void
LinkDownIndication( PPP_CONTEXT *pppContext, pppSession_t *s_p )
{
PPP_CONTEXT *pppContextYoungestActive;
DEBUGMSG( ZONE_PPP, (TEXT("LinkDownIndication( 0x%X, 0x%X )\r\n"), pppContext, s_p ));
// This function must be called with the session in use.
ASSERT( s_p->RefCnt > 0 );
// Can't hold session lock for call into IP
pppUnLock (s_p);
pppContext->fOpen = FALSE;
DEBUGCHK( s_p->SesCritSec.OwnerThread != (HANDLE)GetCurrentThreadId());
// Process according to Mode
switch( s_p->Mode )
{
case PPPMODE_PPP:
//
// Set the ppp_peer's IP address to be that of the youngest
// remaining active PPP session, or NULL if none.
//
EnterCriticalSection (&v_ListCS);
for (pppContextYoungestActive = pppContextList;
pppContextYoungestActive != NULL;
pppContextYoungestActive = pppContextYoungestActive->Next)
{
if (pppContextYoungestActive != pppContext
&& pppContextYoungestActive->fOpen)
{
break;
}
}
LeaveCriticalSection (&v_ListCS);
SetPPPPeerIPAddress(pppContextYoungestActive);
break;
case PPPMODE_SLIP:
case PPPMODE_CSLIP:
break;
default: ASSERT( 0 );
}
// Delete the IP interface
PPPDeleteInterface(s_p->context, s_p->context->Session);
pppLock (s_p);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -