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

📄 option.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	DWORD		 cbOptData= *pcbOptData;
	DWORD		 peerRequestedIPAddress;
	static BYTE  IPAddrZero[4] = {0,0,0,0};

	if (pOptData == NULL)
	{
		//
		//	The peer did not send us its IP address in a Config-Request, and we want it to.
		//  So, we send a NAK with a 0 address.
		//
		*ppOptData = &IPAddrZero[0];
		*pcbOptData = 4;
	}
	else
	{
		//
		// The generic option handling code should have rejected any illegal sized option.
		//
		ASSERT(cbOptData == 4);

		IPADDR_TO_DWORD(peerRequestedIPAddress, pOptData);

		if (pSession->bIsServer)
		{
			if (pContext->peer.ipAddress == 0)
			{
				//
				// Get the IP address (static or DHCP) allocated
				// for the client side when the line was enabled
				//
				
				pContext->peer.ipAddress = PPPServerGetSessionClientIPAddress(pSession);
			}

			DEBUGMSG(ZONE_NCP, (TEXT("PPP: Server assigning IP Address %u.%u.%u.%u to client\n"), IPADDROUT(pContext->peer.ipAddress)));
			
			if (pContext->peer.ipAddress == 0)
			{
				// Unable to obtain an IP address for the client
				*pCode = PPP_CONFIGURE_REJ;
			}
			else
			{
				//
				//	If we are a server, then we will only allow the client to use
				//	the IP address we assign.  If the client requests any other
				//	address (including 0), we NAK and tell him the address to use.
				//
				if (peerRequestedIPAddress == pContext->peer.ipAddress)
				{
					*pCode = PPP_CONFIGURE_ACK;
				}
				else
				{
					DWORD_TO_IPADDR(&pContext->optDataIPAddress[0], pContext->peer.ipAddress);
					*pCode = PPP_CONFIGURE_NAK;
					*ppOptData = &pContext->optDataIPAddress[0];
				}
			}
		}
		else
		{
			//
			//	If we are a client, then we will allow the server to use any
			//	address it wants, except 0.
			//
			pContext->peer.ipAddress = peerRequestedIPAddress;

			if (peerRequestedIPAddress != 0)
			{
				*pCode = PPP_CONFIGURE_ACK;
			}
			else
			{
				RASPENTRY   *pRasEntry = &pSession->rasEntry;

								if (pContext->local.ipAddress == 0)
				{
					memcpy( &pContext->local.ipAddress, &pRasEntry->ipaddr, 4 );
				}
				DWORD_TO_IPADDR(&pContext->optDataIPAddress[0], pContext->local.ipAddress);
				pContext->optDataIPAddress[3] += 1;
				*pCode = PPP_CONFIGURE_NAK;
				*ppOptData = &pContext->optDataIPAddress[0];

				DEBUGMSG( ZONE_IPCP, (TEXT( "PPP: Server Trying to use 0.0.0.0 IP ADDRESS, PROB W95, substituting...: 0x%X\r\n" ), pContext->local.ipAddress + 1 ) );
			}
		}
	}
	return dwResult;
}

/////////////	Name Server Address configuration callbacks //////////////

DWORD
ipcpBuildNSAddressOptionCb(
	IN		PVOID  context,
	IN	OUT	POptionInfo pInfo,
	OUT		PBYTE  pOptData,
	OUT		PDWORD pcbOptData)
