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

📄 pppserver.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}

DWORD
PPPServerLineAdd(
	IN	PRASCNTL_SERVERLINE	pBufIn,
	IN	DWORD				dwLenIn)
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	PPPServerLineConfiguration_t *pLine;
	DWORD						 dwRetVal = SUCCESS;

	if ((pBufIn == NULL)
	||  (dwLenIn < sizeof(RASCNTL_SERVERLINE)))
	{
		dwRetVal = ERROR_INVALID_PARAMETER;
	}
	else
	{
		EnterCriticalSection( &PPPServerCritSec );

		pLine = PPPServerFindOrCreateLineConfig(&pConfig->LineList, &pBufIn->rasDevInfo);
		if (pLine)
		{
			PPPServerWriteLineConfigurationRegistrySettings(pLine);
		}

		LeaveCriticalSection( &PPPServerCritSec );
	}

	return dwRetVal;
}

DWORD
PPPServerLineRemove(
	IN	PPPServerLineConfiguration_t *pLine)
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	DWORD						  dwRetVal;

	dwRetVal = PPPServerLineDisable(pLine);

	PPPServerRemoveLineConfigurationRegistrySettings(pLine);

	PPPServerDestroyLineConfig(&pConfig->LineList, pLine);

	return dwRetVal;
}

#ifdef DEBUG

#define ENUM_TO_SZ_CASE(name) case(name): return #name

char *
GetRASConnectionStateName(
	RASCONNSTATE state)
{
	switch (state)
	{
	ENUM_TO_SZ_CASE(RASCS_OpenPort);
	ENUM_TO_SZ_CASE(RASCS_PortOpened);
	ENUM_TO_SZ_CASE(RASCS_ConnectDevice);
	ENUM_TO_SZ_CASE(RASCS_DeviceConnected);
	ENUM_TO_SZ_CASE(RASCS_AllDevicesConnected);
	ENUM_TO_SZ_CASE(RASCS_Authenticate);
	ENUM_TO_SZ_CASE(RASCS_AuthNotify);
	ENUM_TO_SZ_CASE(RASCS_AuthRetry);
	ENUM_TO_SZ_CASE(RASCS_AuthCallback);
	ENUM_TO_SZ_CASE(RASCS_AuthChangePassword);
	ENUM_TO_SZ_CASE(RASCS_AuthProject);
	ENUM_TO_SZ_CASE(RASCS_AuthLinkSpeed);
	ENUM_TO_SZ_CASE(RASCS_AuthAck);
	ENUM_TO_SZ_CASE(RASCS_ReAuthenticate);
	ENUM_TO_SZ_CASE(RASCS_Authenticated);
	ENUM_TO_SZ_CASE(RASCS_PrepareForCallback);
	ENUM_TO_SZ_CASE(RASCS_WaitForModemReset);
	ENUM_TO_SZ_CASE(RASCS_WaitForCallback);
	ENUM_TO_SZ_CASE(RASCS_Projected);
	ENUM_TO_SZ_CASE(RASCS_Interactive);
	ENUM_TO_SZ_CASE(RASCS_RetryAuthentication);
	ENUM_TO_SZ_CASE(RASCS_CallbackSetByCaller);
	ENUM_TO_SZ_CASE(RASCS_PasswordExpired);
	ENUM_TO_SZ_CASE(RASCS_Connected);
	ENUM_TO_SZ_CASE(RASCS_Disconnected);
	default: return "???";
	}
}
#endif

////////////////////////////////////
//	DHCP address allocation support
////////////////////////////////////

HINSTANCE				g_hDhcpMod = NULL;
PDHCP_PROTOCOL_CONTEXT	g_pDhcpProtocolContext = NULL;
PFN_DHCP_NOTIFY			g_pfnDhcpNotify;

DWORD
PPPServerGetAdapterIndex(
	LPWSTR	AdapterName,
	PULONG	IfIndex)
{
	DWORD	dwResult = ERROR_NOT_SUPPORTED;

	if (g_pfnGetAdapterIndex)
	{
		dwResult = g_pfnGetAdapterIndex(AdapterName, IfIndex);
	}

	return dwResult;
}

