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

📄 pppserver.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	PPPServerLineConfiguration_t *pLine;
	BOOL						  bInUse;

	// Determine if the address is in use by an existing PPP Server line

	bInUse = FALSE;

	for (pLine  = (PPPServerLineConfiguration_t *)(pConfig->LineList.Flink);
			pLine != (PPPServerLineConfiguration_t *)(&pConfig->LineList);
			pLine  = (PPPServerLineConfiguration_t *)pLine->listEntry.Flink)
	{
		if (ipAddr == pLine->IPAddrInfo[SERVER_INDEX].IPAddr 
		||  ipAddr == pLine->IPAddrInfo[CLIENT_INDEX].IPAddr)
		{
			// Address in use, try another.
			bInUse = TRUE;
			break;
		}
	}

	return bInUse;
}

BOOL
PPPServerIPAddrInUseOnNet(
	DWORD	dwIpAddr)
//
//	Determine whether the specified IP address is assigned to some
//  other adapter on our device, or some other device on the subnet.
//
//  dwIpAddr will be in format 0xDDCCBBAA where the ip address is A.B.C.D
//
{
	BOOL				bInUse = FALSE;
	DWORD				dwResult;
	BYTE				macAddr[6];
	DWORD				cbMacAddr;
	PMIB_IPADDRTABLE	pTable;
	PMIB_IPADDRROW		pRow;
	DWORD               i;

	//
	// Check to see if the address is in use on the local device.
	//
	dwResult = PPPServerGetIPAddrTable(&pTable, NULL);
	if (dwResult == NO_ERROR)
	{
		// Search the table for an interface with a matching IpAddr
		for (i = 0; i < pTable->dwNumEntries; i++)
		{
			pRow = &pTable->table[i];
			if (pRow->dwAddr == dwIpAddr)
			{
				bInUse = TRUE;
				break;
			}
		}
		LocalFree(pTable);
	}

	//
	// If not in use on local device, check to see if some external
	// device is using it.
	//
	if (!bInUse && g_pfnSendARP)
	{
		cbMacAddr = sizeof(macAddr);
		dwResult = g_pfnSendARP(dwIpAddr, 0, (PULONG)(&macAddr[0]), &cbMacAddr);

		if (dwResult == NO_ERROR && cbMacAddr > 0)
		{
			bInUse = TRUE;
		}
	}

	DEBUGMSG(ZONE_TRACE, (TEXT("PPP: ARP for %x, inUse=%d\n"), dwIpAddr, bInUse));

	return bInUse;
}

//**    PPPServerDhcpSetNTE
//
//      Routine to identify which NTE is currently being DHCP'ed. We take as input
//      an nte_context. If the context is less than the max NTE context, we look
//      for a matching NTE and if we find him we save a pointer. If we don't we
//      fail. If the context > max NTE context we're disabling DHCPing, and
//      we NULL out the save pointer.
//
//      Input:  Context         - NTE context value.
//                                (will be 0x1FFFF if clearing NTE)
//
//      Returns: TRUE if we succeed, FALSE if we don't.
//
uint
PPPServerDhcpSetNTECb(
				IN	uint		Context,
	OPTIONAL	OUT	PVOID		*ppNTE,
	OPTIONAL		char		*pAddr,
	OPTIONAL	OUT	DWORD		*cAddr)
{
	uint						  bSuccess = TRUE;
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PPPServerDhcpSetNTECb(%x)\n"), Context));

#if 0 // Don't currently support this feature
	if (g_pfnCESetDHCPNTEByName)
	{
		PWSTR					 wszDeviceName;

		if (Context == 0x1ffff)
		{
			// Clearing DHCP NTE
			bSuccess = g_pfnCESetDHCPNTEByName(NULL);
		}
		else
		{
			wszDeviceName = pConfig->wszDhcpInterface;
			if (wszDeviceName[0])
			{
				bSuccess = g_pfnCESetDHCPNTEByName(wszDeviceName);
			}
		}
	}
	DEBUGMSG(!bSuccess && ZONE_ERROR, (TEXT("PPP: WARNING: PPPServerDhcpSetNTECb(%x) failed\n"), Context));
#endif

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -PPPServerDhcpSetNTECb(%x) bSuccess=%d\n"), Context, bSuccess));

	return bSuccess;
}