//
//	Called to fill in the data for a name server IP Address option
//	that is part of a configure-request we will send to the peer.
//
{
	PIPCPContext pContext = (PIPCPContext)context;
	pppSession_t *pSession = pContext->session;
	DWORD	     dwResult = NO_ERROR;

	PBYTE pAddr;

	switch( pInfo->pDescriptor->type)
	{
	case IPCP_OPT_DNS_IP_ADDR:           pAddr = (PBYTE)&pSession->rasEntry.ipaddrDns;    break;
	case IPCP_OPT_WINS_IP_ADDR:          pAddr = (PBYTE)&pSession->rasEntry.ipaddrWins;   break;
	case IPCP_OPT_DNS_BACKUP_IP_ADDR:    pAddr = (PBYTE)&pSession->rasEntry.ipaddrDnsAlt; break;
	case IPCP_OPT_WINS_BACKUP_IP_ADDR:   pAddr = (PBYTE)&pSession->rasEntry.ipaddrWinsAlt;break;
	default: ASSERT(FALSE); return ERROR_INVALID_PARAMETER;
	}

	//
	// This is a kludge to support ActiveSync. ActiveSync silently drops 0.0.0.0 name
	// server addresses from its ACK messages without REJecting them. It will NAK the
	// DNS address. So, after receiving a NAK for one or more name server addresses
	// do not send 0.0.0.0 name server addresses in any subsequent config-requests.
	//
	if (pContext->bNakReceived && *(PDWORD)pAddr == 0)
	{
		dwResult = ERROR_PPP_SKIP_OPTION;
	}
	else
	{
		// RASIPADDR is stored LSB first, option is MSB first
		pOptData[0] = pAddr[3];
		pOptData[1] = pAddr[2];
		pOptData[2] = pAddr[1];
		pOptData[3] = pAddr[0];
		*pcbOptData = 4;
	}

	return dwResult;
}

DWORD
ipcpAckNSAddressOptionCb(
	IN		PVOID  context,
	IN	OUT	POptionInfo pInfo,
	IN		PBYTE  pOptData,
	IN		DWORD  cbOptData)
//
//	Called when the peer ACKs a name server IP address option
//	that we sent in a CR.
//
{
	PIPCPContext pContext = (PIPCPContext)context;
	DWORD	     dwResult = NO_ERROR;

	// This is where we should commit to using the name server addresses...
	// Currently they are committed in the Nak callback.

	return dwResult;
}

DWORD
ipcpNakNSAddressOptionCb(
	IN		PVOID  context,
	IN OUT	struct OptionInfo *pInfo,
	IN		PBYTE  pOptData,
	IN		DWORD  cbOptData)
//
//	Called when the peer NAKs a name server IP address option
//	that we sent in a CR.
//
{
	PIPCPContext pContext = (PIPCPContext)context;
	pppSession_t *pSession = pContext->session;
	DWORD	     dwResult = NO_ERROR;
	DWORD		 ipAddrNameServer;

	//
	// We only send a configure-request with name server address options
	// if we are configured as a client.
	//
	ASSERT(!pSession->bIsServer);

	//
	// The generic option handling code should have rejected any illegal sized option.
	//
	ASSERT(cbOptData == 4);

	IPADDR_TO_DWORD(ipAddrNameServer, pOptData);

	pContext->bNakReceived = TRUE;

	if (ipAddrNameServer == 0 || ipAddrNameServer == 0xFFFFFFFF)
	{
		//
		//	IP address is 0 or the broadcast address, neither of which
		//	is valid.  We will ignore it and do no further negotiation
		//	of this option (treat it as if the peer had REJected it instead).
		//
		pInfo->onsLocal = ONS_Rejected;
		DEBUGMSG(ZONE_WARN, (TEXT("PPP: WARNING - Server NAKed option %hs with Invalid IPAddr=%x\n"), 
			pInfo->pDescriptor->szName, ipAddrNameServer));
	}
	else
	{
		PVOID pAddr;

		//
		//	IP address seems reasonable. Save it for use in subsequent config-request
		//

		switch( pInfo->pDescriptor->type)
		{
		case IPCP_OPT_DNS_IP_ADDR:           pAddr = &pSession->rasEntry.ipaddrDns;    break;
		case IPCP_OPT_WINS_IP_ADDR:          pAddr = &pSession->rasEntry.ipaddrWins;   break;
		case IPCP_OPT_DNS_BACKUP_IP_ADDR:    pAddr = &pSession->rasEntry.ipaddrDnsAlt; break;
		case IPCP_OPT_WINS_BACKUP_IP_ADDR:   pAddr = &pSession->rasEntry.ipaddrWinsAlt;break;
		default: ASSERT(FALSE); pAddr = NULL; break;
		}
		if (pAddr)
			memcpy( pAddr, &ipAddrNameServer, sizeof( DWORD ) );
	}

	return dwResult;
}

DWORD
ipcpRequestNSAddressCb(
	IN	OUT	PVOID context,
	IN	OUT	POptionInfo pInfo,
		OUT	PBYTE		pCode,
	IN	OUT	PBYTE		*ppOptData,
	IN	OUT	PDWORD		pcbOptData)