DWORD
PPPServerCreateIpForwardEntry(
	PMIB_IPFORWARDROW	pRoute)
{
	DWORD	dwResult = ERROR_NOT_SUPPORTED;

	if (g_pfnCreateIpForwardEntry)
	{
		dwResult = g_pfnCreateIpForwardEntry(pRoute);
	}

	return dwResult;
}

DWORD
PPPServerDeleteIpForwardEntry(
	PMIB_IPFORWARDROW	pRoute)
{
	DWORD	dwResult = ERROR_NOT_SUPPORTED;

	if (g_pfnDeleteIpForwardEntry)
	{
		dwResult = g_pfnDeleteIpForwardEntry(pRoute);
	}

	return dwResult;
}

DWORD
PPPServerBuildRoute(
	IN  PPPServerLineConfiguration_t *pLine,
	OUT	PMIB_IPFORWARDROW			 pRoute)
{
	DWORD ClientIPAddr;

	ClientIPAddr = pLine->IPAddrInfo[CLIENT_INDEX].IPAddr;
	ClientIPAddr = htonl(ClientIPAddr);

	pRoute->dwForwardDest		= ClientIPAddr;
	pRoute->dwForwardMask		= 0xFFFFFFFF;		// Only forward exact matches of the client IP address
	pRoute->dwForwardNextHop	= ClientIPAddr;
	pRoute->dwForwardPolicy		= 0;
	pRoute->dwForwardIfIndex	= pLine->dwIfIndex;
	pRoute->dwForwardType		= 3;				// The next hop is the final destination (local route)
	pRoute->dwForwardProto		= PROTO_IP_NETMGMT;	// Routes added by "route add" or through SNMP
	pRoute->dwForwardAge		= 0;
	pRoute->dwForwardNextHopAS	= 0;
	pRoute->dwForwardMetric1  = 1;
	pRoute->dwForwardMetric2  = -1;
	pRoute->dwForwardMetric3  = -1;
	pRoute->dwForwardMetric4  = -1;
	pRoute->dwForwardMetric5  = -1;

	return NO_ERROR;
}


void
PPPServerAddRouteToClient(
	pppSession_t *pSession)
//
//	Add a route that will cause received packets with an IP
//	address equal to that of the client to be sent through
//	the PPP server interface.
//
{
	DWORD						  dwResult = ERROR_DEVICENAME_NOT_FOUND;
	MIB_IPFORWARDROW			  route;
	PPPServerLineConfiguration_t *pLine;

	pLine = PPPServerFindLineWithSession(pSession);
	if (pLine)
	{
		dwResult = PPPServerGetAdapterIndex(pSession->context->AdapterName, &pLine->dwIfIndex);
		if (dwResult == NO_ERROR)
		{
			dwResult = PPPServerBuildRoute(pLine, &route);
			if (dwResult == NO_ERROR)
			{
				dwResult = PPPServerCreateIpForwardEntry(&route);
			}
		}
	}
}

void
PPPServerDeleteRouteToClient(
	pppSession_t        *pSession)
//
//	Delete a route to a client previously created by PPPServerAddRouteToClient.
//
{
	DWORD						  dwResult = ERROR_DEVICENAME_NOT_FOUND;
	MIB_IPFORWARDROW			  route;
	PPPServerLineConfiguration_t *pLine;

	pLine = PPPServerFindLineWithSession(pSession);
	if (pLine)
	{
		dwResult = PPPServerBuildRoute(pLine, &route);
		if (dwResult == NO_ERROR)
		{
			dwResult = PPPServerDeleteIpForwardEntry(&route);
		}
	}
}


BOOL
PPPServerGetUniqueMacAddress(
	OUT	BYTE	*pMacAddress,
	IN	UINT	cbMacAddress,
	OUT	PDWORD	pdwIfIndex)
//
//	Find the MAC address of a LAN adapter installed in the server
//	to use to generate unique client hardware IDs for getting DHCP
//	leases for PPP connections.
//
//	Return the MAC address and the interface index for its adapter.
//
{
	BOOL				bSuccess = FALSE;

	memset(pMacAddress, 0, cbMacAddress);

	bSuccess = utilFindEUI(0, TRUE, pMacAddress, (1<<cbMacAddress), &cbMacAddress, pdwIfIndex);

	return bSuccess;
}

VOID
PPPServerFindIPInfoByIndex(
	DWORD						   Index,
	PPPServerLineConfiguration_t **ppLine,
	PDWORD						   pInfoType)
