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

📄 pppserver.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
		ArpIfListEntryDelete(pEntry, (PIfListEntry)pEntry->IfList.Flink);
	}
}

PMIB_IPADDRROW
IpAddrTableFindRowByIndex(
    IN       PMIB_IPADDRTABLE	pTable,
	IN       DWORD              dwIfIndex)
{
	PMIB_IPADDRROW pRow = NULL;
	DWORD          i;

	for (i = 0; i < pTable->dwNumEntries; i++)
	{
		if (pTable->table[i].dwIndex == dwIfIndex)
		{
			pRow = &pTable->table[i];
			break;
		}
	}

	return pRow;
}

PIfListEntry
IfEntryFindByIndex(
   IN PLIST_ENTRY pIfList,
   IN DWORD       dwIfIndex)
{
	PIfListEntry        pIfEntry  = NULL;

	ListValidate(pIfList);
	for (pIfEntry = (PIfListEntry)(pIfList->Flink);
		 TRUE;
		 pIfEntry  = (PIfListEntry)pIfEntry->link.Flink)
	{
		if (pIfEntry == (PIfListEntry)pIfList)
		{
			// no match found
			pIfEntry = NULL;
			break;
		}

		if (pIfEntry->dwIfIndex == dwIfIndex)
			break;
	}

	return pIfEntry;
}

BOOL
ShouldBeProxied(
	IN	DWORD               dwIpAddress,
	IN  PMIB_IPADDRROW		pRow)
//
//  Return TRUE if the specified IP Address should be proxied on
//  the specified interface.
//
{
	BOOL  bShouldBeProxied = FALSE;
	DWORD dwIfNetMask,
		  dwIfNetAddr;

	// Only do ARP proxying on LANs
	if (IFTypeIsLAN(pRow->dwIndex))
	{
		dwIfNetMask = ntohl(pRow->dwMask);
		dwIfNetAddr = ntohl(pRow->dwAddr);

		if (dwIfNetAddr == 0 || dwIfNetAddr == 0xFFFFFFFF || dwIfNetMask == 0)
		{
			// Invalid address or mask, do not proxy on it
		}
		else if ((dwIpAddress & dwIfNetMask) == (dwIfNetAddr & dwIfNetMask))
		{
			// If the the address is on the interfaces subnet,
			// then we should proxy it
			bShouldBeProxied = TRUE;
		}

		DEBUGMSG(ZONE_PPP, (TEXT("PPPSERVER: ShouldBeProxied %x on IF IP=%x MASK=%x = %d\n"), dwIpAddress, dwIfNetAddr, dwIfNetMask, bShouldBeProxied));
	}

	return bShouldBeProxied;
}

void
ArpProxyListEntryUpdateProxies(
	IN  OUT  PArpProxyListEntry pEntry,
    IN       PMIB_IPADDRTABLE	pTable)
//
//	For each interface that this entry should be proxied on and is not currently, proxy it.
//  For each interface that this entry is proxied on but should not, unproxy it.
//
{
	PIfListEntry        pIfEntry,
		                pIfEntryNext;
	PMIB_IPADDRROW		pRow;
	DWORD               i;

	ListValidate(&pEntry->IfList);

	//  For each interface that this entry is proxied on but should not, unproxy it.

	for (pIfEntry = (PIfListEntry)(pEntry->IfList.Flink);
		 pIfEntry != (PIfListEntry)&pEntry->IfList;
		 pIfEntry = pIfEntryNext)
	{
		pIfEntryNext = (PIfListEntry)pIfEntry->link.Flink;

		pRow = IpAddrTableFindRowByIndex(pTable, pIfEntry->dwIfIndex);
		if (pRow == NULL
		||  !ShouldBeProxied(pEntry->dwIpAddress, pRow))
		{
			//
			// Interface we were proxying on no longer exists, or
			// Interface address/type has changed, don't want to proxy any more
			//
			ArpIfListEntryDelete(pEntry, pIfEntry);
		}
	}

	// For each interface, proxy this entry if it is not currently proxied but should be.

	for (i = 0; i < pTable->dwNumEntries; i++)
	{
		pRow = &pTable->table[i];

		if (ShouldBeProxied(pEntry->dwIpAddress, pRow))
		{
			pIfEntry = IfEntryFindByIndex(&pEntry->IfList, pRow->dwIndex);
			if (pIfEntry == NULL)
			{
				// Not currently proxied, Create a new IfEntry and add it to the list
				pIfEntry = ArpIfListEntryNew(pEntry, pRow->dwIndex);
			}
			else
			{
				// An interface could get deleted and re-added quickly, before we run.
				// However, it should get a new interface id in that case. So we shouldn't
				// have to worry about it
			}
		}
	}
}