//
//	Called when we receive an IPCP configure request containing
//	DNS or WINS primary or secondary IP Address option.  If the IP address is 0, then
//  the peer is requesting that we NAK with an IP address for it
//  to use.
//
{
	PIPCPContext pContext = (PIPCPContext)context;
	DWORD	     dwResult = NO_ERROR;
	PBYTE		 pOptData = *ppOptData;
	DWORD		 cbOptData= *pcbOptData;
	DWORD		 peerRequestedNameServerAddress;
	DWORD		 ipAddrNameServer;

	//
	// The generic option handling code will reject this option unless we are a server,
	// per our call to PppFsmOptionsAdd.
	//
	ASSERT(pContext->session->bIsServer);

	//
	// The generic option handling code should have rejected any illegal sized option.
	//
	ASSERT(cbOptData == 4);

	IPADDR_TO_DWORD(peerRequestedNameServerAddress, pOptData);

	//
	// If we are a server then the client requests the addresses of the name
	// servers by sending them in a CR with values of 0
	//
	if (peerRequestedNameServerAddress == 0)
	{
		//
		// Get IP address of appropriate name server
		//
		switch(pInfo->pDescriptor->type)
		{
		case IPCP_OPT_DNS_IP_ADDR:
			ipAddrNameServer = g_dwDNSIpAddr[0];
			break;

		case IPCP_OPT_DNS_BACKUP_IP_ADDR:
			ipAddrNameServer = g_dwDNSIpAddr[1];
			break;

		case IPCP_OPT_WINS_IP_ADDR:
			ipAddrNameServer = g_dwWINSIpAddr[0];
			break;

		case IPCP_OPT_WINS_BACKUP_IP_ADDR:
			ipAddrNameServer = g_dwWINSIpAddr[1];
			break;

		default:
			ASSERT(FALSE);
			ipAddrNameServer = 0;
			break;
		}

		//
		// If we don't have a valid name server, reject the option.
		// Otherwise, NAK and tell the client the name server address.
		//

		if (ipAddrNameServer == 0)
		{
			*pCode = PPP_CONFIGURE_REJ;
		}
		else
		{
			DWORD_TO_IPADDR(&pContext->optDataIPAddress[0], ipAddrNameServer);		
			*pCode = PPP_CONFIGURE_NAK;
			*ppOptData = &pContext->optDataIPAddress[0];
		}
	}
	else
	{
		// Presumably the client is sending the name server address
		// that we previously NAKed with.  Regardless, accept the name
		// server IP address the client has chosen.

		*pCode = PPP_CONFIGURE_ACK;
	}

	return dwResult;
}

//
//	Constant information describing IPCP options:
//
OptionDescriptor ipcpIPCompressionOptionDescriptor =
{
	IPCP_OPT_IPCOMPRESSION,			// type == IP-Compression-Protocol
	OPTION_VARIABLE_LENGTH,			// can be 2 or more octets
	"IP-Compression-Protocol",		// name
	ipcpBuildIPCompressionOptionCb,
	ipcpAckIPCompressionOptionCb,
	ipcpNakIPCompressionOptionCb,
	NULL,							// no special reject handling
	ipcpRequestIPCompressionCb,
	ipCompressionOptionToStringCb		// debug routine
};

OptionDescriptor ipcpIPAddressOptionDescriptor =
{
	IPCP_OPT_IPADDRESS,			    // type == IP-Address
	4,			                    // always exactly 4 octets
	"IP-Address",		            // name
	ipcpBuildIPAddressOptionCb,
	ipcpAckIPAddressOptionCb,
	ipcpNakIPAddressOptionCb,
	ipcpRejIPAddressOptionCb,
	ipcpRequestIPAddressCb,
	ipAddressOptionToStringCb		// debug routine
};

OptionDescriptor ipcpDNSAddressOptionDescriptor =
{
	IPCP_OPT_DNS_IP_ADDR,			// type == DNS-Address
	4,			                    // always exactly 4 octets
	"DNS-Address",		            // name
	ipcpBuildNSAddressOptionCb,
	ipcpAckNSAddressOptionCb,
	ipcpNakNSAddressOptionCb,
	NULL,							// no special reject handling
	ipcpRequestNSAddressCb,
	ipAddressOptionToStringCb		// debug routine
};