//* PPPServerDhcpSetAddr - Set the IP address of an NTE.
//
//  Wrapper routine for IPpSetNTEAddr
//
//  Input:  Context - Context of NTE to alter.
//          Addr    - IP address to set.
//          Mask    - Subnet mask for Addr.
//
//  Returns: IP_SUCCESS if we changed the address
//
uint
PPPServerDhcpSetAddrCb(
	IN	ushort		Context,
	OUT	void		*NTEp,
	IN	IPAddr		Addr,
	IN	IPMask		Mask,
	IN	IPAddr		GWAddr)
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
    uint						  Result = IP_SUCCESS;
	PPPServerLineConfiguration_t *pLine;
	DWORD						  type;  // SERVER_INDEX or CLIENT_INDEX
	DWORD						  OldIPAddr, OldMask;
	BOOL                          bDhcpCompleted = TRUE;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PPPServerDhcpSetAddrCb(%x) Addr=%x Mask=%x GW=%x\n"), Context, Addr, Mask, GWAddr));

	//
	//	Find the IPAddrInfo for the Context
	//
	PPPServerFindIPInfoByIndex(Context, &pLine, &type);

	if (pLine == NULL)
	{
		DEBUGMSG(ZONE_WARN, (TEXT("PPP: WARNING: PPPServerDhcpSetAddrCb(%x) Addr=%x Mask=%x GW=%x  *NO LINE*\n"), Context, Addr, Mask, GWAddr));
		Result = IP_DEVICE_DOES_NOT_EXIST;
	}
	else
	{
		OldIPAddr = pLine->IPAddrInfo[type].IPAddr;
		OldMask = pLine->IPAddrInfo[type].IPMask;
		pLine->IPAddrInfo[type].IPAddr = ntohl(Addr);
		pLine->IPAddrInfo[type].IPMask = ntohl(Mask);
		pLine->IPAddrInfo[type].GWAddr = ntohl(GWAddr);

		if (Addr == 0)
		{
			if (pLine->IPAddrInfo[type].bDhcpCollision)
			{
				//
				// DHCP calls us immediately after we report a collision
				// to take away the address that we rejected. We don't want
				// to signal the lease process is done in that case.
				//
				pLine->IPAddrInfo[type].bDhcpCollision = FALSE;
				bDhcpCompleted = FALSE; // DHCP will try again to get a lease
			}
			else
			{
				//
				//	If we lost the lease unexpectedly then we want to shut the line down.
				//	If we gave up the lease (disabled the line ourselves by setting the
				//	global or local line enable flags off), then we don't need to do
				//  anything.
				//
				if (pConfig->bEnable)
				{
					DEBUGMSG(ZONE_WARN, (L"PPPSERVER: WARNING - DHCP Lease Failure, shutting down line\n"));
					PPPServerLineDisable(pLine);
				}
			}

			// Stop using the address, the lease is not available

			if (OldIPAddr)
			{
				// Tell IP to stop handling proxy ARP requests for the address.

				ArpProxyManagerIssueRequest(OldIPAddr, FALSE);
			}
		}
		else
		{
			// Lease obtained

			if (PPPServerIPAddrInUseOnNet(Addr))
			{
				DEBUGMSG(ZONE_WARN, (TEXT("PPP: WARNING: DHCP assigned Addr=%x is already IN USE by another device\n"), Addr));
				Result = IP_DUPLICATE_ADDRESS;
				bDhcpCompleted = FALSE; // DHCP will try again to get a lease
				pLine->IPAddrInfo[type].bDhcpCollision = TRUE;
				pLine->IPAddrInfo[type].dwDhcpCollisionCount++;
			}
			else
			{
				// Configure IP to handle ARP requests for the address
				Result = ArpProxyManagerIssueRequest(ntohl(Addr), TRUE);
			}
		}

		//
		// We are done unless the address was a duplicate in which case
		// the attempt to get a lease continues.
		//
		if (bDhcpCompleted)
		{
			DEBUGMSG(ZONE_PPP, (L"PPP: SIGNALLING DHCP LEASE REQUEST COMPLETED Result=%d.\n", Result));

			SetEvent(pLine->IPAddrInfo[type].hEvent);
		}
	}

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -PPPServerDhcpSetAddrCb(%x) Result=%d\n"), Context, Result));

    return Result;
}