PArpProxyListEntry
ArpProxyAddressFind(
	DWORD   dwIpAddressToProxy)
{
	PArpProxyListEntry pEntry = NULL;

	ListValidate(&g_ArpProxyList);

	for (pEntry = (PArpProxyListEntry)(g_ArpProxyList.Flink);
		 TRUE;
		 pEntry = (PArpProxyListEntry)pEntry->link.Flink)
	{
		if (pEntry == (PArpProxyListEntry)(&g_ArpProxyList))
		{
			// end of list, match not found
			pEntry = NULL;
			break;
		}

		if (pEntry->dwIpAddress == dwIpAddressToProxy)
		{
			// found match
			break;
		}
	}
	return pEntry;
}

DWORD
ArpProxyAddressAdd(
	DWORD   dwIpAddressToProxy)
//
//	Begin managing this proxy arp address.
//
{
	DWORD   dwResult = NO_ERROR;
	PArpProxyListEntry pEntry;
	PMIB_IPADDRTABLE	pTable;

	pEntry = ArpProxyAddressFind(dwIpAddressToProxy);
	if (pEntry == NULL)
		pEntry = ArpProxyListEntryNew(dwIpAddressToProxy);

	if (pEntry)
	{
		// Proxy the address on interfaces as appropriate

		dwResult = PPPServerGetIPAddrTable(&pTable, NULL);

		if (pTable)
		{
			ArpProxyListEntryUpdateProxies(pEntry, pTable);

			LocalFree(pTable);
		}
	}
	else
	{
		dwResult = ERROR_OUTOFMEMORY;
	}

	return dwResult;

}

DWORD
ArpProxyAddressDelete(
	DWORD   dwIpAddressBeingProxied)
//
//	Stop managing this proxy arp address.
//
{
	DWORD   dwResult = NO_ERROR;
	PArpProxyListEntry pEntry;

	pEntry = ArpProxyAddressFind(dwIpAddressBeingProxied);
	if (pEntry)
	{
		// Unproxy the address from any interfaces
		ArpProxyListEntryUnproxyAll(pEntry);

		ArpProxyListEntryDelete(pEntry);
	}

	return dwResult;
}

//
//	Format of the request messages sent to the ARP Proxy Manager thread.
//
typedef struct
{
	LIST_ENTRY	link;
	BOOL        bAddProxy;
	DWORD       dwIpAddress;
} ArpProxyManagerRequest, *PArpProxyManagerRequest;

LIST_ENTRY       g_ArpProxyManagerRequestList;
CRITICAL_SECTION g_CSArpProxyManagerRequestList;
HANDLE           g_hEventManagerRequestList;
HANDLE           g_hEventAddrChange;
HANDLE			 g_hAddrChangeThread;
HANDLE			 g_hProxyManagerThread;

DWORD
ArpProxyAddrChangeNotifierThread(
	PVOID unused)
{
	DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: Start AddrChangeNotifier\n")));

	if (g_pfnNotifyAddrChange)
	{
		while (g_pfnNotifyAddrChange(NULL, NULL) == NO_ERROR)
		{
			SetEvent(g_hEventAddrChange);
		}
	}

	DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: Exit AddrChangeNotifier\n")));

	return NO_ERROR;
}