OptionDescriptor ipcpWINSAddressOptionDescriptor =
{
	IPCP_OPT_WINS_IP_ADDR,			// type == WINS-Address
	4,			                    // always exactly 4 octets
	"WINS-Address",		            // name
	ipcpBuildNSAddressOptionCb,
	ipcpAckNSAddressOptionCb,
	ipcpNakNSAddressOptionCb,
	NULL,							// no special reject handling
	ipcpRequestNSAddressCb,
	ipAddressOptionToStringCb		// debug routine
};

OptionDescriptor ipcpDNSBackupAddressOptionDescriptor =
{
	IPCP_OPT_DNS_BACKUP_IP_ADDR,	// type == DNS-Backup-Address
	4,			                    // always exactly 4 octets
	"DNS-Backup-Address",		    // name
	ipcpBuildNSAddressOptionCb,
	ipcpAckNSAddressOptionCb,
	ipcpNakNSAddressOptionCb,
	NULL,							// no special reject handling
	ipcpRequestNSAddressCb,
	ipAddressOptionToStringCb		// debug routine
};

OptionDescriptor ipcpWINSBackupAddressOptionDescriptor =
{
	IPCP_OPT_WINS_BACKUP_IP_ADDR,	// type == WINS-Backup-Address
	4,			                    // always exactly 4 octets
	"WINS-Backup-Address",		    // name
	ipcpBuildNSAddressOptionCb,
	ipcpAckNSAddressOptionCb,
	ipcpNakNSAddressOptionCb,
	NULL,							// no special reject handling
	ipcpRequestNSAddressCb,
	ipAddressOptionToStringCb		// debug routine
};

DWORD
ipcpOptionInit(
	PIPCPContext pContext)
//
//	This function is called once during session initialization
//	to build the list of options that are supported.
//
{
	DWORD       dwResult;
	pppSession_t *pSession = pContext->session;
	RASPENTRY   *pRasEntry = &pSession->rasEntry;
	OptionRequireLevel orlIPCompressionLocal,
		               orlIPCompressionPeer,
		               orlNSLocal,
					   orlNSPeer;

	orlIPCompressionLocal = ORL_Unsupported;
	orlIPCompressionPeer  = ORL_Unsupported;
	if(pRasEntry->dwfOptions & RASEO_IpHeaderCompression )
    {
		//
        // Negotiate IP header compression - ie Request header compression
        // in our CR and accept it in our peer's CR.
		//
		orlIPCompressionLocal = ORL_Wanted;
		orlIPCompressionPeer  = ORL_Allowed;
	}

	orlNSLocal = ORL_Unsupported;
	orlNSPeer =  ORL_Unsupported;

	if (pSession->bIsServer)
	{
		//
		//	If we are a server, then we want to allow clients to obtain DNS
		//	and WINS server addresses from us.
		//
		orlNSPeer =  ORL_Allowed;
	}
	else
	{
		//
		//	If we are a client, then we want to try to obtain DNS and WINS
		//	server addresses from the server, if:
		//		bAlwaysRequestDNSandWINS registry flag is set, OR
		//      static DNS/WINS addresses were not set
		//
		if (pSession->dwAlwaysRequestDNSandWINS
		||  (pRasEntry->dwfOptions & RASEO_SpecificNameServers) == 0)
		{
			orlNSLocal = ORL_Wanted;
		}
	}

	dwResult = PppFsmOptionsAdd(pContext->pFsm,
							&ipcpIPCompressionOptionDescriptor,    orlIPCompressionLocal, orlIPCompressionPeer,
							&ipcpIPAddressOptionDescriptor,        ORL_Wanted, ORL_Allowed,
							&ipcpDNSAddressOptionDescriptor,       orlNSLocal, orlNSPeer,
							&ipcpWINSAddressOptionDescriptor,      orlNSLocal, orlNSPeer,
							&ipcpDNSBackupAddressOptionDescriptor, orlNSLocal, orlNSPeer,
							&ipcpWINSBackupAddressOptionDescriptor,orlNSLocal, orlNSPeer,
							NULL);

	return dwResult;
}

⌨️ 快捷键说明

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