⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_intf.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		//
		// 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 + -