DWORD
ArpProxyManagerThread(
    PVOID unused)
{
	DWORD dwResult;
	PArpProxyManagerRequest pRequest;
	PArpProxyListEntry      pEntry,
		                    pEntryNext;
	PMIB_IPADDRTABLE	    pTable;
	HANDLE					hEventArray[2];

	DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: Start ARP Proxy Manager\n")));

	hEventArray[0] = g_hEventManagerRequestList;
	hEventArray[1] = g_hEventAddrChange;

	while (TRUE)
	{
		DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: ArpProxyManagerThread Wait\n")));

		APValidateAllLists();
		dwResult = WaitForMultipleObjects(2, &hEventArray[0], FALSE, INFINITE);
		APValidateAllLists();

		DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: ArpProxyManagerThread Wait Result = %x\n"), dwResult));

		if (dwResult == WAIT_OBJECT_0)
		{
			// g_hEventManagerRequestList signalled

			// Process all requests in the request list
			while (TRUE)
			{
				EnterCriticalSection(&g_CSArpProxyManagerRequestList);

				pRequest = NULL;
				if (!IsListEmpty(&g_ArpProxyManagerRequestList))
					pRequest = (PArpProxyManagerRequest)RemoveHeadList(&g_ArpProxyManagerRequestList);

				LeaveCriticalSection(&g_CSArpProxyManagerRequestList);

				DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: ArpProxyManagerThread pRequest = %x\n"), pRequest));

				if (pRequest == NULL)
					break;

				if (pRequest->bAddProxy)
					ArpProxyAddressAdd(pRequest->dwIpAddress);
				else
					ArpProxyAddressDelete(pRequest->dwIpAddress);

				LocalFree(pRequest);
			}
		}
		else if (dwResult == WAIT_OBJECT_0 + 1)
		{
			DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: ArpProxyManagerThread AddrChanged\n")));

			// g_hEventAddrChange signalled
			// Process any interface changes
			dwResult = PPPServerGetIPAddrTable(&pTable, NULL);

			if (pTable)
			{
				for (pEntry  = (PArpProxyListEntry)(g_ArpProxyList.Flink);
					 pEntry != (PArpProxyListEntry)(&g_ArpProxyList);
					 pEntry  =  pEntryNext)
				{
					pEntryNext = (PArpProxyListEntry)pEntry->link.Flink;
					ArpProxyListEntryUpdateProxies(pEntry, pTable);
				}
				LocalFree(pTable);
			}
		}
		else
		{
			// Error in WaitForMultiple
			DEBUGMSG(ZONE_ERROR, (TEXT("PPPSERVER: ArpProxyManagerThread error in WaitForMultiple %d\n"), GetLastError()));
			break;
		}
	}

	CloseHandle(g_hProxyManagerThread);
	g_hProxyManagerThread = NULL;

	DEBUGMSG(ZONE_TRACE, (TEXT("PPPSERVER: Exit ARP Proxy Manager\n")));

	return NO_ERROR;
}

DWORD
ArpProxyManagerIssueRequest(
	DWORD dwIpAddress,
	BOOL  bAddProxy)
//
//  Issue a request to the Arp Proxy manager to add or
//  remove an address form the proxy list.
//
{
	PArpProxyManagerRequest pRequest;
	DWORD                   dwResult = NO_ERROR;

	DEBUGMSG(ZONE_TRACE, (TEXT("PPP: Request %hs proxy for %u.%u.%u.%u\n"),
		bAddProxy ? "Add" : "Delete",
		(dwIpAddress >> 24) & 0xFF, 
		(dwIpAddress >> 16) & 0xFF,
		(dwIpAddress >>  8) & 0xFF, 
		(dwIpAddress      ) & 0xFF));

	pRequest = LocalAlloc(LPTR, sizeof(*pRequest));
	if (pRequest)
	{
		pRequest->dwIpAddress = dwIpAddress;
		pRequest->bAddProxy = bAddProxy;

		EnterCriticalSection(&g_CSArpProxyManagerRequestList);
		InsertTailList(&g_ArpProxyManagerRequestList, &pRequest->link);
		LeaveCriticalSection(&g_CSArpProxyManagerRequestList);

		SetEvent(g_hEventManagerRequestList);
	}
	else
	{
		dwResult = ERROR_OUTOFMEMORY;
	}

	return dwResult;
}

