Ejemplo n.º 1
0
u8* _malloc(u32 sz)
{

	u8 	*pbuf;

#ifdef PLATFORM_LINUX
#ifdef RTK_DMP_PLATFORM
	if(sz > 0x4000)
		pbuf = dvr_malloc(sz);
	else
#endif
		pbuf = 	kmalloc(sz, /*GFP_KERNEL*/GFP_ATOMIC);

#endif	
	
#ifdef PLATFORM_WINDOWS

	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);

#endif
	if ( pbuf == NULL )
		printk( "[%s] allocate memory failed! sz = %d\n", __FUNCTION__, sz);
	
	return pbuf;	
	
}
Ejemplo n.º 2
0
BOOLEAN
FilterPacket_ReceiveHandler (
	PVOID pHeadBuffer,
	ULONG ulHeadSize,
	PNDIS_PACKET pPacket
	)
/*++

Routine Description:

	Filters network packets for NDISReceiveHandler.


Arguments:

	...


Return Value:

	TRUE: This packet should be blocked.

	FALSE: This packet should pass through.


Author:

	xiaonie

	2012/07/12


--*/
{
	ULONG ulPacketSize;
	PUCHAR pBuffer = NULL;
	NDIS_STATUS status;
	PNDIS_BUFFER pFirstBuffer, pNextBuffer;
	BOOLEAN bRet = FALSE;

	NdisQueryPacket(pPacket, NULL, NULL, NULL, &ulPacketSize);
	if (ulPacketSize == 0)
		return FALSE;

	DbgPrint("ulHeadSize == %d, ulPacketSize == %d in FilterPacket_ReceiveHandler!\r\n", ulHeadSize, ulPacketSize);

	status = NdisAllocateMemoryWithTag(&pBuffer, ulPacketSize + ulHeadSize, '!nmN');
	if (status != NDIS_STATUS_SUCCESS/* || pBuffer == NULL */)
		return FALSE;

	//obtain content from the packet
	NdisMoveMemory(pBuffer, pHeadBuffer, ulHeadSize);
	ReadPacket(pPacket, pBuffer + ulHeadSize, ulPacketSize);

	bRet = RabbitHole(pBuffer, ulPacketSize + ulHeadSize);

	NdisFreeMemory(pBuffer, ulPacketSize + ulHeadSize, 0);

	return bRet;
}
Ejemplo n.º 3
0
u8* _rtw_malloc(u32 sz)
{

	u8 	*pbuf=NULL;

#ifdef PLATFORM_LINUX
#ifdef RTK_DMP_PLATFORM
	if(sz > 0x4000)
		pbuf = (u8 *)dvr_malloc(sz);
	else
#endif		
		pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); 		

#endif	
#ifdef PLATFORM_FREEBSD
	pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);	
#endif		
#ifdef PLATFORM_WINDOWS

	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);

#endif

#ifdef DBG_MEMORY_LEAK
#ifdef PLATFORM_LINUX
	if ( pbuf != NULL) {
		atomic_inc(&_malloc_cnt);
		atomic_add(sz, &_malloc_size);
	}
#endif
#endif /* DBG_MEMORY_LEAK */

	return pbuf;	
	
}
Ejemplo n.º 4
0
PVOID
MemAlloc(
    __in ULONG p_Size,
    __in BOOLEAN zero
)
{
    PVOID l_Return = NULL;

    if (p_Size)
    {
        __try
        {
            if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT')
                    == NDIS_STATUS_SUCCESS)
            {
                if (zero)
                {
                    NdisZeroMemory (l_Return, p_Size);
                }
            }
            else
            {
                l_Return = NULL;
            }
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            l_Return = NULL;
        }
    }

    return l_Return;
}
Ejemplo n.º 5
0
inline u8* _rtw_vmalloc(u32 sz)
{
	u8 	*pbuf;
#ifdef PLATFORM_LINUX	
	pbuf = vmalloc(sz);
#endif	
#ifdef PLATFORM_FREEBSD
	pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);	
#endif	
	
#ifdef PLATFORM_WINDOWS
	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);	
#endif

#ifdef DBG_MEMORY_LEAK
#ifdef PLATFORM_LINUX
	if ( pbuf != NULL) {
		atomic_inc(&_malloc_cnt);
		atomic_add(sz, &_malloc_size);
	}
#endif
#endif /* DBG_MEMORY_LEAK */

	return pbuf;	
}
Ejemplo n.º 6
0
u8* _rtw_malloc(u32 sz)
{

	u8 	*pbuf=NULL;

#ifdef PLATFORM_LINUX
#ifdef RTK_DMP_PLATFORM
	if(sz > 0x4000)
		pbuf = (u8 *)dvr_malloc(sz);
	else
#endif
		pbuf = kmalloc(sz, /*GFP_KERNEL*/GFP_ATOMIC);

#endif	
	
#ifdef PLATFORM_WINDOWS

	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);

#endif

#ifdef MEMORY_LEAK_DEBUG
#ifdef PLATFORM_LINUX
	if ( pbuf != NULL) {
		atomic_inc(&_malloc_cnt);
		atomic_add(sz, &_malloc_size);
	}
#endif
#endif /* MEMORY_LEAK_DEBUG */

	return pbuf;	
	
}
/*----------------------------------------------------------------------------*/
PVOID kalMemAlloc(IN UINT_32 u4Size, IN ENUM_KAL_MEM_ALLOCATION_TYPE eMemType)
{
	PVOID pvAddr;

	if (NdisAllocateMemoryWithTag(&pvAddr, u4Size, NIC_MEM_TAG) == NDIS_STATUS_SUCCESS) {
		return pvAddr;
	}

	return NULL;
}				/* kalMemAlloc */
Ejemplo n.º 8
0
BOOLEAN
FilterPacket_ProtocolReceiveHandler (
	PNDIS_PACKET pPacket
	)
/*++

Routine Description:

	Filters network packets for NDISProtocolReceiveHandler.


Arguments:

	pPacket - Pointer to the packet buffer descriptor.


Return Value:

	TRUE: This packet should be blocked.

	FALSE: This packet should pass through.


Author:

	xiaonie

	2012/07/12


--*/
{
	ULONG ulTotalPacketLength;
	PUCHAR pBuffer = NULL;
	BOOLEAN bRet = FALSE;
	NDIS_STATUS status;

	NdisQueryPacket(pPacket, NULL, NULL, NULL, &ulTotalPacketLength);
	if (ulTotalPacketLength == 0)
		return FALSE;

	status = NdisAllocateMemoryWithTag(&pBuffer, ulTotalPacketLength, '!nmN');
	if (status != NDIS_STATUS_SUCCESS/* || pBuffer == NULL*/)
		return FALSE;

	ReadPacket(pPacket, pBuffer, ulTotalPacketLength);

	// filter it!
	bRet = RabbitHole(pBuffer, ulTotalPacketLength);

	NdisFreeMemory(pBuffer, ulTotalPacketLength, 0);

	return bRet;
}
Ejemplo n.º 9
0
inline u8* _rtw_vmalloc(u32 sz)
{
	u8 	*pbuf;
#ifdef PLATFORM_LINUX	
	pbuf = vmalloc(sz);	
#endif	
	
#ifdef PLATFORM_WINDOWS
	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);	
#endif

	return pbuf;	
}
Ejemplo n.º 10
0
u8* _rtw_malloc(u32 sz)
{
	u8 	*pbuf;
#ifdef PLATFORM_LINUX	
	pbuf = 	kmalloc(sz, /*GFP_KERNEL*/GFP_ATOMIC);	
#endif	
	
#ifdef PLATFORM_WINDOWS
	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);	
#endif

	return pbuf;	
	
}
Ejemplo n.º 11
0
// 向适配器过滤列表中添加一个过滤规则
NTSTATUS AddFilterToAdapter(PADAPT_FILTER_RSVD pFilterContext, PPassthruFilter pFilter)
{
	PPassthruFilterList pNew;
	// 为新的过滤规则申请内存空间
	if(NdisAllocateMemoryWithTag(&pNew, sizeof(PassthruFilterList), TAG) != NDIS_STATUS_SUCCESS)
		return STATUS_INSUFFICIENT_RESOURCES;

	// 填充这块内存
	NdisMoveMemory(&pNew->filter, pFilter, sizeof(PassthruFilter));
	
	// 连接到过滤列表中
	pNew->pNext = pFilterContext->pFilterList;
	pFilterContext->pFilterList = pNew;
	
	return STATUS_SUCCESS;
}
Ejemplo n.º 12
0
inline u8* _rtw_zvmalloc(u32 sz)
{
	u8 	*pbuf;
#ifdef PLATFORM_LINUX
	pbuf = _rtw_vmalloc(sz);
	if (pbuf != NULL)
		memset(pbuf, 0, sz);
#endif	
	
#ifdef PLATFORM_WINDOWS
	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
	if (pbuf != NULL)
		NdisFillMemory(pbuf, sz, 0);
#endif

	return pbuf;	
}
Ejemplo n.º 13
0
// Memory allocation
void *NeoMalloc(UINT size)
{
	NDIS_STATUS r;
	void *p;
	if (size == 0)
	{
		size = 1;
	}

	// Allocate the non-paged memory
	r = NdisAllocateMemoryWithTag(&p, size, 'SETH');

	if (NG(r))
	{
		return NULL;
	}
	return p;
}
Ejemplo n.º 14
0
u8* _rtw_zmalloc(u32 sz)
{
	u8 	*pbuf;
#ifdef PLATFORM_LINUX
	// kzalloc(sz, GFP_KERNEL);
	pbuf = 	kmalloc(sz, /*GFP_KERNEL*/GFP_ATOMIC);
	if (pbuf != NULL)
		memset(pbuf, 0, sz);
#endif	
	
#ifdef PLATFORM_WINDOWS
	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
	if (pbuf != NULL)
		NdisFillMemory(pbuf, sz, 0);
#endif

	return pbuf;	
	
}
Ejemplo n.º 15
0
static __inline shared_buffer_t *
get_pb_from_freelist(struct xennet_info *xi)
{
  NDIS_STATUS status;
  shared_buffer_t *pb;
  PVOID ptr_ref;

  if (stack_pop(xi->rx_pb_stack, &ptr_ref))
  {
    pb = ptr_ref;
    pb->ref_count = 1;
    InterlockedDecrement(&xi->rx_pb_free);
    return pb;
  }

  /* don't allocate a new one if we are shutting down */
  if (xi->shutting_down)
    return NULL;
    
  status = NdisAllocateMemoryWithTag(&pb, sizeof(shared_buffer_t), XENNET_POOL_TAG);
  if (status != STATUS_SUCCESS)
  {
    return NULL;
  }
  status = NdisAllocateMemoryWithTag(&pb->virtual, PAGE_SIZE, XENNET_POOL_TAG);
  if (status != STATUS_SUCCESS)
  {
    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    return NULL;
  }
  pb->gref = (grant_ref_t)xi->vectors.GntTbl_GrantAccess(xi->vectors.context,
            (ULONG)(MmGetPhysicalAddress(pb->virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XNRX');
  if (pb->gref == INVALID_GRANT_REF)
  {
    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
    return NULL;
  }
u8* _malloc(u32 sz)
{

	u8 	*pbuf;

#ifdef PLATFORM_LINUX
#ifdef RTK_DMP_PLATFORM
	if(sz > 0x4000)
		pbuf = dvr_malloc(sz);
	else
#endif
	pbuf = 	kmalloc(sz, /*GFP_KERNEL*/GFP_ATOMIC);

#endif	
	
#ifdef PLATFORM_WINDOWS

	NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);

#endif

	return pbuf;	
	
}
Ejemplo n.º 17
0
VOID
PtBindAdapter(
	OUT PNDIS_STATUS			Status,
	IN  NDIS_HANDLE				BindContext,
	IN  PNDIS_STRING			DeviceName,
	IN  PVOID					SystemSpecific1,
	IN  PVOID					SystemSpecific2
	)
/*++

Routine Description:

	Called by NDIS to bind to a miniport below.

Arguments:

	Status			- Return status of bind here.
	BindContext		- Can be passed to NdisCompleteBindAdapter if this call is pended.
	DeviceName 		- Device name to bind to. This is passed to NdisOpenAdapter.
	SystemSpecific1	- Can be passed to NdisOpenProtocolConfiguration to read per-binding information
	SystemSpecific2	- Unused

Return Value:

	NDIS_STATUS_PENDING	if this call is pended. In this case call NdisCompleteBindAdapter
	to complete.
	Anything else		Completes this call synchronously

--*/
{
	NDIS_HANDLE						ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER	Param;
	NDIS_STRING						DeviceStr = NDIS_STRING_CONST("UpperBindings");
	PADAPT							pAdapt = NULL;
	NDIS_STATUS						Sts;
	UINT							MediumIndex;
	ULONG							TotalSize;

	PNDIS_CONFIGURATION_PARAMETER	BundleParam;
	NDIS_STRING						BundleStr = NDIS_STRING_CONST("BundleId");
	NDIS_STATUS						BundleStatus;
	
	DBGPRINT(("==> Protocol BindAdapter\n"));

	do
	{
		//
		// Access the configuration section for our binding-specific
		// parameters.
		//
		NdisOpenProtocolConfiguration(Status,
		  							 &ConfigHandle,
		  							 SystemSpecific1);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Read the "UpperBindings" reserved key that contains a list
		// of device names representing our miniport instances corresponding
		// to this lower binding. Since this is a 1:1 IM driver, this key
		// contains exactly one name.
		//
		// If we want to implement a N:1 mux driver (N adapter instances
		// over a single lower binding), then UpperBindings will be a
		// MULTI_SZ containing a list of device names - we would loop through
		// this list, calling NdisIMInitializeDeviceInstanceEx once for
		// each name in it.
		//
		NdisReadConfiguration(Status,
							  &Param,
		  					  ConfigHandle,
		  					  &DeviceStr,
		  					  NdisParameterString);
		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Allocate memory for the Adapter structure. This represents both the
		// protocol context as well as the adapter structure when the miniport
		// is initialized.
		//
		// In addition to the base structure, allocate space for the device
		// instance string.
		//
		TotalSize = sizeof(ADAPT) + Param->ParameterData.StringData.MaximumLength;
		NdisAllocateMemoryWithTag(&pAdapt, TotalSize, TAG);

		if (pAdapt == NULL)
		{
			*Status = NDIS_STATUS_RESOURCES;
		  	break;
		}

		//
		// Initialize the adapter structure. We copy in the IM device
		// name as well, because we may need to use it in a call to
		// NdisIMCancelInitializeDeviceInstance. The string returned
		// by NdisReadConfiguration is active (i.e. available) only
		// for the duration of this call to our BindAdapter handler.
		//
		NdisZeroMemory(pAdapt, TotalSize);
		pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength;
		pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length;
		pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(ADAPT));
		NdisMoveMemory(pAdapt->DeviceName.Buffer,
					   Param->ParameterData.StringData.Buffer,
					   Param->ParameterData.StringData.MaximumLength);

		NdisInitializeEvent(&pAdapt->Event);

		//
		// Allocate a packet pool for sends. We need this to pass sends down.
		// We cannot use the same packet descriptor that came down to our send
		// handler (see also NDIS 5.1 packet stacking).
		//
		NdisAllocatePacketPoolEx(Status,
		  						 &pAdapt->SendPacketPoolHandle,
		  						 MIN_PACKET_POOL_SIZE,
		  						 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  						 sizeof(SEND_RSVD));

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Allocate a packet pool for receives. We need this to indicate receives.
		// Same consideration as sends (see also NDIS 5.1 packet stacking).
		//
		NdisAllocatePacketPoolEx(Status,
		  						 &pAdapt->RecvPacketPoolHandle,
		  						 MIN_PACKET_POOL_SIZE,
		  						 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  						 PROTOCOL_RESERVED_SIZE_IN_PACKET);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Now open the adapter below and complete the initialization
		//
		NdisOpenAdapter(Status,
		  				&Sts,
		  				&pAdapt->BindingHandle,
		  				&MediumIndex,
		  				MediumArray,
		  				sizeof(MediumArray)/sizeof(NDIS_MEDIUM),
		  				ProtHandle,
		  				pAdapt,
		  				DeviceName,
		  				0,
		  				NULL);

		if (*Status == NDIS_STATUS_PENDING)
		{
		  	NdisWaitEvent(&pAdapt->Event, 0);
		  	*Status = pAdapt->Status;
		}

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		pAdapt->Medium = MediumArray[MediumIndex];

		//
		// Now ask NDIS to initialize our miniport (upper) edge.
		// Set the flag below to synchronize with a possible call
		// to our protocol Unbind handler that may come in before
		// our miniport initialization happens.
		//
		pAdapt->MiniportInitPending = TRUE;
		NdisInitializeEvent(&pAdapt->MiniportInitEvent);

		*Status = NdisIMInitializeDeviceInstanceEx(DriverHandle,
  										 &pAdapt->DeviceName,
  										 pAdapt);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
			DBGPRINT(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n",
				pAdapt, *Status));
			break;
		}

	} while(FALSE);

	//
	// Close the configuration handle now - see comments above with
	// the call to NdisIMInitializeDeviceInstanceEx.
	//
	if (ConfigHandle != NULL)
	{
		NdisCloseConfiguration(ConfigHandle);
	}

	if (*Status != NDIS_STATUS_SUCCESS)
	{
		if (pAdapt != NULL)
		{
			if (pAdapt->BindingHandle != NULL)
			{
				NDIS_STATUS	LocalStatus;

				//
				// Close the binding we opened above.
				//
				NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
				pAdapt->BindingHandle = NULL;

				if (LocalStatus == NDIS_STATUS_PENDING)
				{
 					NdisWaitEvent(&pAdapt->Event, 0);
 					LocalStatus = pAdapt->Status;
				}
			}

			if (pAdapt->SendPacketPoolHandle != NULL)
			{
				 NdisFreePacketPool(pAdapt->SendPacketPoolHandle);
			}

			if (pAdapt->RecvPacketPoolHandle != NULL)
			{
				 NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);
			}

			NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
			pAdapt = NULL;
		}
	}


	DBGPRINT(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *Status));
}
Ejemplo n.º 18
0
NDIS_STATUS NICAllocAdapter(
    PMP_ADAPTER *pAdapter)
{
    PMP_ADAPTER Adapter = NULL;
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    PUCHAR pTCBMem;
    PTCB  pTCB;
    NDIS_STATUS Status;

    LONG index;

    DEBUGP(MP_TRACE, ("--> NICAllocAdapter\n"));

    PAGED_CODE();

    *pAdapter = NULL;

    do
    {
        //
        // Allocate memory for adapter context
        //
        Status = NdisAllocateMemoryWithTag(
            &Adapter, 
            sizeof(MP_ADAPTER), 
            NIC_TAG);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for adapter context\n"));
            break;
        }
        //
        // Zero the memory block
        //
        NdisZeroMemory(Adapter, sizeof(MP_ADAPTER));
        NdisInitializeListHead(&Adapter->List);

        //
        // Initialize Send & Recv listheads and corresponding 
        // spinlocks.
        //
        //NdisInitializeListHead(&Adapter->RecvWaitList);
        //NdisInitializeListHead(&Adapter->SendWaitList);
        //NdisInitializeListHead(&Adapter->SendFreeList);
        NdisAllocateSpinLock(&Adapter->SendLock);                                                  

        //NdisInitializeListHead(&Adapter->RecvFreeList);
        NdisAllocateSpinLock(&Adapter->RecvLock);  


				//allocate a packet pool
				NdisAllocatePacketPool(
            &Status,
            &Adapter->LdnRecvPacketPoolHandle,
            1,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
				
				//allocate a single packet in the pool
				NdisAllocatePacket(
                &Status,
                &Adapter->LdnRecvPacket,
                Adapter->LdnRecvPacketPoolHandle);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
        }
				
				
				//allocate a buffer pool
				NdisAllocateBufferPool(
            &Status,
            &Adapter->LdnRecvBufferPoolHandle,
            1);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for recv buffer failed\n"));
            break;
        }
				
				//allocate a single buffer in the buffer pool
				NdisAllocateBuffer(
                &Status,
                &Adapter->LdnRecvPacketBuffer,
                Adapter->LdnRecvBufferPoolHandle,
                (PVOID)&Adapter->LdnRecvPacketBufferData[0],
                NIC_BUFFER_SIZE);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
        }
				
				//chain the buffer to the packet
				NdisChainBufferAtBack(Adapter->LdnRecvPacket,
						Adapter->LdnRecvPacketBuffer);
				
	      NDIS_SET_PACKET_STATUS(Adapter->LdnRecvPacket, NDIS_STATUS_RESOURCES);
				NDIS_SET_PACKET_HEADER_SIZE(Adapter->LdnRecvPacket, ETH_HEADER_SIZE);
  


        /*//
        // Allocate lookside list for Receive Control blocks.
        //
        NdisInitializeNPagedLookasideList(
                    &Adapter->RecvLookaside,
                    NULL, // No Allocate function
                    NULL, // No Free function
                    0,    // Reserved for system use
                    sizeof(RCB),
                    NIC_TAG, 
                    0); // Reserved for system use
                    
        MP_SET_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE); 
        
        //
        // Allocate packet pool for receive indications
        //
        NdisAllocatePacketPool(
            &Status,
            &Adapter->RecvPacketPoolHandle,
            NIC_MAX_BUSY_RECVS,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
        //
        // Initialize receive packets
        //
        for(index=0; index < NIC_MAX_BUSY_RECVS; index++)
        {
            //
            // Allocate a packet descriptor for receive packets
            // from a preallocated pool.
            //
            NdisAllocatePacket(
                &Status,
                &Packet,
                Adapter->RecvPacketPoolHandle);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
            }
            
            NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

            //
            // Insert it into the list of free receive packets.
            //
            NdisInterlockedInsertTailList(
                &Adapter->RecvFreeList, 
                (PLIST_ENTRY)&Packet->MiniportReserved[0], 
                &Adapter->RecvLock);
        }
        
        //
        // Allocate a huge block of memory for all TCB's
        //
        Status = NdisAllocateMemoryWithTag(
            &pTCBMem, 
            sizeof(TCB) * NIC_MAX_BUSY_SENDS, 
            NIC_TAG);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for TCB's\n"));
            break;
        }
        NdisZeroMemory(pTCBMem, sizeof(TCB) * NIC_MAX_BUSY_SENDS);
        Adapter->TCBMem = pTCBMem;

        //
        // Allocate a buffer pool for send buffers.
        //

        NdisAllocateBufferPool(
            &Status,
            &Adapter->SendBufferPoolHandle,
            NIC_MAX_BUSY_SENDS);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for send buffer failed\n"));
            break;
        }

        //
        // Divide the TCBMem blob into TCBs and create a buffer
        // descriptor for the Data portion of the TCBs.
        //
        for(index=0; index < NIC_MAX_BUSY_SENDS; index++)
        {
            pTCB = (PTCB) pTCBMem;
            //
            // Create a buffer descriptor for the Data portion of the TCBs.
            // Buffer descriptors are nothing but MDLs on NT systems.
            //
            NdisAllocateBuffer(
                &Status,
                &Buffer,
                Adapter->SendBufferPoolHandle,
                (PVOID)&pTCB->Data[0],
                NIC_BUFFER_SIZE);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
            }

            //
            // Initialize the TCB structure.
            // 
            pTCB->Buffer = Buffer;
            pTCB->pData = (PUCHAR) &pTCB->Data[0];       
            pTCB->Adapter = Adapter;

            NdisInterlockedInsertTailList(
                &Adapter->SendFreeList, 
                &pTCB->List, 
                &Adapter->SendLock);

            pTCBMem = pTCBMem + sizeof(TCB);
        }*/

    } while(FALSE);


    *pAdapter = Adapter;

    //
    // In the failure case, the caller of this routine will end up
    // calling NICFreeAdapter to free all the successfully allocated
    // resources.
    //
    DEBUGP(MP_TRACE, ("<-- NICAllocAdapter\n"));

    return(Status);

}
Ejemplo n.º 19
0
PVOID
ndisprotAuditAllocMem(
	PVOID	pPointer,
	ULONG	Size,
	ULONG	FileNumber,
	ULONG	LineNumber
)
{
	PVOID				pBuffer;
	PNPROTD_ALLOCATION	pAllocInfo;

	if (!ndisprotdInitDone)
	{
		NdisAllocateSpinLock(&(ndisprotdMemoryLock));
		ndisprotdInitDone = TRUE;
	}

	NdisAllocateMemoryWithTag(
		(PVOID *)&pAllocInfo,
		Size+sizeof(NPROTD_ALLOCATION),
		(ULONG)'oiuN'
	);

	if (pAllocInfo == (PNPROTD_ALLOCATION)NULL)
	{
		DEBUGP(DL_VERY_LOUD+50,
			("ndisprotAuditAllocMem: file %d, line %d, Size %d failed!\n",
				FileNumber, LineNumber, Size));
		pBuffer = NULL;
	}
	else
	{
		pBuffer = (PVOID)&(pAllocInfo->UserData);
		NPROT_SET_MEM(pBuffer, 0xaf, Size);
		pAllocInfo->Signature = NPROTD_MEMORY_SIGNATURE;
		pAllocInfo->FileNumber = FileNumber;
		pAllocInfo->LineNumber = LineNumber;
		pAllocInfo->Size = Size;
		pAllocInfo->Location = (ULONG_PTR)pPointer;
		pAllocInfo->Next = (PNPROTD_ALLOCATION)NULL;

		NdisAcquireSpinLock(&(ndisprotdMemoryLock));

		pAllocInfo->Prev = ndisprotdMemoryTail;
		if (ndisprotdMemoryTail == (PNPROTD_ALLOCATION)NULL)
		{
			// empty list
			ndisprotdMemoryHead = ndisprotdMemoryTail = pAllocInfo;
		}
		else
		{
			ndisprotdMemoryTail->Next = pAllocInfo;
		}
		ndisprotdMemoryTail = pAllocInfo;
		
		ndisprotdAllocCount++;
		NdisReleaseSpinLock(&(ndisprotdMemoryLock));
	}

	DEBUGP(DL_VERY_LOUD+100,
	 ("ndisprotAuditAllocMem: file %c%c%c%c, line %d, %d bytes, [0x%p] <- 0x%p\n",
	 			(CHAR)(FileNumber & 0xff),
	 			(CHAR)((FileNumber >> 8) & 0xff),
	 			(CHAR)((FileNumber >> 16) & 0xff),
	 			(CHAR)((FileNumber >> 24) & 0xff),
				LineNumber, Size, pPointer, pBuffer));

	return (pBuffer);

}
Ejemplo n.º 20
0
PNDIS_PACKET
SecLabAllocateReceivePacket(
    PADAPT			                pAdapt,
    IN UINT                         DataLength,
    OUT PUCHAR *                    ppDataBuffer
    )
/*++

Routine Description:

    分配用于拷贝和排队接收包的资源.

Arguments:

    DataLength - 封包的总长度,包括包头和数据
    ppDataBuffer - 返回的缓冲区地址

Return Value:

    如果成功则返回包的指针,否则为空.

--*/
{
    PNDIS_PACKET            pNdisPacket;
    PNDIS_BUFFER            pNdisBuffer;
    PUCHAR                  pDataBuffer;
    NDIS_STATUS             Status;

    pNdisPacket = NULL;
    pNdisBuffer = NULL;
    pDataBuffer = NULL;

    do
    {
		NdisAllocateMemoryWithTag((PVOID *)(&pDataBuffer), DataLength,'lceS');

        if (pDataBuffer == NULL)
        {
            DbgPrint("Can not Allocate resoures for packet");
            break;
        }

        //
        //  将其转化为NDIS_BUFFER.
        //
        NdisAllocateBuffer(
            &Status,
            &pNdisBuffer,
            RecvBufferPool,
            pDataBuffer,
            DataLength);
        
        if (Status != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("failed to allocate Ndis Buffer");
            break;
        }

        NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->RecvPacketPoolHandle);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("failed to alloc NDIS packet");
            break;
        }

        NDIS_SET_PACKET_STATUS(pNdisPacket, 0);
        SECLAB_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket) = NULL;

        NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

        *ppDataBuffer = pDataBuffer;

        break;
    }
    while (FALSE);

    if (pNdisPacket == NULL)
    {
        //
        //  Clean up
        //
        if (pNdisBuffer != NULL)
        {
            NdisFreeBuffer(pNdisBuffer);
        }

        if (pDataBuffer != NULL)
        {
            NdisFreeMemory(pDataBuffer, 0, 0);
        }
    }

    return (pNdisPacket);
}
Ejemplo n.º 21
0
INT
LpxProtocolReceivePacket(
	IN NDIS_HANDLE	ProtocolBindingContext,
	IN PNDIS_PACKET	Packet
){
	PDEVICE_CONTEXT	deviceContext;
	PNDIS_BUFFER	ndisFirstBuffer;
	PVOID			firstBuffer;
	UINT		    firstBufferSize;
	UINT			totalBufferSize;
	USHORT		    protocol;
	PNDIS_PACKET	packet = NULL;
	NDIS_STATUS		status;
	INT				pktReferenceCount = 0;
	UINT		    addiLlcHeaderSize = 0;
	PLPX_HEADER		lpxHeader;
	USHORT			lpxHeaderSize;
	UINT			lpxPayload;
	UINT			rawDataOffset;


	DebugPrint( 4, ("ProtocolReceivePacket: Entered\n") );
	
	deviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	//
	//	Check to see if the device context is initialized.
	//
	ASSERT( deviceContext->NdisBindingHandle );

	if (!FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_START) ||
		FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_STOP)) {

			DebugPrint( 4,("Device is not initialized. Drop packet\n") );

			return 0;
	}

	//
	//	validation
	//
	NdisGetFirstBufferFromPacket(
				Packet,
				&ndisFirstBuffer,
				&firstBuffer,
				&firstBufferSize,
				&totalBufferSize);

	if (firstBufferSize < ETHERNET_HEADER_LENGTH) {

		DebugPrint( 1, ("ProtocolReceivePacket: FirstBufferSize = %x\n", firstBufferSize) );
		return 0;
	}

	protocol = ((PETHERNET_HEADER)firstBuffer)->Type;

	//
	//	Discard 802.2 LLC SNAP field.
	//
	// if Ether Type less than 0x0600 ( 1536 )
	//

	if (NTOHS(protocol) < 0x0600  && 
	    NTOHS(protocol) != 0x0060 && // LOOP: Ethernet Loopback
		NTOHS(protocol) != 0x0200 && // PUP : Xerox PUP packet
		NTOHS(protocol) != 0x0201) { // PUPAP: Xerox PUP address trans packet 

		protocol = *(PUSHORT)((PUCHAR)firstBuffer + ETHERNET_HEADER_LENGTH + LENGTH_8022LLCSNAP - 2);
		if(firstBufferSize >= LENGTH_8022LLCSNAP)
			firstBufferSize -= LENGTH_8022LLCSNAP;
		else {
			DebugPrint( 1, ("ProtocolReceivePacket: Too small first buffer\n") );
			return 0;
		}

		if(totalBufferSize >= LENGTH_8022LLCSNAP)
			totalBufferSize -= LENGTH_8022LLCSNAP;
		else {
			DebugPrint( 1, ("ProtocolReceivePacket: Too small total buffer\n") );
			return 0;
		}
		addiLlcHeaderSize = LENGTH_8022LLCSNAP;
	}

	if (protocol != HTONS(ETH_P_LPX)) {
	
		DebugPrint( 4, ("ProtocolReceivePacket: Type = %x\n", protocol) );
		return 0;
	}
	if(totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + sizeof(LPX_HEADER)) {
		DebugPrint( 1, ("ProtocolReceivePacket: too small packet(1).\n"));
		return 0;
	}

	//
	// Extract LPX header information
	//
	//

	lpxHeader = (PLPX_HEADER)((PBYTE)firstBuffer + ETHERNET_HEADER_LENGTH + addiLlcHeaderSize);
	lpxHeaderSize = sizeof(LPX_HEADER);
	lpxPayload = NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize;

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {
		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

	if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	if(totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize + lpxPayload) {
		DebugPrint( 1, ("ProtocolReceivePacket: too small packet(2).\n"));
		return 0;
	}

	//
	// DROP PACKET for DEBUGGING!!!!
	//

#if 1 //DBG // Enabled for testing

	if (PacketRxDropRate) {

		PacketRxCountForDrop++;
				
		if ((PacketRxCountForDrop % 1000) <= PacketRxDropRate) {
			PLPX_HEADER        lpxHeader = (PLPX_HEADER)((PUCHAR)firstBuffer + addiLlcHeaderSize);
#if 0
			if ((PacketRxCountForDrop % (PacketRxDropRate*20)) == 0) 
				DebugPrint( 1, ("[Drop(%x,%x,%x))]\n", 
								 NTOHS(lpxHeader->Lsctl), NTOHS(lpxHeader->Sequence), NTOHS(lpxHeader->AckSequence)) );
#endif			
			DebugPrint( 1, ("D\n") );

			return 0;
		}
	}

#endif

	ASSERT( addiLlcHeaderSize == 0 );

	DebugPrint( 4, ("ProtocolReceivePacket: TotalBuffSz = %d, FirstBuffSz = %d, LPX_HEADER size = %d\n",
					 totalBufferSize, firstBufferSize, sizeof(LPX_HEADER)) );
	//
	//  If the miniport is out of resources, we can't queue
	//  this packet - make a copy if this is so.
	//
	if (NDIS_GET_PACKET_STATUS(Packet) == NDIS_STATUS_RESOURCES) {

		UINT			bytesCopied;

		DebugPrint( 1, ("ProtocolReceivePacket: Miniport reported low packet resources.\n"));

		status = RcvPacketAlloc( deviceContext,
								 lpxPayload,
								 &packet );

		if (status == STATUS_SUCCESS) {
			ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
			//
			// Copy lpx payload. payload contains only data.
			//
			NdisCopyFromPacketToPacket(
						packet, 0,
						lpxPayload,
						Packet, ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize,
						&bytesCopied);
			ASSERT(lpxPayload == bytesCopied);
		}

		rawDataOffset = 0;
		pktReferenceCount = 0;
	} else {
		PLPX_RESERVED	externalReserved;
		//
		// No need to allocate new NDIS packet and copy data to the new NDIS packet.
		// But, NDIS miniport allocates only 4 * sizeof(PVOID) for protocol reserved context.
		// We should allocate our own.
		//
		packet = Packet;

		status = NdisAllocateMemoryWithTag(&externalReserved, sizeof(LPX_RESERVED), LPX_MEM_TAG_EXTERNAL_RESERVED);
		if(status == NDIS_STATUS_SUCCESS) {

			RtlZeroMemory(externalReserved, sizeof(LPX_RESERVED));

			// By setting the external reserved field, RESERVED() uses external reserved context automatically.
			((PLPX_RESERVED)packet->ProtocolReserved)->ExternalReserved = externalReserved;

			// Initialize LPX reserved context instead of RcvPacketAlloc().
			RESERVED(packet)->Cloned = 0;
			RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE;
			RESERVED(packet)->RecvFlags |= LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT;

			// set data offset
			// Because NDIS miniport allocated the packet, the NDIS packet contains whole raw packet data.
			rawDataOffset = ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize;
			lpxPayload += rawDataOffset;

			// return one reference count indicating LPX will call NdisReturnPackets() once.
			pktReferenceCount = 1;

		}
	}

	if (status != NDIS_STATUS_SUCCESS) {

		return 0;
	}

	//
	// Init LPX reserved context
	//

	LpxCopyEthLpxHeadersToLpxReserved(packet, firstBuffer, protocol, lpxHeader, lpxHeaderSize);
	RESERVED(Packet)->Packet = packet;
	RESERVED(Packet)->RecvTime = CurrentTime();
	RESERVED(Packet)->PacketRawDataLength = lpxPayload;
	RESERVED(Packet)->PacketRawDataOffset = rawDataOffset;

	//
	// Queue to the device context.
	//

	ExInterlockedInsertTailList( &deviceContext->PacketInProgressList,
								 &(RESERVED(Packet)->ListEntry),
								 &deviceContext->PacketInProgressQSpinLock );


	return pktReferenceCount;
}
Ejemplo n.º 22
0
INT
LpxProtocolReceivePacket (
	IN NDIS_HANDLE	ProtocolBindingContext,
	IN PNDIS_PACKET	Packet
	)
{
	PDEVICE_CONTEXT	deviceContext;

	PLPX_RESERVED	reserved = NULL;	

	PNDIS_BUFFER	ndisFirstBuffer;
	PVOID			firstBuffer;
	UINT		    firstBufferSize;
	UINT			totalBufferSize;
	PNDIS_PACKET	packet = NULL;
	NDIS_STATUS		status;
	INT				pktReferenceCount = 0;
	UINT		    addiLlcHeaderSize = 0;
	PLPX_HEADER		lpxHeader;
	USHORT			lpxHeaderSize;
	UINT			lpxPayload;
	UINT			rawDataOffset;
	ETHERNET_HEADER	ethernetHeader;

	DebugPrint( 4, ("ProtocolReceivePacket: Entered\n") );
	
	deviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	//	Check to see if the device context is initialized.

	if (!FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_START) || FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_STOP)) {

		DebugPrint( 1, ("Device is not initialized. Drop packet\n") );

		return NDIS_STATUS_NOT_RECOGNIZED;
	}

	NDAS_ASSERT( deviceContext->NdisBindingHandle );

	//	validation

#ifndef NTDDI_VERSION

	NdisGetFirstBufferFromPacket( Packet,
								  &ndisFirstBuffer,
								  &firstBuffer,
								  &firstBufferSize,
								  &totalBufferSize );
#else

	firstBufferSize = 0;
	
	NdisGetFirstBufferFromPacketSafe( Packet,
									  &ndisFirstBuffer,
									  &firstBuffer,
									  &firstBufferSize,
									  &totalBufferSize,
									  HighPagePriority );
#endif

	if (firstBufferSize < ETHERNET_HEADER_LENGTH) {

		NDAS_ASSERT(FALSE);

		DebugPrint( 2, ("ProtocolReceivePacket: FirstBufferSize = %x\n", firstBufferSize) );
		return 0;
	}

	RtlCopyMemory( &ethernetHeader, firstBuffer, ETHERNET_HEADER_LENGTH );

	if (ethernetHeader.DestinationAddress[5] != 0xFF) {

		DebugPrint( 3, ("LpxProtocolReceivePacket: Type = %X\n", ethernetHeader.Type) );	
	}

	//	Discard 802.2 LLC SNAP field.
	//
	// if Ether Type less than 0x0600 ( 1536 )

	if (NTOHS(ethernetHeader.Type)  < 0x0600 && 
		NTOHS(ethernetHeader.Type) != 0x0060 && // LOOP:  Ethernet Loopback
		NTOHS(ethernetHeader.Type) != 0x0200 && // PUP :  Xerox PUP packet
		NTOHS(ethernetHeader.Type) != 0x0201) { // PUPAP: Xerox PUP address trans packet 

		RtlCopyMemory( &ethernetHeader, 
					   (PUCHAR)firstBuffer + ETHERNET_HEADER_LENGTH + LENGTH_8022LLCSNAP - 2, 
					   ETHERNET_HEADER_LENGTH );

		if (firstBufferSize >= LENGTH_8022LLCSNAP) {

			firstBufferSize -= LENGTH_8022LLCSNAP;
		
		} else {

			DebugPrint( 2, ("ProtocolReceivePacket: Too small first buffer\n") );
			return 0;
		}

		if (totalBufferSize >= LENGTH_8022LLCSNAP) {

			totalBufferSize -= LENGTH_8022LLCSNAP;
		
		} else {

			DebugPrint( 2, ("ProtocolReceivePacket: Too small total buffer\n") );
			return 0;
		}

		addiLlcHeaderSize = LENGTH_8022LLCSNAP;

		NDAS_ASSERT( ethernetHeader.Type != HTONS(ETH_P_LPX) );
	}

	if (ethernetHeader.Type != HTONS(ETH_P_LPX)) {
	
		DebugPrint( 4, ("ProtocolReceivePacket: Type = %x\n", ethernetHeader.Type) );
		return 0;
	}

	if (totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + sizeof(LPX_HEADER)) {

		DebugPrint( 2, ("ProtocolReceivePacket: too small packet(1).\n"));
		return 0;
	}

	// DROP PACKET for DEBUGGING!!!!

	if (PacketRxDropRate) {

		PacketRxCountForDrop++;
				
		if ((PacketRxCountForDrop % 1000) <= PacketRxDropRate) {

			PLPX_HEADER        lpxHeader = (PLPX_HEADER)((PUCHAR)firstBuffer + addiLlcHeaderSize);

			if ((PacketRxCountForDrop % (PacketRxDropRate*20)) == 0) {

				DebugPrint( 6, ("[Drop(%x,%x,%x))]\n", 
								 NTOHS(lpxHeader->Lsctl), NTOHS(lpxHeader->Sequence), NTOHS(lpxHeader->AckSequence)) );
			}

			DebugPrint( 2, ("D\n") );

			return 0;
		}
	}

	if (!(RtlEqualMemory(ethernetHeader.DestinationAddress, deviceContext->LocalAddress.Address, ETHERNET_ADDRESS_LENGTH) ||
		  RtlEqualMemory(ethernetHeader.DestinationAddress, LpxBroadcastAddress, ETHERNET_ADDRESS_LENGTH))) {

		DebugPrint( 4, ("LpxProtocolReceivePacket, %02x%02x%02x%02x%02x%02x\n",
						 deviceContext->LocalAddress.Address[0], deviceContext->LocalAddress.Address[1], 
						 deviceContext->LocalAddress.Address[2], deviceContext->LocalAddress.Address[3], 
						 deviceContext->LocalAddress.Address[4], deviceContext->LocalAddress.Address[5]) );

		DebugPrint( 4, ("LpxProtocolReceivePacket, %02x%02x%02x%02x%02x%02x\n",
						 ethernetHeader.DestinationAddress[0], ethernetHeader.DestinationAddress[1], 
						 ethernetHeader.DestinationAddress[2], ethernetHeader.DestinationAddress[3], 
						 ethernetHeader.DestinationAddress[4], ethernetHeader.DestinationAddress[5]) );

		return 0;
	}

	// Extract LPX header information

	lpxHeader = (PLPX_HEADER)((PBYTE)firstBuffer + ETHERNET_HEADER_LENGTH + addiLlcHeaderSize);
	lpxHeaderSize = sizeof(LPX_HEADER);
	lpxPayload = NTOHS((UINT16)(lpxHeader->PacketSize & ~LPX_TYPE_MASK)) - lpxHeaderSize;

	if (lpxHeader->DestinationPort == NTOHS(LPXRP_HIX_PORT)) {

		DebugPrint( 1, ("[LPX] LpxProtocolReceivePacket: DataGram packet arrived.\n") );
	}

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {

		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

	if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {

		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	if (totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize + lpxPayload) {

		DebugPrint( 2, ("ProtocolReceivePacket: too small packet(2).\n") );

		return 0;
	}

	NDAS_ASSERT( addiLlcHeaderSize == 0 );

	DebugPrint( 4, ("ProtocolReceivePacket: TotalBuffSz = %d, FirstBuffSz = %d, LPX_HEADER size = %d\n",
					 totalBufferSize, firstBufferSize, sizeof(LPX_HEADER)) );

	//  If the miniport is out of resources, we can't queue
	//  this packet - make a copy if this is so.

	NDAS_ASSERT( sizeof(ZeroProtocolReserved) == PROTOCOL_RESERVED_OFFSET );

	if (NDIS_GET_PACKET_STATUS(Packet) == NDIS_STATUS_RESOURCES ||
		!RtlEqualMemory(&Packet->ProtocolReserved[PROTOCOL_RESERVED_OFFSET], ZeroProtocolReserved, sizeof(ZeroProtocolReserved))) {

		UINT bytesCopied;
		INT  i;

		for (i=0; i<16; i++) {

			DebugPrint( 1, ("Packet->ProtocolReserved[%d] = %d\n", i, Packet->ProtocolReserved[i]) );
		}

		NDAS_ASSERT(FALSE);

		DebugPrint( 2, ("ProtocolReceivePacket: Miniport reported low packet resources.\n") );

		status = RcvPacketAlloc( deviceContext, lpxPayload, &packet );

		if (status == STATUS_SUCCESS) {

			NDAS_ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

			// Copy lpx payload. payload contains only data.

			NdisCopyFromPacketToPacket( packet, 
										0,
										lpxPayload,
										Packet, 
										ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize,
										&bytesCopied
										);

			NDAS_ASSERT( lpxPayload == bytesCopied );
		}

		rawDataOffset = 0;
		pktReferenceCount = 0;
	
	} else {
	
		PLPX_RESERVED externalReserved;

		// No need to allocate new NDIS packet and copy data to the new NDIS packet.
		// But, NDIS miniport allocates only 4 * sizeof(PVOID) for protocol reserved context.
		// We should allocate our own.

		packet = Packet;

		status = NdisAllocateMemoryWithTag( &externalReserved, sizeof(LPX_RESERVED), LPX_MEM_TAG_EXTERNAL_RESERVED );

		if (status == NDIS_STATUS_SUCCESS) {

			RtlZeroMemory( externalReserved, sizeof(LPX_RESERVED) );

			// By setting the external reserved field, LpxGetReserved() uses external reserved context automatically.

			((PLPX_RESERVED)(&packet->ProtocolReserved[PROTOCOL_RESERVED_OFFSET]))->ExternalReserved = externalReserved;

			reserved = LpxGetReserved(packet);

			// Initialize LPX reserved context instead of RcvPacketAlloc().

			reserved->Cloned = 0;
			reserved->Type = LPX_PACKET_TYPE_RECEIVE;
			reserved->RecvFlags |= LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT;

			// set data offset
			// Because NDIS miniport allocated the packet, the NDIS packet contains whole raw packet data.

			rawDataOffset = ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize;
			lpxPayload += rawDataOffset;

			// return one reference count indicating LPX will call NdisReturnPackets() once.

			pktReferenceCount = 1;
		}
	}

	if (status != NDIS_STATUS_SUCCESS) {

		DebugPrint( 2, ("ProtocolReceivePacket: status != NDIS_STATUS_SUCCESS\n") );
		return 0;
	}

	// Init LPX reserved context

	LpxCopyEthLpxHeadersToLpxReserved( packet, firstBuffer, ethernetHeader.Type, lpxHeader, lpxHeaderSize );

	reserved = LpxGetReserved(packet);

	reserved->Packet = packet;
	reserved->RecvTime = NdasCurrentTime();
	reserved->PacketRawDataLength = lpxPayload;
	reserved->PacketRawDataOffset = rawDataOffset;

	// Queue to the device context.

	ExInterlockedInsertTailList( &deviceContext->PacketInProgressList,
								 &(reserved->ListEntry),
								 &deviceContext->PacketInProgressQSpinLock );

	return pktReferenceCount;
}
Ejemplo n.º 23
0
// Called at <= DISPATCH_LEVEL
static NDIS_STATUS
XenNet_Init(
  OUT PNDIS_STATUS OpenErrorStatus,
  OUT PUINT SelectedMediumIndex,
  IN PNDIS_MEDIUM MediumArray,
  IN UINT MediumArraySize,
  IN NDIS_HANDLE MiniportAdapterHandle,
  IN NDIS_HANDLE WrapperConfigurationContext
  )
{
  NDIS_STATUS status;
  BOOLEAN medium_found = FALSE;
  struct xennet_info *xi = NULL;
  UINT nrl_length;
  PNDIS_RESOURCE_LIST nrl;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  KIRQL irq_level = 0;
  ULONG irq_vector = 0;
  ULONG irq_mode = 0;
  NDIS_HANDLE config_handle;
  NDIS_STRING config_param_name;
  PNDIS_CONFIGURATION_PARAMETER config_param;
  ULONG i;
  PUCHAR ptr;
  UCHAR type;
  PCHAR setting, value;
  ULONG length;
  //CHAR buf[128];
  PVOID network_address;
  UINT network_address_length;
  BOOLEAN qemu_hide_filter = FALSE;
  ULONG qemu_hide_flags_value = 0;
  
  UNREFERENCED_PARAMETER(OpenErrorStatus);

  FUNCTION_ENTER();

  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));

  /* deal with medium stuff */
  for (i = 0; i < MediumArraySize; i++)
  {
    if (MediumArray[i] == NdisMedium802_3)
    {
      medium_found = TRUE;
      break;
    }
  }
  if (!medium_found)
  {
    KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n"));
    return NDIS_STATUS_UNSUPPORTED_MEDIA;
  }
  *SelectedMediumIndex = i;

  /* Alloc memory for adapter private info */
  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }
  RtlZeroMemory(xi, sizeof(*xi));
  xi->adapter_handle = MiniportAdapterHandle;
  xi->rx_target     = RX_DFL_MIN_TARGET;
  xi->rx_min_target = RX_DFL_MIN_TARGET;
  xi->rx_max_target = RX_MAX_TARGET;
  xi->inactive      = TRUE;
  NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */
#ifdef NDIS51_MINIPORT
    |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
#endif
    |NDIS_ATTRIBUTE_DESERIALIZE
    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
    NdisInterfaceInternal); /* PnpBus option doesn't exist... */
  xi->multicast_list_size = 0;
  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;

  nrl_length = 0;
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    NULL, (PUINT)&nrl_length);
  KdPrint((__DRIVER_NAME "     nrl_length = %d\n", nrl_length));
  status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get allocate memory for Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    nrl, (PUINT)&nrl_length);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  xi->event_channel = 0;
  xi->config_csum = 1;
  xi->config_csum_rx_check = 1;
  xi->config_sg = 1;
  xi->config_gso = 61440;
  xi->config_page = NULL;
  xi->config_rx_interrupt_moderation = 0;
  
  for (i = 0; i < nrl->Count; i++)
  {
    prd = &nrl->PartialDescriptors[i];

    switch(prd->Type)
    {
    case CmResourceTypeInterrupt:
      irq_vector = prd->u.Interrupt.Vector;
      irq_level = (KIRQL)prd->u.Interrupt.Level;
      irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive;
      KdPrint((__DRIVER_NAME "     irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level,
        (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive"));
      break;
    case CmResourceTypeMemory:
      if (xi->config_page)
      {
        KdPrint(("More than one memory range\n"));
        return NDIS_STATUS_RESOURCES;
      }
      else
      {
        status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
        if (!NT_SUCCESS(status))
        {
          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
          NdisFreeMemory(nrl, nrl_length, 0);
          return NDIS_STATUS_RESOURCES;
        }
      }
      break;
    }
  }
  NdisFreeMemory(nrl, nrl_length, 0);
  if (!xi->config_page)
  {
    KdPrint(("No config page given\n"));
    return NDIS_STATUS_RESOURCES;
  }

  KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
  KeInitializeSpinLock(&xi->resume_lock);

  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);

  NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
    &xi->lower_do, NULL, NULL);
  xi->packet_filter = 0;

  status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
    NAME_SIZE, xi->dev_desc, &length);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
    status = NDIS_STATUS_FAILURE;
    goto err;
  }

  ptr = xi->config_page;
  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
  {
    switch(type)
    {
    case XEN_INIT_TYPE_VECTORS:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
      {
        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
        FUNCTION_EXIT();
        return NDIS_STATUS_FAILURE;
      }
      else
        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
      break;
    case XEN_INIT_TYPE_STATE_PTR:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
      xi->device_state = (PXENPCI_DEVICE_STATE)value;
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
      qemu_hide_flags_value = PtrToUlong(value);
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
      qemu_hide_filter = TRUE;
      break;
    default:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
      break;
    }
  }

  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter)
    xi->inactive = FALSE;

  xi->power_state = NdisDeviceStateD0;
  xi->power_workitem = IoAllocateWorkItem(xi->fdo);

  // now build config page
  
  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not open config in registry (%08x)\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }

  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
    xi->config_sg = 1;
  }
  else
  {
    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
    xi->config_sg = config_param->ParameterData.IntegerData;
  }
  
  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
    xi->config_gso = 0;
  }
  else
  {
    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_gso = config_param->ParameterData.IntegerData;
    if (xi->config_gso > 61440)
    {
      xi->config_gso = 61440;
      KdPrint(("(clipped to %d)\n", xi->config_gso));
    }
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
    xi->config_csum = 1;
  }
  else
  {
    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status));
    xi->config_csum_rx_check = 1;
  }
  else
  {
    KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status));
    xi->config_csum_rx_dont_fix = 0;
  }
  else
  {
    KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData;
  }
  
  
  
  NdisInitUnicodeString(&config_param_name, L"MTU");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read MTU value (%08x)\n", status));
    xi->config_mtu = 1500;
  }
  else
  {
    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
    xi->config_mtu = config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status));
    xi->config_rx_interrupt_moderation = 1500;
  }
  else
  {
    KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData));
    xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData;
  }
  

  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02))
  {
    KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status));
    memset(xi->curr_mac_addr, 0, ETH_ALEN);
  }
  else
  {
    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
    KdPrint(("     Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]));
  }

  xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE);
  
  NdisCloseConfiguration(config_handle);

  status = XenNet_D0Entry(xi);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Failed to go to D0 (%08x)\n", status));
    goto err;
  }
  return NDIS_STATUS_SUCCESS;
  
err:
  NdisFreeMemory(xi, 0, 0);
  *OpenErrorStatus = status;
  FUNCTION_EXIT_STATUS(status);
  return status;
}
Ejemplo n.º 24
0
BOOLEAN
GetUdpPortMapOut(
    IN   USHORT   original,
    IN   BOOLEAN  trans,
    OUT  PUSHORT  mapped
    )
/*++

Routine Description:

    Get the mapped id for the outflow UDP packet.
    
Arguments:

    original - Original UDP source port in outflow packet.
    trans - TRUE for 4to6 mapping; FLASE for 6to6 mapping.
    mapped - Pointer to caller-supplied memory that holds the returned mapping port.

Return Value:

    TRUE if find mapping is successful, mapped port is returned in 'mapped' pointer;
    FALSE if failed to find or create a mapping info, 'mapped' is set to 0 in this case.

--*/
{
    USHORT    ret = 0;
    SHORT     remaining;
    LONG      MaxPorts = 65536 / LocalPrefixInfo.Ratio;  // Total port number is determined by ratio
    
    USHORT    rover_j;
    USHORT    rover_k;
    USHORT    low;  // lower bound of j
    USHORT    high; // higher bound of j
    
    PUDP_MAP_CONTEXT  Map = NULL;
    NDIS_STATUS       Status;

    NdisAcquireSpinLock(&PortListLock);
    
    // Do NOT call RefreshUdpListEntrySafe() since we have already hold the spin lock.
    RefreshUdpListEntry();
    
    if (UdpPortMapOutTable[original].Map != NULL)
    {
        Map = UdpPortMapOutTable[original].Map;
        if (Map->OriginalPort == original && Map->Translated == trans)  // Found existing mapping info
        {
            ret = Map->MappedPort;
            NdisGetCurrentSystemTime(&(Map->MapSetTime));  // refresh timer
            DBGPRINT(("==> GetUdpPortMapOut: Find Map %d -> %d\n", Map->OriginalPort, Map->MappedPort));
        }
    }
    
    if (ret == 0) // no existing map, generate new map
    {
        if (PortListLength >= MaxPorts)
        {
            NdisReleaseSpinLock(&PortListLock);
            DBGPRINT(("==> GetUdpPortMapOut: list full. Map id is used up.\n"));
            *mapped = 0;
            return FALSE;
        }
        
        if (LocalPrefixInfo.XlateMode == 1)   // 1:N id mapping
        {
            low = (USHORT)(1024 / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent) + 1;
            high = (USHORT)(65536 / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent) - 1;
            remaining = (high - low) + 1;
    
            if (PortListLength != 0)
            {
                rover_j = (USHORT)(LastAllocatedUdpPort / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent);
                rover_k = (USHORT)(LastAllocatedUdpPort % LocalPrefixInfo.Adjacent) + 1;
                if (rover_k == LocalPrefixInfo.Adjacent)
                {
                    rover_j++;
                    rover_k = 0;
                }
            }
            else
            {
                // No port allocated before
                rover_j = low;
                rover_k = 0;
            }
            
            do
            {
                ret = (rover_j * LocalPrefixInfo.Ratio + LocalPrefixInfo.Offset) * LocalPrefixInfo.Adjacent + rover_k;
                if (UdpPortMapInTable[ret].Map == NULL)
                {
                    // find idle ivi port
                    break;
                }
                rover_k++;
                if (rover_k == LocalPrefixInfo.Adjacent)
                {
                    rover_j++;
                    remaining--;
                    rover_k = 0;
                    if (rover_j > high)
                    {
                        rover_j = low;
                    }
                }
            }
            while (remaining > 0);
            
            if (remaining <= 0)
            {
                NdisReleaseSpinLock(&PortListLock);
                *mapped = 0;
                return FALSE;
            }
        }
        else
        {
            // 1:1 id mapping
            ret = original;
        }
        
        // Allocate map info memory
        Status = NdisAllocateMemoryWithTag((PVOID)&Map, sizeof(UDP_MAP_CONTEXT), TAG);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            NdisReleaseSpinLock(&PortListLock);
            // No memory for map info. Fail this map.
            DBGPRINT(("==> GetUdpPortMapOut: NdisAllocateMemoryWithTag failed for port %d\n", original));
            *mapped = 0;
            return FALSE;
        }
        NdisZeroMemory(Map, sizeof(UDP_MAP_CONTEXT));
        
        // Routine to add new map-info
        Map->OriginalPort = original;
        Map->MappedPort = ret;
        Map->Translated = trans;
        NdisGetCurrentSystemTime(&(Map->MapSetTime));  // set timer for newly added mapping
        // Set hash table pointer
        UdpPortMapOutTable[Map->OriginalPort].Map = Map;
        UdpPortMapInTable[Map->MappedPort].Map = Map;
        // Linked list need not be sorted. Just insert new entry at tail.
        InsertTailList(&PortListHead, &(Map->ListEntry));
        PortListLength++;
        LastAllocatedUdpPort = ret;
        DBGPRINT(("==> GetUdpPortMapOut: New map %d -> %d added, xlate=%d.\n", 
                  Map->OriginalPort, Map->MappedPort, Map->Translated));
    }
    
    NdisReleaseSpinLock(&PortListLock);
    
    *mapped = ret;
    
    return TRUE;
}
Ejemplo n.º 25
0
NDIS_STATUS
FakeNDISReceiveHandler (
	NDIS_HANDLE ProtocolBindingContext,
	NDIS_HANDLE MacReceiveContext,
	PUCHAR pHeaderBuffer,
	UINT HeaderBufferSize,
	PUCHAR pLookaheadBuffer,
	UINT LookaheadBufferSize,
	UINT PacketSize
	)
/*++

Routine Description:

	Filters network packets received.


Arguments:

	ProtocolBindingContext - ...

	MacReceiveContext - ...

	pHeaderBuffer - packet header

	HeaderBufferSize - packet header length

	pLookaheadBuffer - look ahead buffer after packet header

	LookaheadBufferSize - length of look ahead buffer

	PacketSize - length of packet, exclude packet header


Return Value:

	...


Author:

	xiaonie

	2012/07/12


--*/
{
	PLIST_ENTRY pEntry;
	PNDIS_HOOK_LIST_NODE pNode;
	KIRQL irql;
	ULONG ulFunAddr = 0;
	// PVOID MacHandle = NULL;
	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
	PNDIS_PACKET pNdisPacket = NULL;
	PNDIS_BUFFER pNdisBuffer = NULL;
	PUCHAR pBuffer = NULL;
	ULONG ulLen;
	KEVENT evt;

	KeAcquireSpinLock(&g_lock, &irql);
	for (pEntry = g_linkListHead.Flink; pEntry != &g_linkListHead; pEntry = pEntry->Flink) {
		pNode = CONTAINING_RECORD(pEntry, NDIS_HOOK_LIST_NODE, ListEntry);
		if (pNode->ProtocolBindingContext == ProtocolBindingContext) {
			ulFunAddr = pNode->ulRealReceiveHandler;
			// MacHandle = pNode->MacHandle;
			break;
		}
	}
	KeReleaseSpinLock(&g_lock, irql);

	if (ulFunAddr == 0) {
		DbgPrint("\r\n Attention: FunAddr == 0(0: FakeNDISReceiveHandler)\r\n");
		// return NDIS_STATUS_SUCCESS;
		return NDIS_STATUS_NOT_ACCEPTED;
	}


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	if (PacketSize + HeaderBufferSize < PacketSize || PacketSize < LookaheadBufferSize) {	// PacketSize not valid
		DbgPrint("\r\n Attention: PacketSize not valid!(0: FakeNDISReceiveHandler)\r\n");
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	// allocate buffer to hold network packet
	status = NdisAllocateMemoryWithTag(&pBuffer, HeaderBufferSize + PacketSize, '!nmN');
	if (status != NDIS_STATUS_SUCCESS/* || pBuffer == NULL*/)
		return NDIS_STATUS_NOT_ACCEPTED;

	// copy packet header to buffer
	NdisMoveMemory(pBuffer, pHeaderBuffer, HeaderBufferSize);

	if (PacketSize == LookaheadBufferSize)		// Lookahead buffer contains a complete packet
	{
		//
		//	path 1 of 3, tested ok!
		//
		NdisMoveMemory(pBuffer + HeaderBufferSize, pLookaheadBuffer, PacketSize);

		// do the filtering work
		if (TRUE == RabbitHole(pBuffer, HeaderBufferSize + PacketSize)) {
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreeMemory(pBuffer, 0, 0);

	}
	else										// Lookahead buffer contains an incomplete packet
	{
		//
		// get the full packet
		//
		// DbgPrint("Get Full Packet!\r\n");

		//if (MacHandle == NULL) {
		//	DbgPrint("MacHandle == NULL!(0: FakeNDISReceiveHandler)\r\n");
		//	NdisFreeMemory(pBuffer, 0, 0);
		//	return NDIS_STATUS_NOT_ACCEPTED;
		//}

		// make pBuffer a NDIS buffer to hold data
		NdisAllocateBuffer(&status, &pNdisBuffer, g_BufferPool, pBuffer + HeaderBufferSize, PacketSize);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisBuffer == NULL*/) {
			DbgPrint("allocate pNdisBuffer(size = %d) failed in FakeNDISReceiveHandler!\r\n", PacketSize);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		// allocate a NIDS packet to chain buffer in.
		NdisAllocatePacket(&status, &pNdisPacket, g_PacketPool);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisPacket == NULL*/) {
			DbgPrint("allocate pNdisPacket failed in FakeNDISReceiveHandler!\r\n");
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NDIS_SET_PACKET_STATUS(pNdisPacket, STATUS_SUCCESS);

		// Bring explosives.
		KeInitializeEvent(&evt, NotificationEvent, FALSE);
		*(PKEVENT *)(pNdisPacket->ProtocolReserved) = &evt;

		NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

		// try to get complete packet
		NdisTransferData(&status, pNode->pOpenBlock, MacReceiveContext, 0, PacketSize, pNdisPacket, &ulLen);

		if (status == NDIS_STATUS_PENDING) {			// wait for the right time
			//
			// Path 2 of 3, not tested yet! Warning: An Error may occur!
			//
			DbgPrint("NdisTransferData is pending in FakeNDISReceiveHandler!\r\n", status);
			KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL);
		} else if (status != NDIS_STATUS_SUCCESS) {
			DbgPrint("NdisTransferData failed(status == 0x%08x) in FakeNDISReceiveHandler!\r\n", status);
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		//
		// Path 3 of 3, Filtering doesn't seem to work properly.
		//
		// do the filtering work
		if (TRUE == FilterPacket_ReceiveHandler(pBuffer, HeaderBufferSize, pNdisPacket)) {
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreePacket(pNdisPacket);
		NdisFreeBuffer(pNdisBuffer);
		NdisFreeMemory(pBuffer, 0, 0);
	}

	// call the original NDIS routine.
	__asm {
		pushad;
		push	PacketSize;
		push	LookaheadBufferSize;
		push	pLookaheadBuffer;
		push	HeaderBufferSize;
		push	pHeaderBuffer;
		push	MacReceiveContext;
		push	ProtocolBindingContext;
		mov		eax, ulFunAddr;
		call	eax;
		mov		status, eax;
		popad;
	}

	return status;
}
Ejemplo n.º 26
0
//
//发送相关函数的实现、
//
NTSTATUS
SecLabSendPacket(
                 PADAPT			         pAdapt,
				 IN PDEVICE_OBJECT       DeviceObject,
				 IN PIRP                 pIrp
				 )
{
	PIO_STACK_LOCATION      pIrpSp;
    ULONG                   FunctionCode;
    ULONG                   DataLength;
    NTSTATUS                NtStatus=STATUS_INVALID_HANDLE;
    NDIS_STATUS             Status;
    
    PNDIS_PACKET                pNdisPacket;
    PNDIS_BUFFER                pNdisBuffer;
//  SECLAB_ETH_HEADER UNALIGNED *pEthHeader;

	PUCHAR      pData;
	ULONG        i;

#ifdef NDIS51
    PVOID                   CancelId;
#endif

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

    pNdisPacket = NULL;
	pNdisBuffer = NULL;

    do
    {
        if (pAdapt == NULL)
        {
            DbgPrint("Write: FileObject not yet associated with a device\n");
            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        //
        // 检查发送数据包的长度
        //

		DataLength=pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
		
        if (DataLength > MAX_SEND_PACKETLEN )
        {
            DbgPrint("Write: Open data length larger than max frame size\n");

            NtStatus = STATUS_UNSUCCESSFUL;
            break;
        }

        //
        //  构造一个发送封包
        //

		if(pAdapt->SendPacketPoolHandle==NULL)
		{
			DbgPrint("The Packet Pool should not be NULL");
			DbgBreakPoint();
			break;
		}

	    do
		{
			 //其实怎么样分配内存是无关紧要的,忘记资源的释放也不是很严重的
			 //最多导致内存支出过多。关键是不能让程序引用不存在的内存,这样会
			 //造成崩溃,比如重复释放内存。崩溃的另一大可能是在Dispatch>=passive
			 //级别上调用非分页内存。
		     //pData=(PUCHAR)ExAllocatePool(NonPagedPool,DataLength);
			 NdisAllocateMemoryWithTag((PVOID *)(&pData), DataLength,'lceS');

		     if(pData==NULL)
			 {
			      DbgPrint("Can not allocate pool for send");
			      break;
			 }
		     //RtlCopyMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength);
             NdisMoveMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength);

             //
             //  将其转化为NDIS_BUFFER.
             //
             NdisAllocateBuffer(
                 &Status,
                 &pNdisBuffer,
                 SendBufferPool,
                 pData,
                 DataLength);
        
              if (Status != NDIS_STATUS_SUCCESS)
			  {
                   DbgPrint("failed to allocate Ndis Buffer");
                   break;
			  }		

              NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->SendPacketPoolHandle);

              if (Status != NDIS_STATUS_SUCCESS)
			  {
                   DbgPrint("failed to alloc NDIS packet");
                   break;
			  }

              NDIS_SET_PACKET_STATUS(pNdisPacket, 0);
              pNdisBuffer->Next = NULL;
              NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
			  
		      pNdisPacket->Private.Head->Next=NULL;
		      pNdisPacket->Private.Tail=NULL;

              break;
		}
        while (FALSE);

        if (pNdisPacket == NULL || pNdisBuffer==NULL)
		{
            //
            //  Clean up
            //
            if (pNdisBuffer != NULL)
			{
                NdisFreeBuffer(pNdisBuffer);
			}

            if (pData != NULL)
			{
                NdisFreeMemory(pData, 0, 0);
			}
		}

        IoMarkIrpPending(pIrp);
		NtStatus = STATUS_PENDING;
        pIrp->IoStatus.Status = STATUS_PENDING;
        //
        //  初始化封包中的标志符。当标志符值为0时此包被释放
        //
        SECLAB_SEND_PKT_RSVD(pNdisPacket)->RefCount = 1;

#ifdef NDIS51

        //
        //  NDIS 5.1 supports cancelling sends. We set up a cancel ID on
        //  each send packet (which maps to a Write IRP), and save the
        //  packet pointer in the IRP. If the IRP gets cancelled, we use
        //  NdisCancelSendPackets() to cancel the packet.
        //

        CancelId = SECLAB_GET_NEXT_CANCEL_ID();
        NDIS_SET_PACKET_CANCEL_ID(pNdisPacket, CancelId);
        pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pAdapt;
        pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNdisPacket;

		NdisInterlockedIncrement(&PendedSendCount);

		NdisAcquireSpinLock(&WriteIrpLock);
        InsertTailList(&PendedWritesList, &pIrp->Tail.Overlay.ListEntry);
        IoSetCancelRoutine(pIrp, SecLabCancelWrite);
		NdisReleaseSpinLock(&WriteIrpLock);

#endif // NDIS51
               
        //
        //  创建一个指针从packet回指向IRP
        //
        SECLAB_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp;

		//
		//创建三个信号,以便在发送完成例程中指示此包
		//
		SECLAB_SIGNAL1_FROM_SEND_PKT(pNdisPacket)=SIGNAL1;
        SECLAB_SIGNAL2_FROM_SEND_PKT(pNdisPacket)=SIGNAL2;
		SECLAB_SIGNAL3_FROM_SEND_PKT(pNdisPacket)=SIGNAL3;

		//
		//发包
		//
        NdisSendPackets(pAdapt->BindingHandle, &pNdisPacket, 1); 
    }

    while (FALSE);

    if (NtStatus != STATUS_PENDING)
    {
        pIrp->IoStatus.Status = NtStatus;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);	
    }

    return (NtStatus);
}
Ejemplo n.º 27
0
VOID
	natpBindAdapter(
		OUT PNDIS_STATUS Status,
		IN  NDIS_HANDLE BindContext,
		IN  PNDIS_STRING DeviceName,
		IN  PVOID SystemSpecific1,
		IN  PVOID SystemSpecific2
		)
{
	NDIS_HANDLE ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER Param;
	NDIS_STRING DeviceStr = UPPER_BINDINGS;
	PFILTER_ADAPTER pAdapt = NULL;
	NDIS_STATUS Sts;
	UINT MediumIndex, i;
	ULONG TotalSize;
	WCHAR DevicePrefix[]  = L"\\Device\\";

	UNREFERENCED_PARAMETER(BindContext);
	UNREFERENCED_PARAMETER(SystemSpecific2);

	__try{
		
		NdisOpenProtocolConfiguration(
			Status,
			&ConfigHandle,
			SystemSpecific1
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisReadConfiguration(
			Status,
			&Param,
			ConfigHandle,
			&DeviceStr,
			NdisParameterString
			);
		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		TotalSize = sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength + DeviceName->MaximumLength;
		NdisAllocateMemoryWithTag(&pAdapt, TotalSize, NAT_TAG);

		if (NULL == pAdapt){
			*Status = NDIS_STATUS_RESOURCES;
			__leave;
		}


		NdisZeroMemory(pAdapt, TotalSize);
		pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength;
		pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length;
		pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER));
		NdisMoveMemory(
			pAdapt->DeviceName.Buffer,
			Param->ParameterData.StringData.Buffer,
			Param->ParameterData.StringData.MaximumLength
			);
		if(sizeof(DevicePrefix) >= DeviceName->Length){
		
			
		}else{
		
			pAdapt->RootDeviceName.MaximumLength = DeviceName->MaximumLength;
			pAdapt->RootDeviceName.Length = DeviceName->Length - sizeof(DevicePrefix) + sizeof(WCHAR);
			pAdapt->RootDeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength);
			NdisMoveMemory(
				pAdapt->RootDeviceName.Buffer,
				DeviceName->Buffer + sizeof(DevicePrefix)/sizeof(WCHAR) - 1,
				DeviceName->MaximumLength - sizeof(DevicePrefix)/sizeof(WCHAR) + 1
				);
		}

		NdisInitializeEvent(&pAdapt->Event);
		NdisAllocateSpinLock(&pAdapt->Lock);

		natInitControlBlock(&pAdapt->ctrl);

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->SndBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->RcvBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisOpenAdapter(
			Status,
			&Sts,
			&pAdapt->BindingHandle,
			&MediumIndex,
			MediumArray,
			sizeof(MediumArray)/sizeof(NDIS_MEDIUM),
			ProtHandle,
			pAdapt,
			DeviceName,
			0,NULL
			);

		if (*Status == NDIS_STATUS_PENDING){
			NdisWaitEvent(&pAdapt->Event, 0);
			*Status = pAdapt->Status;
		}

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		pAdapt->Medium = MediumArray[MediumIndex];

		pAdapt->MiniportInitPending = TRUE;
		NdisInitializeEvent(&pAdapt->MiniportInitEvent);

		*Status = 
			NdisIMInitializeDeviceInstanceEx(
				DriverHandle,
				&pAdapt->DeviceName,
				pAdapt
				);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		StartQueryInfo( pAdapt );

	} __finally{
	}

	if (ConfigHandle != NULL)
		NdisCloseConfiguration(ConfigHandle);

	if(NDIS_STATUS_SUCCESS != *Status){
		
		if (pAdapt != NULL){
			
			if (pAdapt->BindingHandle != NULL){

				NDIS_STATUS    LocalStatus;

				NdisResetEvent(&pAdapt->Event);

				NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
				pAdapt->BindingHandle = NULL;

				if (LocalStatus == NDIS_STATUS_PENDING){
					NdisWaitEvent(&pAdapt->Event, 0);
					LocalStatus = pAdapt->Status;
				}
			}

			natFreeAllItems(&pAdapt->ctrl);
			natFreeAllFwSessionsAndRules(&pAdapt->ctrl);

			for(i = 0;i<FLT_FW_SESSION_HASH_TBL_SZ;i++)
				NdisFreeSpinLock(pAdapt->ctrl.FwSessionLocks + i);

			NdisFreeSpinLock(&pAdapt->ctrl.IcmpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.UdpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.TcpRuleLock);

			natmFreeAllPacketPools(pAdapt);

			NdisFreeSpinLock(&pAdapt->Lock);

			NdisFreeMemory(pAdapt, 0, 0);
			pAdapt = NULL;
		}
	}
}
Ejemplo n.º 28
0
NDIS_STATUS
NTAPI
MiniportInitialize (
    OUT PNDIS_STATUS OpenErrorStatus,
    OUT PUINT SelectedMediumIndex,
    IN PNDIS_MEDIUM MediumArray,
    IN UINT MediumArraySize,
    IN NDIS_HANDLE MiniportAdapterHandle,
    IN NDIS_HANDLE WrapperConfigurationContext
    )
{
    PRTL_ADAPTER adapter;
    NDIS_STATUS status;
    UINT i;
    PNDIS_RESOURCE_LIST resourceList;
    UINT resourceListSize;
    
    //
    // Make sure the medium is supported
    //
    for (i = 0; i < MediumArraySize; i++)
    {
        if (MediumArray[i] == NdisMedium802_3)
        {
            *SelectedMediumIndex = i;
            break;
        }
    }
    
    if (i == MediumArraySize)
    {
        NDIS_DbgPrint(MIN_TRACE, ("802.3 medium was not found in the medium array\n"));
        return NDIS_STATUS_UNSUPPORTED_MEDIA;
    }
    
    //
    // Allocate our adapter context
    //
    status = NdisAllocateMemoryWithTag((PVOID*)&adapter,
                                       sizeof(*adapter),
                                       ADAPTER_TAG);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context\n"));
        return NDIS_STATUS_RESOURCES;
    }
    
    RtlZeroMemory(adapter, sizeof(*adapter));
    adapter->MiniportAdapterHandle = MiniportAdapterHandle;
    NdisAllocateSpinLock(&adapter->Lock);

    //
    // Notify NDIS of some characteristics of our NIC
    //
    NdisMSetAttributesEx(MiniportAdapterHandle,
                         adapter,
                         0,
                         NDIS_ATTRIBUTE_BUS_MASTER,
                         NdisInterfacePci);

    //
    // Get our resources for IRQ and IO base information
    //
    resourceList = NULL;
    resourceListSize = 0;
    NdisMQueryAdapterResources(&status,
                               WrapperConfigurationContext,
                               resourceList,
                               &resourceListSize);
    if (status != NDIS_STATUS_RESOURCES)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #1\n"));
        status = NDIS_STATUS_FAILURE;
        goto Cleanup;
    }
    
    status = NdisAllocateMemoryWithTag((PVOID*)&resourceList,
                                resourceListSize,
                                RESOURCE_LIST_TAG);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list\n"));
        goto Cleanup;
    }
    
    NdisMQueryAdapterResources(&status,
                               WrapperConfigurationContext,
                               resourceList,
                               &resourceListSize);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #2\n"));
        goto Cleanup;
    }
    
    ASSERT(resourceList->Version == 1);
    ASSERT(resourceList->Revision == 1);
    
    for (i = 0; i < resourceList->Count; i++)
    {
        switch (resourceList->PartialDescriptors[i].Type)
        {
            case CmResourceTypePort:
                ASSERT(adapter->IoRangeStart == 0);
                
                ASSERT(resourceList->PartialDescriptors[i].u.Port.Start.HighPart == 0);
                
                adapter->IoRangeStart = resourceList->PartialDescriptors[i].u.Port.Start.LowPart;
                adapter->IoRangeLength = resourceList->PartialDescriptors[i].u.Port.Length;
                
                NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n",
                              adapter->IoRangeStart, adapter->IoRangeStart + adapter->IoRangeLength));
                break;
                
            case CmResourceTypeInterrupt:
                ASSERT(adapter->InterruptVector == 0);
                ASSERT(adapter->InterruptLevel == 0);
                
                adapter->InterruptVector = resourceList->PartialDescriptors[i].u.Interrupt.Vector;
                adapter->InterruptLevel = resourceList->PartialDescriptors[i].u.Interrupt.Level;
                adapter->InterruptShared = (resourceList->PartialDescriptors[i].ShareDisposition == CmResourceShareShared);
                adapter->InterruptFlags = resourceList->PartialDescriptors[i].Flags;
                
                NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", adapter->InterruptVector));
                break;

            default:
                NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", resourceList->PartialDescriptors[i].Type));
                break;
        }
    }
    
    NdisFreeMemory(resourceList, resourceListSize, 0);
    resourceList = NULL;
    
    if (adapter->IoRangeStart == 0 || adapter->InterruptVector == 0)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n"));
        goto Cleanup;
    }
    
    //
    // Allocate the DMA resources
    //
    status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle,
                                             FALSE, // RTL8139 only supports 32-bit addresses
                                             MAXIMUM_FRAME_SIZE);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n"));
        goto Cleanup;
    }

    adapter->ReceiveBufferLength = FULL_RECEIVE_BUFFER_SIZE;
    NdisMAllocateSharedMemory(MiniportAdapterHandle,
                              adapter->ReceiveBufferLength,
                              FALSE,
                              (PVOID*)&adapter->ReceiveBuffer,
                              &adapter->ReceiveBufferPa);
    if (adapter->ReceiveBuffer == NULL)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive buffer\n"));
        status = NDIS_STATUS_RESOURCES;
        goto Cleanup;
    }
    
    NdisMAllocateSharedMemory(MiniportAdapterHandle,
                              MINIMUM_FRAME_SIZE * TX_DESC_COUNT,
                              FALSE,
                              (PVOID*)&adapter->RuntTxBuffers,
                              &adapter->RuntTxBuffersPa);
    if (adapter->RuntTxBuffers == NULL)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate runt TX buffer\n"));
        status = NDIS_STATUS_RESOURCES;
        goto Cleanup;
    }
    
    //
    // Register the I/O port range and configure the NIC
    //
    status = NdisMRegisterIoPortRange((PVOID*)&adapter->IoBase,
                                      MiniportAdapterHandle,
                                      adapter->IoRangeStart,
                                      adapter->IoRangeLength);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", status));
        goto Cleanup;
    }
    
    //
    // Adapter setup
    //
    status = NICPowerOn(adapter);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", status));
        goto Cleanup;
    }
    
    status = NICSoftReset(adapter);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", status));
        goto Cleanup;
    }
    
    status = NICGetPermanentMacAddress(adapter, adapter->PermanentMacAddress);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", status));
        goto Cleanup;
    }
    
    RtlCopyMemory(adapter->CurrentMacAddress, adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH);
    
    //
    // Update link state and speed
    //
    NICUpdateLinkStatus(adapter);
        
    status = NICRegisterReceiveBuffer(adapter);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to setup receive buffer (0x%x)\n", status));
        goto Cleanup;
    }

    //
    // We're ready to handle interrupts now
    //
    status = NdisMRegisterInterrupt(&adapter->Interrupt,
                                    MiniportAdapterHandle,
                                    adapter->InterruptVector,
                                    adapter->InterruptLevel,
                                    TRUE, // We always want ISR calls
                                    adapter->InterruptShared,
                                    (adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ?
                                        NdisInterruptLatched : NdisInterruptLevelSensitive);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", status));
        goto Cleanup;
    }
    
    adapter->InterruptRegistered = TRUE;
    
    //
    // Enable interrupts on the NIC
    //
    adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
    status = NICApplyInterruptMask(adapter);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", status));
        goto Cleanup;
    }
    
    //
    // Turn on TX and RX now
    //
    status = NICEnableTxRx(adapter);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", status));
        goto Cleanup;
    }

    return NDIS_STATUS_SUCCESS;
    
Cleanup:
    if (resourceList != NULL)
    {
        NdisFreeMemory(resourceList, resourceListSize, 0);
    }
    if (adapter != NULL)
    {
        MiniportHalt(adapter);
    }
    
    return status;
}
Ejemplo n.º 29
0
/******************************************************************************
 *
 *  Name: AllocateRxQ()
 *
 *  Description: Allocate Rx Buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS AllocateRxQ(
  IN PMRVDRV_ADAPTER Adapter
  )
{

  ULONG i;
    NDIS_STATUS tStatus;
    BOOLEAN                 bSuccess = TRUE;
    PACKET_QUEUE_NODE       **pNode;
    PNDIS_PACKET_OOB_DATA   pOOB; 

    /// Initialize rx-related variables 
    Adapter->RxBufferPoolHandle = 
    Adapter->RxPacketPoolHandle = NULL;
    //
    InitializeQKeeper(&Adapter->RxPacketFreeQueue);
    // 
    for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    {
        Adapter->pRxBufVM[i] = NULL;
        Adapter->pRxBuffer[i] = NULL;
        Adapter->pRxPacket[i] = NULL;
    }

    /// Allocate all needed memory space 
    do
    {
     // packet pool 
     NdisAllocatePacketPoolEx(
                                &tStatus, 
                                &Adapter->RxPacketPoolHandle,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE, 
                                PROTOCOL_RESERVED_SIZE_IN_PACKET);

        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate packet pool!\n"));
            return tStatus;
        }

        // buffer pool 
        NdisAllocateBufferPool(
                               &tStatus,
                               &Adapter->RxBufferPoolHandle,
                               MRVDRV_NUM_RX_PKT_IN_QUEUE);
        
        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate buffer pool!\n"));
            bSuccess = FALSE;
            break;
        }

    // assign space to used three array 
        for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
        {                          
          // data payload space array 
           tStatus = NdisAllocateMemoryWithTag(
                         &Adapter->pRxBufVM[i], 
                         MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                         MRVDRV_MEMORY_TAG);
           //to hide unused packet header ahead of pointer.   
           //(ULONG)Adapter->pRxBufVM[i] += (sizeof(RxPD)+sizeof(pkt.Len)+sizeof(pkt.Type));
           (ULONG)Adapter->pRxBufVM[i] += MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE;

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }
                      
            // buffer array 
            NdisAllocateBuffer(
                                &tStatus,
                                &Adapter->pRxBuffer[i],
                                Adapter->RxBufferPoolHandle,
                                Adapter->pRxBufVM[i],
                                (MRVDRV_ETH_RX_PACKET_BUFFER_SIZE-MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE));

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

      // packet array   
            NdisAllocatePacket(
                               &tStatus, 
                               &Adapter->pRxPacket[i],
                               Adapter->RxPacketPoolHandle);

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

            // init OBB space
            pOOB = NDIS_OOB_DATA_FROM_PACKET(Adapter->pRxPacket[i]);
            NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA));
            NDIS_SET_PACKET_HEADER_SIZE(Adapter->pRxPacket[i], MRVDRV_ETH_HEADER_SIZE);

            // chain the packet and buffer 
            NdisChainBufferAtFront(Adapter->pRxPacket[i],
                                   Adapter->pRxBuffer[i]);

            // fill packet node 
            Adapter->RxPacketQueueNode[i].pPacket = Adapter->pRxPacket[i];
    
            pNode = (PACKET_QUEUE_NODE **)Adapter->pRxPacket[i]->MiniportReserved;
            *pNode = &Adapter->RxPacketQueueNode[i];
            
            // insert to free queue
            InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);

        }   // end of for(;;)

    } while (0);

    if ( ! bSuccess )
    {
        // clean up all
        FreeRxQ(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    Adapter->sNumOutstandingRxPacket = 0;

    return NDIS_STATUS_SUCCESS;
}