📄 pppserver.c
字号:
{
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 + -