DWORD
ArpProxyManagerInitialize()
{
	DWORD dwResult = NO_ERROR;

	InitializeListHead(&g_ArpProxyList);
	InitializeListHead(&g_ArpProxyManagerRequestList);
	if (!g_hEventManagerRequestList)
		g_hEventManagerRequestList = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (!g_hEventAddrChange)
	g_hEventAddrChange = CreateEvent(NULL, FALSE, FALSE, NULL);
	InitializeCriticalSection(&g_CSArpProxyManagerRequestList);

	if (g_hEventManagerRequestList == NULL || g_hEventAddrChange == NULL)
	{
		dwResult = ERROR_OUTOFMEMORY;
	}

	return dwResult;
}


DWORD
ArpProxyManagerStart()
{
	DWORD dwThreadId;
	DWORD dwResult = NO_ERROR;

	if (!g_hAddrChangeThread)
		g_hAddrChangeThread = CreateThread(NULL, 0, ArpProxyAddrChangeNotifierThread, NULL, 0, &dwThreadId);
	if (!g_hProxyManagerThread)
		g_hProxyManagerThread = CreateThread(NULL, 0, ArpProxyManagerThread, NULL, 0, &dwThreadId);

	if (g_hAddrChangeThread == NULL || g_hProxyManagerThread == NULL)
	{
		dwResult = ERROR_OUTOFMEMORY;
	}

	return dwResult;
}

//
// End ARP Proxy Manager
//
//////////////////////////////////////////////////////////////////////////////////////

// Global Variables

PPPServerConfiguration_t PPPServerConfig;
CRITICAL_SECTION		 PPPServerCritSec;

PPPServerLineConfiguration_t *
PPPServerFindLineConfig(
	PLIST_ENTRY	pLineList,
	RASDEVINFO	*pRasDevInfo)
//
//	If the list contains a config with the given name and type, return a pointer to it.
//	Otherwise, return NULL.
//
{
	PPPServerLineConfiguration_t *pLineConfig;

	for (pLineConfig = (PPPServerLineConfiguration_t *)(pLineList->Flink);
		 TRUE;
		 pLineConfig = (PPPServerLineConfiguration_t *)pLineConfig->listEntry.Flink)
	{
		if (pLineConfig == (PPPServerLineConfiguration_t *)pLineList)
		{
			// Reached end of the list
			pLineConfig = NULL;
			break;
		}

		// Check for a matching name and type
		if ((_tcscmp(pRasDevInfo->szDeviceName, pLineConfig->rasDevInfo.szDeviceName) == 0)
		&&  (_tcscmp(pRasDevInfo->szDeviceType, pLineConfig->rasDevInfo.szDeviceType) == 0))
			break;		
	}

	return pLineConfig;
}

PPPServerLineConfiguration_t *
PPPServerFindLineWithSession(
	pppSession_t *pSession)
{
	PPPServerConfiguration_t *pConfig = &PPPServerConfig;
	PPPServerLineConfiguration_t *pLine, *pMatchingLine;

	pMatchingLine = NULL;
	for (pLine  = (PPPServerLineConfiguration_t *)(pConfig->LineList.Flink);
		 pLine != (PPPServerLineConfiguration_t *)(&pConfig->LineList);
		 pLine  = (PPPServerLineConfiguration_t *)pLine->listEntry.Flink)
	{
		if (pLine->pSession == pSession)
		{
			pMatchingLine = pLine;
			break;

⌨️ 快捷键说明

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