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

📄 pppserver.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// 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 + -