void
PPPServerRegisterWithDhcp()
//
//	Obtain and register hooks into the dhcp library
//
{
	PFNDhcpRegister		pfnDhcpRegister;

	//
	//	If the DHCP dll is not currently loaded, try to load it
	//
	if (g_hDhcpMod == NULL)
	{
		g_hDhcpMod = LoadLibrary(TEXT("dhcp.dll"));
	}

	if (g_hDhcpMod && !g_pDhcpProtocolContext)
	{
		// Get handle to DhcpRegister
		pfnDhcpRegister = (PFNDhcpRegister)GetProcAddress(g_hDhcpMod, TEXT("DhcpRegister"));
		if (pfnDhcpRegister)
		{
			g_pDhcpProtocolContext = pfnDhcpRegister(L"PPP", PPPServerDhcpSetNTECb, PPPServerDhcpSetAddrCb, &g_pfnDhcpNotify);
			if (g_pDhcpProtocolContext)
			{
				DEBUGMSG (ZONE_INIT, (TEXT("PPP: registered w/ DHCP\n")));
			}
			else
			{
				DEBUGMSG (ZONE_ERROR, (TEXT("PPP: DhcpRegister failed\n")));
			}
		}
	}
}

////////////////////////////////////
//	Auto IP address allocation support
////////////////////////////////////

DWORD
PPPServerLineGenerateAutoIpAddrs(
	PPPServerLineConfiguration_t *pLine)
//
//	Generate random IP addresses on the AutoIP subnet that are not in use.
//
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	DWORD	dwResult = NO_ERROR;
	DWORD	type;
	DWORD	randomIpAddr;
	DWORD   dwTriesRemaining;

	for (type = SERVER_INDEX; type <= CLIENT_INDEX; type++)
	{
		for (dwTriesRemaining = 10; dwTriesRemaining; dwTriesRemaining--)
		{
			// A host id of all 0's or all 1's is not allowed
			do
			    CeGenRandom(sizeof(randomIpAddr), (PBYTE)&randomIpAddr);
			while (((randomIpAddr & ~pConfig->dwAutoIpSubnetMask) == 0)
			||     ((randomIpAddr & ~pConfig->dwAutoIpSubnetMask) == ~pConfig->dwAutoIpSubnetMask));
			
			randomIpAddr &= ~pConfig->dwAutoIpSubnetMask;
			randomIpAddr |=  pConfig->dwAutoIpSubnet;
			if (!PPPServerUsingIpAddr(randomIpAddr)
			&&  !PPPServerIPAddrInUseOnNet(htonl(randomIpAddr)))
				// random address is available, we'll use it
				break;
		}

		if (dwTriesRemaining == 0)
		{
			dwResult = ERROR_NO_IP_ADDRESSES;
			break;
		}

		pLine->IPAddrInfo[type].IPAddr = randomIpAddr;
		pLine->IPAddrInfo[type].IPMask = pConfig->dwAutoIpSubnetMask;

		// Configure IP to handle ARP requests for the address
		dwResult = ArpProxyManagerIssueRequest(randomIpAddr, TRUE);
	}

	return dwResult;
}

////////////////////////////////////
//	Static IP address allocation support
////////////////////////////////////

DWORD
PPPServerGetFreeStaticIpAddress()
//
//	Find an unused address in the static IP pool and return it.
//	Return 0 if no free address is found.
//
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	DWORD						  ipAddr;
	DWORD						  i;

	for (i = 0; TRUE; i++)
	{
		if (i == pConfig->dwStaticIpAddrCount)
		{
			// All addresses in static pool are in use
			ipAddr = 0;
			break;
		}

		ipAddr = pConfig->dwStaticIpAddrStart + i;

		//
		// If the address is not in use, we are done.
		//
		if (!PPPServerUsingIpAddr(ipAddr))
		{
			break;
		}

		// Otherwise, keep looking for a free one
	}

	return ipAddr;
}

VOID
PPPServerLineReleaseIPAddresses(
	PPPServerLineConfiguration_t *pLine)
{

	DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PPPServerLineReleaseIPAddresses\n")));

	//
	// Static addresses are implicitly released when the line
	// is disabled.
	//
	// DHCP addresses need to be explicitly released.
	//
	if (pLine->bUsingDhcpAddress)
	{
		PPPServerLineReleaseDHCPAddrs(pLine);
		pLine->bUsingDhcpAddress = FALSE;
	}

	// Make sure any ARP proxying is terminated
	ArpProxyManagerIssueRequest(pLine->IPAddrInfo[SERVER_INDEX].IPAddr, FALSE);
	ArpProxyManagerIssueRequest(pLine->IPAddrInfo[CLIENT_INDEX].IPAddr, FALSE);

	pLine->IPAddrInfo[SERVER_INDEX].IPAddr = 0;
	pLine->IPAddrInfo[SERVER_INDEX].Index = 0;
	pLine->IPAddrInfo[CLIENT_INDEX].IPAddr = 0;
	pLine->IPAddrInfo[CLIENT_INDEX].Index = 0;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -PPPServerLineReleaseIPAddresses\n")));
}

DWORD
PPPServerLineGetIPAddresses(
	PPPServerLineConfiguration_t *pLine)
//
//	Obtain IP addresses for the server and client sides
//	of a PPP connection.
//
//	Return:
//		SUCCESS if it works,
//		ERROR_NO_IP_ADDRESS if no addresses were assigned
//
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	DWORD						  dwResult = ERROR_NO_IP_ADDRESSES;
	BYTE						  MacAddress[6];
	BOOL						  bSuccess;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PPPServerLineGetIPAddresses\n")));

	ASSERT(pLine->IPAddrInfo[SERVER_INDEX].IPAddr == 0);
	ASSERT(pLine->IPAddrInfo[CLIENT_INDEX].IPAddr == 0);

	if (pConfig->bUseDhcpAddresses)
	{
		if (g_pDhcpProtocolContext == NULL)
		{
			// The DHCP service is not available
		}
		else
		{
			//
			//	Get the MAC address of a DHCP enabled LAN
			//	adapter in the system.  Also find out the interface index for 
			//
			bSuccess = PPPServerGetUniqueMacAddress(MacAddress, sizeof(MacAddress), &pLine->dwDhcpIfIndex);

			if (bSuccess)
			{
				//
				//	Build the client HW address to use with DHCP
				//
				PPPServerLineBuildClientHWAddrs(pLine, MacAddress, sizeof(MacAddress));

				//
				//	Issue the request to DHCP to assign the client
				//	and server IP addresses
				//
				dwResult = PPPServerLineRequestDHCPAddrs(pLine);

				if (dwResult == SUCCESS)
				{
					pLine->bUsingDhcpAddress = TRUE;
				}
			}
		}
	}
	else if (pConfig->bUseAutoIpAddresses)
	{
		// Auto IP address assignment

		pLine->bUsingDhcpAddress = FALSE;
		dwResult = PPPServerLineGenerateAutoIpAddrs(pLine);
	}
	else
	{
		// Static IP address assignment

		pLine->bUsingDhcpAddress = FALSE;
		pLine->IPAddrInfo[SERVER_INDEX].IPAddr = PPPServerGetFreeStaticIpAddress();
		pLine->IPAddrInfo[SERVER_INDEX].IPMask = IPGetNetMask(pLine->IPAddrInfo[SERVER_INDEX].IPAddr);
		pLine->IPAddrInfo[CLIENT_INDEX].IPAddr = PPPServerGetFreeStaticIpAddress();
		pLine->IPAddrInfo[CLIENT_INDEX].IPMask = IPGetNetMask(pLine->IPAddrInfo[CLIENT_INDEX].IPAddr);

		if (pLine->IPAddrInfo[SERVER_INDEX].IPAddr 
		&&  pLine->IPAddrInfo[CLIENT_INDEX].IPAddr)
		{
			dwResult = SUCCESS;
		}
		else
		{
			// No static IP addresses available
		}
	}
#ifdef DEBUG
	if (dwResult == SUCCESS)
	{
		DEBU

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -