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

📄 ip_intf.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
//-***********************************************************************
//
//  This file contains all of the code that sits under an IP interface
//  and does the necessary multiplexing/demultiplexing for WAN connections.
//
//-***********************************************************************

#include "windows.h"
#include "cxport.h"
#include "types.h"

// IP Header files to bind to the LLIP interface
#include "ndis.h"
#include "ntddip.h"
#include "ip.h"
#include "llipif.h"
#include "tdiinfo.h"
#include "ipinfo.h"
#include "llinfo.h"
#include "tdistat.h"
#include "cellip.h"

#include "memory.h"
#include "afdfunc.h"
#include "cclib.h"

#include "iphlpapi.h"

// VJ Compression Include Files

#define _TCPIP_H_NOIP
#include "tcpip.h"
#include "vjcomp.h"

//  PPP Include Files

#include "protocol.h"
#include "ppp.h"
#include "lcp.h"
#include "ipcp.h"
#include "ncp.h"
#include "mac.h"
#include "ip_intf.h"
#include "ipv6intf.h"
#include "crypt.h"
#include "pppserver.h"
#include "auth.h"
#include "util.h"
#include "debug.h"

#include <ndistapi.h>
#include <cenet.h>

// Function pointers into the upper layer IP stack

HMODULE         g_hTcpStkModule;
IPRcvRtn        IPRcv ;
IPTDCmpltRtn    IPTDComplete ;
IPTxCmpltRtn    IPSendComplete ;
IPStatusRtn     IPStatus ;
IPRcvCmpltRtn   IPRcvComplete ;
IPSetNTEAddrRtn IPSetNTEAddr ;
CEIPAddInterfaceRtn	g_pfnIPAddInterface;
CEIPDelInterfaceRtn	g_pfnIPDelInterface;

BOOL
GetIPProcAddresses(void)
//
//	Initialize function pointers into tcpstk.dll for adding
//	and removing interfaces.
//
{
	BOOL bOk = TRUE;
	DWORD dwResult;

	if (g_hTcpStkModule == NULL)
	{
		dwResult = CXUtilGetProcAddresses(TEXT("tcpstk.dll"), &g_hTcpStkModule,
						TEXT("CEIPAddInterface"), &g_pfnIPAddInterface,
						TEXT("CEIPDelInterface"), &g_pfnIPDelInterface,
						NULL);

		if (dwResult != NO_ERROR)
		{
			RETAILMSG(1, (TEXT("PPP: ERROR: Can't find CEIPAddInterface or CEIPDelInterface in tcpstk.dll!\n")));
			bOk = FALSE;
		}
	}

	return bOk;
}

#define IS_BCAST(x) ((((ulong)(x)) & 0x000000ffL) == 0x000000ffL)

//
// Local Functions
//

static  BOOL
IPConvertStringToAddress( WCHAR *AddressString, DWORD *AddressValue );

/******************************************************************************

 @doc INTERNAL

 @api ULONG | IPGetNetMask | Get the netmask for an address

 @parm ULONG | Addr | an IP address

 @rdesc ULONG | The netmask

********************************************************************/
ULONG
IPGetNetMask(ULONG Addr)
{
    ULONG   AddrType;

	//
	// Get the high byte of the address, which specifies the type
	// (A, B, C, D, E) or IP address.
	//
    AddrType = Addr >> 24;

    if (AddrType <= 127)
    {
		// Class A: Network address is upper 8 bits of an IP address
        return 0xff000000;
    }
    else if (AddrType <= 191)
    {
		// Class B: Network address is upper 16 bits of an IP address
        return 0xffff0000;
    }
    else
    {
		// Class C: Network address is upper 24 bits on an IP addres
        // Don't sweat the wierd stuff (class D or E, ...)

        return 0xffffff00;
    }

}

#ifdef DEBUG
#define PROTOCOL_TCP	6		// from tcpipw\h\tcp.h
#define IP_VER_FLAG		0xF0	// from tcpipw\ip\ipdef.h

BOOL
DumpIP (BOOL Direction, PBYTE Buffer, DWORD Len)
{
	IPHeader IPHdr;
	TCPHeader TCPHdr;

	if (Len < sizeof(IPHeader)) {
		return FALSE;
	}

	memcpy ((char *)&IPHdr, Buffer, sizeof(IPHdr));

	if (IPHdr.iph_protocol == PROTOCOL_TCP) {
		memcpy ((char *)&TCPHdr, Buffer + (IPHdr.iph_verlen & 0x0F)*4, sizeof(TCPHeader));
		NKDbgPrintfW (TEXT("%hs TCP %hs%hs%hs%hs%hs%hs, %d.%d.%d.%d(%d) => %d.%d.%d.%d(%d) Seq=%d-%d Ack=%d Win=%d\r\n"),
					  Direction ? "XMIT" : "RECV",
					  TCPHdr.tcp_flags & TCP_FLAG_URG ? "U" : ".",
					  TCPHdr.tcp_flags & TCP_FLAG_ACK  ? "A" : ".",
					  TCPHdr.tcp_flags & TCP_FLAG_PUSH ? "P" : ".",
					  TCPHdr.tcp_flags & TCP_FLAG_RST  ? "R" : ".",
					  TCPHdr.tcp_flags & TCP_FLAG_SYN  ? "S" : ".",
					  TCPHdr.tcp_flags & TCP_FLAG_FIN  ? "F" : ".",
					  IPHdr.iph_src & 0xFF,
					  (IPHdr.iph_src >> 8) & 0xFF,
					  (IPHdr.iph_src >> 16) & 0xFF,
					  (IPHdr.iph_src >> 24) & 0xFF,
					  net_short(TCPHdr.tcp_src),
					  IPHdr.iph_dest & 0xFF,
					  (IPHdr.iph_dest >> 8) & 0xFF,
					  (IPHdr.iph_dest >> 16) & 0xFF,
					  (IPHdr.iph_dest >> 24) & 0xFF,
					  net_short(TCPHdr.tcp_dest),
					  net_long(TCPHdr.tcp_seq),
					  net_long(TCPHdr.tcp_seq) + net_short(IPHdr.iph_length) -
					  ((IPHdr.iph_verlen & 0x0F)*4 +
					   (net_short(TCPHdr.tcp_flags) >> 12)*4),
					  net_long(TCPHdr.tcp_ack),
					  net_short(TCPHdr.tcp_window));
		return FALSE;
	} else {
		NKDbgPrintfW (TEXT("%hs IP ver=%d hlen=%d tos=0x%X len=%d id=%d offset=%d ttl=%d prot=%d xsum=%d Src=%d.%d.%d.%d Dest=%d.%d.%d.%d\r\n"),
					  Direction ? "XMIT" : "RECV",
					  (IPHdr.iph_verlen & IP_VER_FLAG) >> 4,
					  (IPHdr.iph_verlen & 0x0F)*4,
					  IPHdr.iph_tos,
					  net_short(IPHdr.iph_length),
					  net_short(IPHdr.iph_id), net_short(IPHdr.iph_offset),
					  IPHdr.iph_ttl, IPHdr.iph_protocol, net_short(IPHdr.iph_xsum),
					  IPHdr.iph_src & 0xFF,
					  (IPHdr.iph_src >> 8) & 0xFF,
					  (IPHdr.iph_src >> 16) & 0xFF,
					  (IPHdr.iph_src >> 24) & 0xFF,
					  IPHdr.iph_dest & 0xFF,
					  (IPHdr.iph_dest >> 8) & 0xFF,
					  (IPHdr.iph_dest >> 16) & 0xFF,
					  (IPHdr.iph_dest >> 24) & 0xFF);

	}

	return FALSE;
}
#endif

NDIS_STATUS
PppSendIPvX(
    PVOID		 Context,       // Pointer to ppp context.
    PNDIS_PACKET Packet,        // Pointer to packet to be transmitted.
	DWORD		 ipProto)		// 4 or 6
{
	PPP_CONTEXT *pContext = (PPP_CONTEXT *)Context;
	pppSession_t   *s_p = (pppSession_t *)(pContext->Session);
	NDIS_STATUS	 Status = NDIS_STATUS_SUCCESS;

	ASSERT(ipProto == 4 || ipProto == 6);

	//
	// Invoke packet debug extension if it is loaded.
	//
	if (g_pfnLogTxNdisPacket)
	{
		BOOL bDoSend;

		bDoSend = g_pfnLogTxNdisPacket(L"PPP", pContext->AdapterName, ipProto == 4 ? L"IP" : L"IPV6", Packet);
		if (!bDoSend)
			return Status;
	}

	// Validate the session and make sure it doesn't go away until transmit is done


	if (!PPPADDREF(s_p, REF_SENDIPVX))
	{
		Status = NDIS_STATUS_INVALID_PACKET;
	}
	else
    {
		// Protect the PPP Send
		pppLock( s_p );

		switch( s_p->Mode )
		{
		case PPPMODE_PPP:
			// Route to IP Data Transmit
			pppNcp_SendIPvX( s_p->ncpCntxt, Packet, ipProto == 4 ? NCP_IPCP : NCP_IPV6CP );
			break;

		case PPPMODE_SLIP:
			pppSendNdisBufferChainViaSLIP( s_p, Packet->Private.Head );
			break;

		case PPPMODE_CSLIP:
			// TBD - VJ Header compression
			// TBD - Send the packet
			break;

		default:
			ASSERT( 0 );
		}

		pppUnLock( s_p );

		// Transmit complete, it's ok if the session gets deleted now

		PPPDELREF(s_p, REF_SENDIPVX);
	}

	return Status;
}


//  Transmit
//
//  Function: Callout function for IP to tx data
//

NDIS_STATUS
Transmit( void              *Context,
          PNDIS_PACKET      Packet,
          IPAddr            Destination,
          RouteCacheEntry   *RCE )
{
    DEBUGMSG(ZONE_PPP, (TEXT( "PPP Transmit(%08X, %08X, %08X, %08X)\r\n" ),
          Context, Packet, Destination, RCE ));

#ifdef DEBUG
	if (dpCurSettings.ulZoneMask & 0xF0000000) {
		char		 TempPacket[2048];
		PNDIS_BUFFER pBuffer;
		DWORD		 Length = 0;
		PVOID		 VirtualAddress;
		UINT		 BufferLength;

		NdisQueryPacket(Packet, NULL, NULL, &pBuffer, NULL);
		while (pBuffer)
		{
			NdisQueryBuffer(pBuffer, &VirtualAddress, &BufferLength);
			if ((Length + BufferLength) > sizeof(TempPacket)) {
				NKDbgPrintfW (TEXT("PPP:Transmit Packet too large, truncating at %d\r\n"), Length);
				break;
			}
			memcpy (TempPacket+Length, VirtualAddress, BufferLength);
			Length += BufferLength;
			NdisGetNextBuffer(pBuffer, &pBuffer);
		}

		// Check top bit of zone mask.
		// Turn this on via zo m NNN 0x80000000
		if (dpCurSettings.ulZoneMask & 0x80000000) {
			// Try to decode the first chunk
			DumpIP (TRUE, TempPacket, Length);
		}
		if (dpCurSettings.ulZoneMask & 0x40000000) {
			NKDbgPrintfW (TEXT("PPP:Transmit len=%d\r\n"), Length);
			DumpMem(TempPacket, Length);            // Dump packet contents
		}
	}
#endif

	return PppSendIPvX(Context, Packet, 4);
}

//  Receive
//
//  Function: Send data up to IP
//

void
Receive(
	void		*session,
	pppMsg_t	*pMsg)
{
	HANDLE              threadId;
	PPP_CONTEXT         *pCurContext = (PPP_CONTEXT *)session;

    DEBUGMSG( ZONE_PPP|ZONE_LOCK,
              (TEXT("IPRcv LockWaitCnt=%d Locked=%d LockedCount=%d\r\n"),
              pCurContext->Session->LockWaitCnt,
              pCurContext->Session->Locked,
              pCurContext->Session->SesCritSec.LockCount));

	//
	// Invoke packet debug extension if it is loaded.
	//
	if (g_pfnLogRxContigPacket)
	{
		BOOL bDoReceive;

		bDoReceive = g_pfnLogRxContigPacket(L"PPP", pCurContext->AdapterName, L"IP", pMsg->data, pMsg->len);
		if (!bDoReceive)
			return;
	}

    // Print if lock count exceeds 1 as the receive
    // path should only have the lock once.

    if( pCurContext->Session->SesCritSec.LockCount > 1 )
    {
        DEBUGMSG( ZONE_ERROR, ( TEXT("IPRcv LockCount=%d\r\n"),
        pCurContext->Session->SesCritSec.LockCount) );
    }

    threadId = (HANDLE )GetCurrentThreadId();

    DEBUGMSG( ZONE_LOCK, (TEXT( "iprcv:Current    thread Id 0x%x\n" ), threadId ));
    DEBUGMSG( ZONE_LOCK, (TEXT( "iprcv:Lock Owner thread Id 0x%x\n" ),
        pCurContext->Session->SesCritSec.OwnerThread ));

    ASSERT( pCurContext->Session->SesCritSec.OwnerThread == threadId );

	// Intercept any DHCP ACK packet containing domain name
	if (pCurContext->Session->bDhcpTimerRunning)
	{
		if (PppDhcpRxPacket(pCurContext->Session, pMsg->data, pMsg->len))
		{
			return;
		}
	}

    pppUnLock( pCurContext->Session );

#ifdef DEBUG
	// Check top bit of zone mask.
	// Turn this on via zo m NNN 0x80000000
	if (dpCurSettings.ulZoneMask & 0x80000000) {
		// Try to decode the first chunk
		DumpIP (FALSE, pMsg->data, pMsg->len);
	}
	if (dpCurSettings.ulZoneMask & 0x40000000) {
		NKDbgPrintfW (TEXT("PPP: Recieve Len=%d\r\n"), pMsg->len);
		DumpMem(pMsg->data, pMsg->len);            // Dump packet contents
	}
#endif

	//
	//	IPCP may be OPEN but the interface not registered if we
	//	RequireDataEncryption is set and CCP is not OPEN yet.  In
	//	this case IPContext will be NULL until CCP enters the OPEN
	//	state and registers the interface with IP.  Until the
	//	interface is registered IP packets are discarded.
	//
	if (pCurContext->IPContext != NULL)
	{
		IPRcv( pCurContext->IPContext,      // IP's Context
			   pMsg->data,                  // The Packet
			   pMsg->len,                   // Data Size
			   pMsg->len,                   // Total Size
			   0,                           // Context1
			   0,                           // Context2
			   FALSE,                       // fBroadcast
			   NULL);                       // LINK
	}

    pppLock( pCurContext->Session );
}

void
ReceiveComplete(
	void		*session)
{
	if (IPRcvComplete != NULL)
		IPRcvComplete();
}




//  XferData
//
//  Function: Copy
//

NDIS_STATUS

XferData(   void            *Context,
            NDIS_HANDLE     MACContext,
            uint            MyOffset,
            uint            ByteOffset,
            uint            BytesWanted,
            PNDIS_PACKET    Packet,
            uint            *Transferred )
{
    DEBUGMSG (ZONE_PPP, (
    TEXT( "PPP XferData(%08X, %08X, %d, %d, %d, %08X, %08X)\r\n"),
           Context, MACContext, MyOffset, ByteOffset,
           BytesWanted, Packet, Transferred));

    ASSERT( 0 );

    return( NDIS_STATUS_SUCCESS );
}

void

Close( void *Context )
{
    PPP_CONTEXT     *pCurContext = (PPP_CONTEXT *)Context;

    DEBUGMSG (ZONE_PPP, (TEXT("PPP Close(%08X)\r\n"), Context));

    pCurContext->fOpen = FALSE;

    return;
}

void

Invalidate( void *Context, RouteCacheEntry *RCE )
{
    DEBUGMSG (ZONE_PPP, (TEXT("PPP Invalidate(%08X,%08X)\r\n"), Context, RCE));

    // No action

    return;
}

uint

AddAddr( void *Context, uint Type, IPAddr Address, IPMask Mask, PVOID pControlBlock )
{
    DEBUGMSG( ZONE_PPP, (
    TEXT( "PPP AddAddr(%08X,%d,%08X, %08X)\r\n"), Context,Type,Address,Mask));

    return( TRUE );
}

uint

DeleteAddr( void *Context, uint Type, IPAddr Address, IPMask Mask )
{
    DEBUGMSG (ZONE_PPP, (TEXT("PPP DeleteAddr(%08X,%d,%08X, %08X)\r\n"),
                  Context, Type, Address, Mask));

    return( TRUE );
}

void

Open( void *Context )
{
    DEBUGMSG (ZONE_PPP, (TEXT("PPP Open(%08X)\r\n"), Context));

⌨️ 快捷键说明

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