//
//	Find the line with IP Info having the specified Index
//	Return NULL if no match found.
//
{
	PPPServerConfiguration_t	 *pConfig = &PPPServerConfig;
	PPPServerLineConfiguration_t *pLine;
	DWORD						  type;

	*ppLine = NULL;

	for (pLine  = (PPPServerLineConfiguration_t *)(pConfig->LineList.Flink);
		 pLine != (PPPServerLineConfiguration_t *)(&pConfig->LineList);
		 pLine  = (PPPServerLineConfiguration_t *)pLine->listEntry.Flink)
	{
		for (type = SERVER_INDEX; type <= CLIENT_INDEX; type++)
		{
			if (Index == pLine->IPAddrInfo[type].Index)
			{
				*ppLine = pLine;
				*pInfoType = type;
				break;
			}
		}

		if (*ppLine)
			break;
	}
}

VOID
PPPServerLineAssignUnusedIndices(
	PPPServerLineConfiguration_t *pLine)
//
//	Assign lowest available unused index values for the server and client IP info structures
//	These indexes become the last 4 bytes of the unique client hw address identifiers that
//	are used to reserve DHCP addresses.
//
{
	DWORD						  index;
	PPPServerLineConfiguration_t *pLineUsingIndex;
	DWORD						  type, typeUsingIndex;

	//
	//	We should have freed and zeroed any prior in use indices
	//
	ASSERT(pLine->IPAddrInfo[SERVER_INDEX].Index == 0);
	ASSERT(pLine->IPAddrInfo[CLIENT_INDEX].Index == 0);

	index = 0x8001;
	type = SERVER_INDEX;

	while (type <= CLIENT_INDEX)
	{
		PPPServerFindIPInfoByIndex(index, &pLineUsingIndex, &typeUsingIndex);
		if (pLineUsingIndex == NULL)
		{
			// index is not in use, assign it
			pLine->IPAddrInfo[type].Index = index;
			type++;
		}

		index++;

		// There should not be too many of these in use in practice
		ASSERT(index <= 0xFFFF);
	}
}

#define RAS_PREPEND_SIZE	strlen(RAS_PREPEND)

VOID
PPPServerLineBuildClientHWAddrs(
	PPPServerLineConfiguration_t *pLine,
	BYTE						 *pMacAddr,
	DWORD						  cbMacAddr)
//
//	Build the client hardware addresses to be used to acquire DHCP leases.
//
//	The address takes the form:
//
//		4 Bytes:	"RAS "
//		8 Bytes:	<MacAddress> (0 padded on the front)
//		4 Bytes:	<Index>
//
{
	DWORD	type, index;
	BYTE	*pHWAddr;

	PPPServerLineAssignUnusedIndices(pLine);

	if (cbMacAddr > 8)
		cbMacAddr = 8;

	for (type = SERVER_INDEX; type <= CLIENT_INDEX; type++)
	{
		//
		//	"RAS " part
		//
		pHWAddr = &pLine->IPAddrInfo[type].DhcpClientHWAddress[0];
		memcpy(pHWAddr, RAS_PREPEND, RAS_PREPEND_SIZE);
		pHWAddr += RAS_PREPEND_SIZE;

		//
		//	<MacAddress> part
		//
		memset(pHWAddr, 0, 8);
		memcpy(pHWAddr + (8 - cbMacAddr), pMacAddr, cbMacAddr);
		pHWAddr += 8;

		//
		//	<Index> part
		//
		index = pLine->IPAddrInfo[type].Index;
		index = htonl(index);
		memcpy(pHWAddr, (BYTE *)&index, sizeof(index));
	}
}

TCHAR cLineTypeSuffix[2] = 
{
	TEXT('s'),	// SERVER_INDEX
	TEXT('c')	// CLIENT_INDEX
};

DWORD
PPPServerLineRequestDHCPAddrs(
	PPPServerLineConfiguration_t *pLine)
//
//	Issue requests to DHCP to assign IP addresses for the line
//
{
	PPPServerConfiguration_t *pConfig = &PPPServerConfig;
	TCHAR	tszAdapterName[RAS_MaxDeviceName+1+1];
	DWORD	dwResult;
	DWORD	type;
	DWORD   dwCollisionCount;
	DWORD   dhcpTimeouts;

	for (type = SERVER_INDEX; type <= CLIENT_INDEX; type++)
	{
		// tszAdapterName has to be unique for the Dhcp lease, 
		//   e.g. "VPN1s" for serverside, "VPN1c" for clientside
		_stprintf(tszAdapterName, TEXT("%s%c"), pLine->rasDevInfo.szDeviceName, cLineTypeSuffix[type]);

		DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: DHCP_REQUEST_ADDRESS for %s\n"), tszAdapterName));

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

		dwResult = g_pfnDhcpNotify(
					DHCP_REQUEST_ADDRESS, 
					g_pDhcpProtocolContext, 
					tszAdapterName,
					pLine, // Nte
					pLine->IPAddrInfo[type].Index,
					pLine->IPAddrInfo[type].DhcpClientHWAddress,
					sizeof(pLine->IPAddrInfo[type].DhcpClientHWAddress));

		if (dwResult != DHCP_SUCCESS)
		{
			DEBUGMSG(ZONE_ERROR, (TEXT("PPP: DHCP_REQUEST_ADDRESS failed, error=%x\n"), dwResult));
			break;
		}
		else
		{
			// Wait for DHCP to get the lease

			for (dhcpTimeouts = 0; dhcpTimeouts <= pConfig->DhcpMaxTimeouts;  dhcpTimeouts++)
			{
				dwCollisionCount = pLine->IPAddrInfo[type].dwDhcpCollisionCount;

				LeaveCriticalSection( &PPPServerCritSec );

				DEBUGMSG(ZONE_PPP, (L"PPPSERVER: Wait for DHCP lease...\n"));
				dwResult = WaitForSingleObject(pLine->IPAddrInfo[type].hEvent, pConfig->DhcpTimeoutMs);
				DEBUGMSG(ZONE_PPP, (L"PPPSERVER: Lease request completed, result=%d.\n", dwResult));

				EnterCriticalSection( &PPPServerCritSec );

				// If didn't time out or had no activity, we are done
				if (dwResult != WAIT_TIMEOUT
				||  dwCollisionCount == pLine->IPAddrInfo[type].dwDhcpCollisionCount)
				{
					break;
				}
			}

			if (dwResult == WAIT_TIMEOUT)
			{
				// No response from DHCP to our request with 30 seconds
				DEBUGMSG(ZONE_ERROR, (L"PPPSERVER: ERROR - DHCP Lease request timeout\n"));
				dwResult = ERROR_NO_IP_ADDRESSES;
				break;
			}

			if (pLine->IPAddrInfo[type].IPAddr == 0)
			{
				// DHCP failed to obtain a lease.
				dwResult = ERROR_NO_IP_ADDRESSES; 
				DEBUGMSG(ZONE_ERROR, (L"PPPSERVER: ERROR - DHCP Lease request failure\n"));
				break;
			}

			dwResult = NO_ERROR;
		}

		DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: DHCP_REQUEST_ADDRESS for %s RESULT=%d\n"), tszAdapterName, dwResult));
	}

	DEBUGMSG(ZONE_ERROR && dwResult, (TEXT("PPP: PPPServerLineRequestDHCPAddrs FAILED result=%d\n"), dwResult));

	return dwResult;
}

DWORD
PPPServerLineReleaseDHCPAddrs(
	PPPServerLineConfiguration_t *pLine)
//
//	Issue requests to DHCP to release IP addresses for the line
//
{
	TCHAR	tszAdapterName[RAS_MaxDeviceName+1+1];
	DWORD	dwResult;
	DWORD	type;

	for (type = SERVER_INDEX; type <= CLIENT_INDEX; type++)
	{
		_stprintf(tszAdapterName, TEXT("%s%c"), pLine->rasDevInfo.szDeviceName, cLineTypeSuffix[type]);

		DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: DHCP_REQUEST_RELEASE for %s\n"), tszAdapterName));

		dwResult = g_pfnDhcpNotify(
					DHCP_REQUEST_RELEASE, 
					g_pDhcpProtocolContext, 
					tszAdapterName,
					NULL, // Nte
					0,
					NULL,
					0);
	}

	return dwResult;
}

BOOL
PPPServerUsingIpAddr(
	 DWORD ipAddr)
//
//  ipAddr should be in the format 0xAABBCCDD
//
{

⌨️ 快捷键说明

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