📄 pppserver.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//
// PPP Server implementation module
//
// Include Files
#include "windows.h"
#include "cclib.h"
#include "types.h"
#include "netui.h"
#include "cxport.h"
#include "crypt.h"
#include "memory.h"
#include "wincrypt.h"
#include "ntlmssp.h"
#include "ntlmi.h"
// VJ Compression Include Files
#include "ndis.h"
#include "tcpip.h"
#include "vjcomp.h"
// PPP Include Files
#include "protocol.h"
#include "ppp.h"
#include "auth.h"
#include "lcp.h"
#include "ipcp.h"
#include "ncp.h"
#include "mac.h"
#include "raserror.h"
#include "util.h"
#include "ip_intf.h"
#include "pppserver.h"
#include "iphlpapi.h"
#include "dhcp.h"
DWORD g_dwTotalLineCount = 0;
#define PPP_SERVER_DEFAULT_STARTUP_DELAY_SECONDS 15
#define PPP_REGKEY_PARMS TEXT("Comm\\ppp\\Server\\Parms")
#define PPP_REGKEY_USER TEXT("Comm\\ppp\\Server\\User")
#define PPP_REGKEY_LINE TEXT("Comm\\ppp\\Server\\Line")
#define PPP_REGKEY_LINE_LEN 21
#define RAS_USERS_GROUP_NAME L"RasUsers"
DWORD
PPPServerLineDisable(
IN PPPServerLineConfiguration_t *pLine);
DWORD
PPPServerLineEnable(
IN PPPServerLineConfiguration_t *pLine);
typedef DWORD (*pfnGetNetworkParams) (PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
typedef DWORD (*pfnGetAdaptersInfo) (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
typedef DWORD (*pfnGetIpAddrTable)(
PMIB_IPADDRTABLE pIpAddrTable, // buffer for mapping table
PULONG pdwSize, // size of buffer
BOOL bOrder // sort the table
);
typedef DWORD (*pfnGetIfEntry)(
PMIB_IFROW pRow);
typedef DWORD (*pfnSendARP)(
IPAddr DestIP, // destination IP address
IPAddr SrcIP, // IP address of sender (optional)
PULONG pMacAddr, // returned physical address
PULONG PhyAddrLen // length of returned physical addr.
);
BOOL (*g_pfnCESetDHCPNTEByName)(PWSTR);
typedef DWORD (* PFN_GETIFTABLE)(
PMIB_IFTABLE pIfTable,
PULONG pdwSize,
BOOL bOrder
);
typedef DWORD (* PFN_GETADAPTERSINFO)(
PIP_ADAPTER_INFO pAdapterInfo,
PULONG pOutBufLen
);
typedef DWORD (* PFN_CREATEPROXYARPENTRY)(
DWORD dwIpAddressToProxy,
DWORD dwSubnetMask,
DWORD dwIfIndex
);
typedef DWORD (* PFN_DELETEPROXYARPENTRY)(
DWORD dwIpAddressToProxy,
DWORD dwSubnetMask,
DWORD dwIfIndex
);
typedef DWORD (* PFN_GETADAPTERINDEX)(
LPWSTR AdapterName,
PULONG IfIndex
);
typedef DWORD (* PFN_CREATEIPFORWARDENTRY)(
PMIB_IPFORWARDROW pRoute
);
typedef DWORD (* PFN_DELETEIPFORWARDENTRY)(
PMIB_IPFORWARDROW pRoute
);
typedef DWORD (* PFN_NOTIFYADDRCHANGE)(
);
HINSTANCE g_hTcpIpMod = NULL;
HINSTANCE g_hIpHlpApiMod = NULL;
PFN_NOTIFYADDRCHANGE g_pfnNotifyAddrChange;
PFN_CREATEIPFORWARDENTRY g_pfnCreateIpForwardEntry;
PFN_CREATEPROXYARPENTRY g_pfnCreateProxyArpEntry;
PFN_DELETEPROXYARPENTRY g_pfnDeleteProxyArpEntry;
PFN_DELETEIPFORWARDENTRY g_pfnDeleteIpForwardEntry;
pfnGetAdaptersInfo g_pfnGetAdaptersInfo;
PFN_GETADAPTERINDEX g_pfnGetAdapterIndex;
pfnGetIfEntry g_pfnGetIfEntry;
pfnGetIpAddrTable g_pfnGetIpAddrTable;
pfnGetNetworkParams g_pfnGetNetworkParams;
pfnSendARP g_pfnSendARP;
DWORD
CountListEntries(
PLIST_ENTRY pListHead)
{
PLIST_ENTRY pEntry;
DWORD nEntries = 0;
for (pEntry = pListHead->Flink; pEntry != pListHead; pEntry = pEntry->Flink)
nEntries++;
return nEntries;
}
////////////////////////// Proxy ARP Support Module //////////////////////////
//
// The IP Helper support for ARP Proxying is pretty primitive. It just allows
// ARP proxying to be enabled one interface at a time. One particular limitation
// is that it does not track the coming and going of interfaces.
//
// This Proxy ARP Support Module keeps track of all the addresses being proxied,
// and ensures that each one gets proxied on all applicable interfaces that are
// available at any moment in time. When interfaces are added, ARP proxies will
// be set up for them if appropriate. When interfaces are deleted, proxies will
// be disabled from those interfaces.
//
LIST_ENTRY g_ArpProxyList;
typedef struct
{
LIST_ENTRY link;
DWORD dwIpAddress; // Ip Address being proxied
LIST_ENTRY IfList; // List of IfListEntry - interfaces this address proxied on
} ArpProxyListEntry, *PArpProxyListEntry;
typedef struct
{
LIST_ENTRY link;
DWORD dwIfIndex;
} IfListEntry, *PIfListEntry;
#define ARP_PROXY_DO_VALIDATION 1
#ifdef ARP_PROXY_DO_VALIDATION
static void
ListValidate(
IN PLIST_ENTRY List
)
{
ULONG Nodes = 0;
PLIST_ENTRY Prev, Curr;
Prev = List;
Curr = List->Flink;
while (TRUE)
{
if (Curr == NULL)
{
RETAILMSG(1, (L"PPP Server: Malformed list %x node #%u is NULL\n", List, Nodes));
DebugBreak();
break;
}
if (Curr->Blink != Prev)
{
RETAILMSG(1, (L"PPP Server: Malformed list %x at node %x #%u invalid Blink\n", List, Curr, Nodes));
DebugBreak();
break;
}
if (Curr == List)
{
// reached the end
break;
}
Nodes++;
if (Nodes > 10000)
{
RETAILMSG(1, (L"PPP Server: Malformed list %x has too many nodes\n", List));
DebugBreak();
break;
}
Prev = Curr;
Curr = Curr->Flink;
}
}
static void
APInsertTailList(
IN PLIST_ENTRY pList,
IN PLIST_ENTRY pNode)
{
ListValidate(pList);
InsertTailList(pList, pNode);
ListValidate(pList);
}
static void
APRemoveEntryList(
IN PLIST_ENTRY pList,
IN PLIST_ENTRY pNode)
{
ListValidate(pList);
RemoveEntryList(pNode);
ListValidate(pList);
}
static void
APValidateAllLists()
{
PArpProxyListEntry pEntry;
ListValidate(&g_ArpProxyList);
for (pEntry = (PArpProxyListEntry)(g_ArpProxyList.Flink);
pEntry != (PArpProxyListEntry)(&g_ArpProxyList);
pEntry = (PArpProxyListEntry)pEntry->link.Flink)
{
ListValidate(&pEntry->IfList);
}
}
#else
#define APInsertTailList(pList,pNode) InsertTailList((pList),(pNode))
#define APRemoveEntryList(pList,pNode) RemoveEntryList((pNode))
#define APValidateAllLists() (void)0
#define ListValidate(pList) (void)0
#endif
BOOLEAN
IFTypeIsLAN(
DWORD dwIfIndex)
//
// Determine whether the specified interface is of the LAN type.
//
{
BOOL bIsLAN = TRUE;
MIB_IFROW row;
DWORD dwResult;
if (g_pfnGetIfEntry)
{
row.dwIndex = dwIfIndex;
dwResult = g_pfnGetIfEntry(&row);
if (dwResult == NO_ERROR)
{
bIsLAN = row.dwType == MIB_IF_TYPE_ETHERNET || row.dwType == MIB_IF_TYPE_TOKENRING;
}
}
return bIsLAN;
}
DWORD
PPPServerGetIPAddrTable(
OUT PMIB_IPADDRTABLE *ppTable,
OUT PDWORD pcbTable OPTIONAL)
//
// Call the IP helper API GetIPAddrTable to allocate
// space for and retrieve the table. The caller must
// free the returned table pointer when done with it.
//
{
DWORD dwResult = ERROR_NOT_SUPPORTED;
PMIB_IPADDRTABLE pTable = NULL;
DWORD cbTable = 0;
if (g_pfnGetIpAddrTable)
{
dwResult = g_pfnGetIpAddrTable(pTable, &cbTable, FALSE);
pTable = LocalAlloc(LPTR, cbTable);
if (pTable == NULL)
{
dwResult = ERROR_OUTOFMEMORY;
cbTable = 0;
}
else
{
dwResult = g_pfnGetIpAddrTable(pTable, &cbTable, FALSE);
if (dwResult != NO_ERROR)
{
LocalFree(pTable);
pTable = NULL;
cbTable = 0;
}
}
}
*ppTable = pTable;
if (pcbTable)
*pcbTable = cbTable;
return dwResult;
}
DWORD
PPPServerCreateProxyArpEntry(
DWORD dwIpAddressToProxy,
DWORD dwMask,
DWORD dwIfIndex)
{
DWORD dwResult = ERROR_NOT_SUPPORTED;
if (g_pfnCreateProxyArpEntry)
{
DEBUGMSG(ZONE_TRACE, (TEXT("PPP: Creating Proxy ARP entry for address %u.%u.%u.%u on IF %x\n"),
(dwIpAddressToProxy >> 24) & 0xFF,
(dwIpAddressToProxy >> 16) & 0xFF,
(dwIpAddressToProxy >> 8) & 0xFF,
(dwIpAddressToProxy ) & 0xFF,
dwIfIndex));
dwResult = g_pfnCreateProxyArpEntry(htonl(dwIpAddressToProxy), dwMask, dwIfIndex);
DEBUGMSG(ZONE_ERROR && dwResult, (TEXT("PPP: ERROR %d Creating Proxy ARP entry for address %u.%u.%u.%u on IF %x\n"),
dwResult,
(dwIpAddressToProxy >> 24) & 0xFF,
(dwIpAddressToProxy >> 16) & 0xFF,
(dwIpAddressToProxy >> 8) & 0xFF,
(dwIpAddressToProxy ) & 0xFF,
dwIfIndex));
}
return dwResult;
}
DWORD
PPPServerDeleteProxyArpEntry(
DWORD dwIpAddressToProxy,
DWORD dwMask,
DWORD dwIfIndex)
{
DWORD dwResult = ERROR_NOT_SUPPORTED;
if (g_pfnDeleteProxyArpEntry)
{
DEBUGMSG(ZONE_TRACE, (TEXT("PPP: Deleting Proxy ARP entry for address %u.%u.%u.%u on IF %x\n"),
(dwIpAddressToProxy >> 24) & 0xFF,
(dwIpAddressToProxy >> 16) & 0xFF,
(dwIpAddressToProxy >> 8) & 0xFF,
(dwIpAddressToProxy ) & 0xFF,
dwIfIndex));
dwResult = g_pfnDeleteProxyArpEntry(htonl(dwIpAddressToProxy), dwMask, dwIfIndex);
}
return dwResult;
}
PArpProxyListEntry
ArpProxyListEntryNew(
DWORD dwIpAddressToProxy)
//
// Create a new arp proxy list entry and add it to the global list.
//
{
PArpProxyListEntry pEntry;
pEntry = pppAllocateMemory(sizeof(*pEntry));
if (pEntry)
{
pEntry->dwIpAddress = dwIpAddressToProxy;
InitializeListHead(&pEntry->IfList);
APInsertTailList(&g_ArpProxyList, &pEntry->link);
DEBUGMSG(ZONE_TRACE, (TEXT("PPP: Start Managing ARP proxies for address %u.%u.%u.%u\n"),
(dwIpAddressToProxy >> 24) & 0xFF,
(dwIpAddressToProxy >> 16) & 0xFF,
(dwIpAddressToProxy >> 8) & 0xFF,
(dwIpAddressToProxy ) & 0xFF));
}
return pEntry;
}
void
ArpProxyListEntryDelete(
PArpProxyListEntry pEntry)
{
DEBUGMSG(ZONE_TRACE, (TEXT("PPP: Stop Managing ARP proxies for address %u.%u.%u.%u\n"),
(pEntry->dwIpAddress >> 24) & 0xFF,
(pEntry->dwIpAddress >> 16) & 0xFF,
(pEntry->dwIpAddress >> 8) & 0xFF,
(pEntry->dwIpAddress ) & 0xFF));
ASSERT(IsListEmpty(&pEntry->IfList));
APRemoveEntryList(&g_ArpProxyList, &pEntry->link);
pEntry->link.Flink = (PVOID)0xDEADDEAD;
pEntry->link.Blink = (PVOID)0xDEADDEAD;
pppFreeMemory(pEntry, sizeof(*pEntry));
}
PIfListEntry
ArpIfListEntryNew(
IN PArpProxyListEntry pEntry,
IN DWORD dwIfIndex)
//
// Create a new IF entry and add it to the IF list for the particular IP address.
// Proxy that IP address on the IF.
//
{
PIfListEntry pIfEntry;
pIfEntry = pppAllocateMemory(sizeof(*pIfEntry));
if (pIfEntry)
{
pIfEntry->dwIfIndex = dwIfIndex;
PPPServerCreateProxyArpEntry(pEntry->dwIpAddress, 0xFFFFFFFF, pIfEntry->dwIfIndex);
APInsertTailList(&pEntry->IfList, &pIfEntry->link);
}
return pIfEntry;
}
void
ArpIfListEntryDelete(
IN PArpProxyListEntry pEntry,
IN PIfListEntry pIfEntry)
//
// Remove the interface from the list of interfaces proxying the address.
// Stop proxying the address on that interface.
//
{
APRemoveEntryList(&pEntry->IfList, &pIfEntry->link);
pIfEntry->link.Flink = (PVOID)0xDEADDEAD;
pIfEntry->link.Blink = (PVOID)0xDEADDEAD;
PPPServerDeleteProxyArpEntry(pEntry->dwIpAddress, 0xFFFFFFFF, pIfEntry->dwIfIndex);
pppFreeMemory(pIfEntry, sizeof(*pIfEntry));
}
void
ArpProxyListEntryUnproxyAll(
PArpProxyListEntry pEntry)
//
// Unproxy this entry's address on all the entries for which it is currently proxied.
//
{
while (!IsListEmpty(&pEntry->IfList))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -