/*----------------------------------------------------------------------------*/
WLAN_STATUS
kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo,
		   IN PVOID pvPacket,
		   IN PUINT_8 pucPacketStart,
		   IN UINT_32 u4PacketLen, IN BOOL fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]
    )
{
	PNDIS_PACKET prNdisPacket;
	PNDIS_BUFFER prNdisBuf;
	NDIS_STATUS rStatus;


	ASSERT(prGlueInfo);
	ASSERT(pvPacket);
	ASSERT(pucPacketStart);

	prNdisPacket = (PNDIS_PACKET) pvPacket;

	NdisAllocateBuffer(&rStatus,
			   &prNdisBuf,
			   prGlueInfo->hBufPool, (PVOID) pucPacketStart, (UINT_32) u4PacketLen);

	if (rStatus != NDIS_STATUS_SUCCESS) {
		ASSERT(0);
		return WLAN_STATUS_FAILURE;
	}

	NdisChainBufferAtBack(prNdisPacket, prNdisBuf);

	if (fgIsRetain) {
		/* We don't have enough receive buffers, so set the status
		   on the packet to NDIS_STATUS_RESOURCES to force the
		   protocol driver(s) to copy this packet and return this
		   buffer immediately after returning from the
		   NdisMIndicateReceivePacket function. */
		NDIS_SET_PACKET_STATUS(prNdisPacket, NDIS_STATUS_RESOURCES);
	} else {

		/* We have enough receive buffers, so set the status on the
		   packet to NDIS_STATUS_SUCCESS. */
		NDIS_SET_PACKET_STATUS(prNdisPacket, NDIS_STATUS_SUCCESS);
	}

#if CFG_TCP_IP_CHKSUM_OFFLOAD
	kalUpdateRxCSUMOffloadParam(pvPacket, aerCSUM);
#endif

	return WLAN_STATUS_SUCCESS;
}
示例#2
0
/*-------------------------------------------------------------------------
  ssh_driver_transfer_data()

  Copies received network data to a given upper layer supplied NDIS packet.
  
  Arguments:
  pkt - NDIS packet for data  
  bytes_transferred - how many bytes has been written into the packet
  miniport_context - virtual NIC object
  receive_context - ???
  byte_offset - where to start copy operation
  bytes_to_transfer -   how may bytes to copy

  Returns:
  NDIS_STATUS_FAILURE - always
  
  Notes:
  This function is not supported because we always indicate complete 
  NDIS packets to the upper layer. So upper layer should never call this 
  function but we anyway return the FAILURE status code to upper layer.

  Default IRQL: DISPATCH_LEVEL
  -------------------------------------------------------------------------*/
static NDIS_STATUS
ssh_driver_transfer_data(PNDIS_PACKET pkt,
                         PUINT bytes_transferred,
                         NDIS_HANDLE miniport_context,
                         NDIS_HANDLE receive_context,
                         UINT byte_offset,
                         UINT bytes_to_transfer)
{
  SshNdisIMAdapter adapter = (SshNdisIMAdapter)miniport_context;

  SSH_ASSERT(SSH_GET_IRQL() <= SSH_DISPATCH_LEVEL);
  SSH_ASSERT(miniport_context != NULL);
  SSH_ASSERT(receive_context != NULL);
  SSH_ASSERT(pkt != NULL);
  SSH_ASSERT(bytes_transferred != NULL);

  *bytes_transferred = 0;

  SSH_DEBUG(SSH_D_ERROR, 
            ("Adapter %@: Unexpected MiniportTransferData() call.",
             ssh_adapter_id_st_render, adapter));

  NDIS_SET_PACKET_STATUS(pkt, NDIS_STATUS_FAILURE);

  return (NDIS_STATUS_FAILURE);
}
示例#3
0
文件: sendrcv.c 项目: PaulJing/Sora
/*
NicIndicateRecvPackets indicate received packet (MAC frame) to NDIS 
(then protocol stack)

Parameters:
    pAdapter       : pointer to adapter object created by miniport driver.
    ppNBSPackets   : pointer to an NDIS packet to be indicated up.
      
Return:  

Note: 

History:    Created by yichen, 1/Apr/2009

IRQL: PASSIVE_LEVEL
*/
VOID NicIndicateRecvPackets(IN PMP_ADAPTER pAdapter,IN PPNDIS_PACKETS_OR_NBL ppNBSPackets)
{
    NDIS_SET_PACKET_HEADER_SIZE(*ppNBSPackets, ETH_HEADER_SIZE);
    NDIS_SET_PACKET_STATUS(*ppNBSPackets, NDIS_STATUS_SUCCESS);
    NdisMIndicateReceivePacket(pAdapter->AdapterHandle, ppNBSPackets, 1); //only 1 packet indicated
    InterlockedIncrement64(&pAdapter->ullGoodReceives);
}
示例#4
0
void CleanQueuedSendPacket(PHWT_ADAPTER Adapter) {

	KIRQL irql;
	KeAcquireSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		&irql);
	if (Adapter->UExtKeObj.SendPacketControl) {
		ObDereferenceObject(Adapter->UExtKeObj.SendPacketControl);
		Adapter->UExtKeObj.SendPacketControl = NULL;
	}
	while(1) {
		PNDIS_PACKET Packet;
		if (remove_thread_safe_enlist_head(Adapter->UExtKeObj.SendPacketList, 
			&Packet,
			1)) {			
			NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_FAILURE);
			NdisMSendComplete(Adapter->AdapterHandle,
				Packet,
				NDIS_STATUS_FAILURE);
			continue;
		}
		break;
	}
	KeReleaseSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		irql);
}
示例#5
0
// Stop check of packet transmission
BOOL NeoNdisSendPacketsHaltCheck(NDIS_PACKET **PacketArray, UINT NumberOfPackets)
{
	UINT i;

	if (ctx == NULL)
	{
		return FALSE;
	}

	if (ctx->Halting != FALSE || ctx->Opened == FALSE)
	{
		// Finishing
		for (i = 0;i < NumberOfPackets;i++)
		{
			NDIS_SET_PACKET_STATUS(PacketArray[i], NDIS_STATUS_FAILURE);

			if (g_is_win8)
			{
				NdisMSendComplete(ctx->NdisMiniport, PacketArray[i], NDIS_STATUS_SUCCESS);
			}

			ctx->Status.NumPacketSendError++;
		}
		return FALSE;
	}
	return TRUE;
}
示例#6
0
NTSTATUS
MPGetSendPacket(PHWT_ADAPTER Adapter, PVOID Input, ULONG InputSize, PVOID Output, ULONG OutputSize, PIRP Irp) {

	PGET_SEND_PACKET_OUT get_send_packet_out;
	PNDIS_PACKET Packet;
	get_send_packet_out = (PGET_SEND_PACKET_OUT)Output;

	if (remove_thread_safe_enlist_head(Adapter->UExtKeObj.SendPacketList, 
		&Packet,
		1)) {
		struct Send_Packet_Data* packet_data;
		packet_data = Packet2PacketData(Packet);
		if (packet_data) {
			get_send_packet_out->hResult = ERROR_SUCCESS;
			get_send_packet_out->Packet = (PACKET_HANDLE)packet_data;
			get_send_packet_out->Addr= packet_data->m_addr;
			get_send_packet_out->Size = packet_data->m_len;	
			return STATUS_SUCCESS;
		}
		else {
			NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_FAILURE);
			NdisMSendComplete(Adapter->AdapterHandle,
				Packet,
				NDIS_STATUS_FAILURE);
		}
	}
	get_send_packet_out->hResult = ERROR_RESOURCE_FAILED;
	get_send_packet_out->Packet = 0;
	get_send_packet_out->Addr= NULL;
	get_send_packet_out->Size = 0;
	return STATUS_SUCCESS;
}
示例#7
0
文件: sendrcv.c 项目: PaulJing/Sora
VOID NicCompletePacket(IN PMP_ADAPTER Adapter, IN PNDIS_PACKET_OR_NBL pNBSPacket)
{
   NDIS_SET_PACKET_STATUS(pNBSPacket,NDIS_STATUS_SUCCESS);
   NdisMSendComplete(Adapter->AdapterHandle,
                     pNBSPacket,
                     NDIS_STATUS_SUCCESS);
   InterlockedIncrement64(&Adapter->ullGoodTransmits);
}
示例#8
0
文件: sendrcv.c 项目: PaulJing/Sora
VOID NicDropPacket(IN PMP_ADAPTER Adapter, IN PNDIS_PACKET_OR_NBL pNBSPacket)
{
   NDIS_SET_PACKET_STATUS(pNBSPacket,NDIS_STATUS_FAILURE);
   NdisMSendComplete(Adapter->AdapterHandle,
                     pNBSPacket,
                     NDIS_STATUS_FAILURE);
   InterlockedIncrement64(&Adapter->ullTransmitFail);
}
示例#9
0
VOID 
MPSendPackets(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN PPNDIS_PACKET PacketArray,
    IN UINT NumberOfPackets) {

	PHWT_ADAPTER Adapter;
	KIRQL irql;
	UINT Index;
	Adapter = (PHWT_ADAPTER)MiniportAdapterContext;
	
	KeAcquireSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		&irql);
	if (Adapter->UExtKeObj.SendPacketControl) {
		for(Index=0; Index < NumberOfPackets; Index++) {
			if (get_thread_safe_enlist_count(Adapter->UExtKeObj.SendPacketList) >= MAX_QUEUED_SEND_PACKET) {
				NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_FAILURE);
				NdisMSendComplete(Adapter->AdapterHandle,
					PacketArray[Index],
					NDIS_STATUS_FAILURE);
				continue;
			}
			insert_thread_safe_enlist_tail(Adapter->UExtKeObj.SendPacketList, 
				PacketArray[Index],
				1); 
			KeReleaseSemaphore(Adapter->UExtKeObj.SendPacketControl,
				IO_NO_INCREMENT,
				1,
				FALSE);
		}
	}
	else {
		for(Index=0; Index < NumberOfPackets; Index++) {
			NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_FAILURE);
			NdisMSendComplete(Adapter->AdapterHandle,
				PacketArray[Index],
				NDIS_STATUS_FAILURE);
		}
	}
	KeReleaseSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		irql);
    return;
}
示例#10
0
NTSTATUS
MPIndicatePacket(PHWT_ADAPTER Adapter, PVOID Input, ULONG InputSize, PDEV_RET Output, ULONG OutputSize, PIRP Irp) {

	PVOID data = NULL;
	NDIS_STATUS ndis_status = NDIS_STATUS_FAILURE;
	PNDIS_BUFFER ndis_buffer = NULL;
	PNDIS_PACKET ndis_packet = NULL;	
	do {
		data = ExAllocatePoolWithTag(NonPagedPool, InputSize, 'tkpi');

		RtlCopyMemory(data, Input, InputSize);
				
		NdisAllocateBuffer(&ndis_status, 
                           &ndis_buffer, 
                           Adapter->AllocateBufferPool,
                           data,
                           InputSize);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisAllocatePacket(&ndis_status,
                           &ndis_packet,
                           Adapter->AllocatePacketPool);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisReinitializePacket(ndis_packet);
		*(PVOID*)ndis_packet->MiniportReserved = data;
		NdisChainBufferAtBack(ndis_packet, ndis_buffer);
		NDIS_SET_PACKET_HEADER_SIZE(ndis_packet, sizeof(ETHERNET_HEADER));
		NDIS_SET_PACKET_STATUS(ndis_packet, NDIS_STATUS_SUCCESS);
		NdisMIndicateReceivePacket(Adapter->AdapterHandle, &ndis_packet, 1);

		Output->hResult = S_OK;

		ndis_status = NDIS_STATUS_SUCCESS;
	} while(FALSE);
	
	if (ndis_status != NDIS_STATUS_SUCCESS &&
		ndis_status != STATUS_PENDING) {
		if (ndis_packet)
			NdisFreePacket(ndis_packet);
		if (ndis_buffer) 
			NdisFreeBuffer(ndis_buffer);		
		if (data)
			ExFreePoolWithTag(data, 'tkpi');
	}
	return ndis_status;
}
示例#11
0
NTSTATUS
MPCompleteSendPacket(PHWT_ADAPTER Adapter, PVOID Input, ULONG InputSize, PDEV_RET Output, ULONG OutputSize, PIRP Irp) {

	PCOMPLETE_SEND_PACKET_IN complete_send_packet_in;
	struct Send_Packet_Data* packet_data;
	complete_send_packet_in = (PCOMPLETE_SEND_PACKET_IN)Input;
	packet_data = (struct Send_Packet_Data*)complete_send_packet_in->Packet;
	NDIS_SET_PACKET_STATUS(packet_data->m_ndis_packet, 
		complete_send_packet_in->hResult);
	NdisMSendComplete(Adapter->AdapterHandle,
		packet_data->m_ndis_packet,
		complete_send_packet_in->hResult);	
	free_send_packet_data(packet_data);
	Output->hResult = ERROR_SUCCESS;
	return STATUS_SUCCESS;
}
示例#12
0
/*
========================================================================
Routine Description:
    Early checking and OS-depened parsing for Tx packet to AP device.

Arguments:
    NDIS_HANDLE 	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
	PPNDIS_PACKET	ppPacketArray			The packet array need to do transmission.
	UINT			NumberOfPackets			Number of packet in packet array.

Return Value:
	NONE

Note:
	This function do early checking and classification for send-out packet.
	You only can put OS-depened & AP related code in here.
========================================================================
*/
VOID wdev_tx_pkts(NDIS_HANDLE dev_hnd, PPNDIS_PACKET pkt_list, UINT pkt_cnt, struct wifi_dev *wdev)
{
    RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd;
    PNDIS_PACKET pPacket;
    BOOLEAN allowToSend;
    UCHAR wcid = MCAST_WCID;
    UINT Index;



    for (Index = 0; Index < pkt_cnt; Index++)
    {
        pPacket = pkt_list[Index];

        if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
                                 fRTMP_ADAPTER_RADIO_OFF |
                                 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)))
        {
            /* Drop send request since hardware is in reset state */
            RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
            continue;
        }

        if ((wdev->allow_data_tx == TRUE) && (wdev->tx_pkt_allowed))
            allowToSend = wdev->tx_pkt_allowed(pAd, wdev, pPacket, &wcid);
        else
            allowToSend = FALSE;

        if (allowToSend == TRUE)
        {
            RTMP_SET_PACKET_WCID(pPacket, wcid);
            RTMP_SET_PACKET_WDEV(pPacket, wdev->wdev_idx);
            NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
            pAd->RalinkCounters.PendingNdisPacketCount++;

#ifdef CONFIG_AP_SUPPORT
            IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
            {
#ifdef DELAYED_TCP_ACK
                if(!delay_tcp_ack(pAd, wcid, pPacket))
#endif /* DELAYED_TCP_ACK */
                    APSendPacket(pAd, pPacket);
            }
#endif /* CONFIG_AP_SUPPORT */

        } else {
示例#13
0
/*
 *************************************************************************
 *  SendPacketsHandler
 *************************************************************************
 *
 *  Send an array of packets simultaneously.
 *
 */
VOID SendPacketsHandler(NDIS_HANDLE MiniportAdapterContext,
						PPNDIS_PACKET PacketArray,
						UINT NumberofPackets)
{
	NDIS_STATUS stat;
	UINT i;

	DBGOUT(("==> SendPacketsHandler(0x%x)", (UINT)MiniportAdapterContext));

	/*
	 *  This is a great opportunity to be lazy.
	 *  Just call MiniportSend with each packet in sequence and
	 *  set the result in the packet array object.
	 */
	for (i = 0; i < NumberofPackets; i++){
		stat = MiniportSend(MiniportAdapterContext, PacketArray[i], 0);
		NDIS_SET_PACKET_STATUS(PacketArray[i], stat);
	}

	DBGOUT(("<== SendPacketsHandler"));
}
示例#14
0
//wireshark这个模块就不自己建线程了,就直接用系统的workitem就好了
VOID	WSWorkThread(PDEVICE_OBJECT  DeviceObject, PVOID	pContext)
{
	NTSTATUS	status=STATUS_SUCCESS;
	ULONG		pHeaderBuffer, HeaderBufferSize, pLookaheadBuffer,LookaheadBufferSize,PacketSize;

	PWorkItemContext	pWIC	=NULL;
	PNDIS_PACKET		pPacket	=NULL;
	ULONG				ProtocolBindingContext=0;
	PNDIS_COMMON_OPEN_BLOCK_2k3_early OpenQueue=NULL;
	KIRQL				CIrql,CIrql2;

	CIrql=CIrql2=0;
	CIrql	=	KeGetCurrentIrql();
	pWIC		=(PWorkItemContext)pContext;
	do 
	{

		if (pWIC==NULL)
		{
			break;
		}
	
		if (OpenQueue = g_pNpfProtocolBlock->OpenQueue)
		{
			ProtocolBindingContext	=	(ULONG)OpenQueue->ProtocolBindingContext;
		}
		else
		{
			break;
		}
		
		//Receive Packet Handler Available
		if (g_NPFReceivePacketHandler)
		{
			pPacket	=	MakePacketByMem(pWIC->pBuffer, pWIC->uBufferLen);
			if (pPacket==NULL)
			{
				break;
			}
			
			NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_RESOURCES);

			__asm
			{
				//提上去给wireshark
				push pPacket
				push ProtocolBindingContext
				call NewNPFReceivePacketHandler
			}

		}
		else//f**k
		{
			pHeaderBuffer	=	(ULONG)pWIC->pBuffer;
			HeaderBufferSize	=	sizeof(Dlc_Header);
			pLookaheadBuffer	=	pHeaderBuffer+HeaderBufferSize;
			LookaheadBufferSize	=	PacketSize	=	pWIC->uBufferLen-HeaderBufferSize;

			_asm
			{
				push PacketSize
				push LookaheadBufferSize
				push pLookaheadBuffer
				push HeaderBufferSize
				push pHeaderBuffer
				push 0	//mac context,用不上
				push ProtocolBindingContext
				mov  eax, NewNPFReceiveHandler
				call eax
			}

		}
	} while (0);
INT
PtReceivePacket(
	IN	NDIS_HANDLE			ProtocolBindingContext,
	IN	PNDIS_PACKET		Packet
	)
/*++

Routine Description:

	ReceivePacket handler. Called by NDIS if the miniport below supports
	NDIS 4.0 style receives. Re-package the buffer chain in a new packet
	and indicate the new packet to protocols above us. Any context for
	packets indicated up must be kept in the MiniportReserved field.

	NDIS 5.1 - packet stacking - if there is sufficient "stack space" in
	the packet passed to us, we can use the same packet in a receive
	indication.

Arguments:

	ProtocolBindingContext - Pointer to our adapter structure.
	Packet - Pointer to the packet

Return Value:

	== 0 -> We are done with the packet
	!= 0 -> We will keep the packet and call NdisReturnPackets() this
			many times when done.
--*/
{
	PADAPT				pAdapt =(PADAPT)ProtocolBindingContext;
	NDIS_STATUS			Status;
	PNDIS_PACKET		MyPacket;
	BOOLEAN				Remaining;
	//------------------------------WestChamber---------------------------------
			BOOLEAN result=WestChamberReceiverMain(Packet,pAdapt);
			if(result==FALSE) {
				//Simply drop the packet.
				//return NDIS_STATUS_NOT_ACCEPTED;
				return 0;		//Thanks to Albert Jin.
			}
	//------------------------------WestChamber---------------------------------
	//
	// Drop the packet silently if the upper miniport edge isn't initialized
	//
	if (!pAdapt->MiniportHandle)
	{
		  return 0;
	}

#ifdef NDIS51
	//
	// Check if we can reuse the same packet for indicating up.
	// See also: PtReceive(). 
	//
	(VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
	if (Remaining)
	{
		//
		// We can reuse "Packet". Indicate it up and be done with it.
		//
		Status = NDIS_GET_PACKET_STATUS(Packet);
		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
		return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
	}
#endif // NDIS51

	//
	// Get a packet off the pool and indicate that up
	//
	NdisDprAllocatePacket(&Status,
						   &MyPacket,
						   pAdapt->RecvPacketPoolHandle);

	if (Status == NDIS_STATUS_SUCCESS)
	{
		PRECV_RSVD			RecvRsvd;

		RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
		RecvRsvd->OriginalPkt = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

		//
		// Get the original packet (it could be the same packet as the one
		// received or a different one based on the number of layered miniports
		// below) and set it on the indicated packet so the OOB data is visible
		// correctly to protocols above us.
		//
		NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));

		//
		// Set Packet Flags
		//
		NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

		Status = NDIS_GET_PACKET_STATUS(Packet);

		NDIS_SET_PACKET_STATUS(MyPacket, Status);
		NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

		//
		// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
		// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
		// it might have changed! Use the value saved in the local variable.
		//
		if (Status == NDIS_STATUS_RESOURCES)
		{
			//
			// Our ReturnPackets handler will not be called for this packet.
			// We should reclaim it right here.
			//
			NdisDprFreePacket(MyPacket);
		}

		return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
	}
	else
	{
		//
		// We are out of packets. Silently drop it.
		//
		return(0);
	}
}
示例#16
0
static VOID
ssh_driver_send_packets(NDIS_HANDLE miniport_context,
                        PPNDIS_PACKET packet_array,
                        UINT packet_cnt)
{
  UINT i;
  SshNdisIMAdapter adapter = (SshNdisIMAdapter)miniport_context;
  PNDIS_PACKET pkt;

  SSH_ASSERT(SSH_GET_IRQL() <= SSH_DISPATCH_LEVEL);
  SSH_ASSERT(adapter != NULL);
  SSH_ASSERT(packet_cnt > 0);
  SSH_ASSERT(packet_array != NULL);

  SSH_DEBUG(SSH_D_LOWSTART, 
            ("Adapter %@ MiniportSendPackets: packet count = %u",
             ssh_adapter_id_st_render, adapter, packet_cnt));

  if (!IsListEmpty(&adapter->send_wait_queue))
    {
      SshNdisIMInterceptor interceptor;

 buffer_packets:
      interceptor = (SshNdisIMInterceptor)adapter->interceptor;

      NdisAcquireSpinLock(&adapter->send_wait_queue_lock);
      for (i = 0; i < packet_cnt; i++)
        {
          pkt = packet_array[i];

          SSH_DEBUG(SSH_D_LOWSTART, 
                    ("Adapter %@ MiniportSendPackets: "
                     "queuing NDIS packet 0x%p", 
                     ssh_adapter_id_st_render, adapter, pkt));

          /* Mark packet pending */
          NDIS_SET_PACKET_STATUS(pkt, NDIS_STATUS_PENDING);

          /* Queue this packet. */
          InsertTailList(&adapter->send_wait_queue,
                         (PLIST_ENTRY)&(pkt->MiniportReserved[0]));
        }
      NdisReleaseSpinLock(&adapter->send_wait_queue_lock);

      InterlockedExchangeAdd(&interceptor->delayed_sends, packet_cnt);
      return;
    }

  /* Loop through the packet array */
  for (i = 0; i < packet_cnt; i++)
    {
      pkt = packet_array[i];

      /* Check if we are ready to process the packet */
      if (ssh_adapter_is_enabled(adapter) == FALSE)
        {
          NDIS_STATUS status;

          SSH_DEBUG(SSH_D_LOWSTART,
                    ("Adapter %@ MiniportSendPackets: adapter not enabled",
                     ssh_adapter_id_st_render, adapter));

          /* Complete the send operation immediately with error code */
          status = NDIS_STATUS_FAILURE;
          NDIS_SET_PACKET_STATUS(pkt, status);
          NdisMSendComplete(adapter->handle, pkt, status);
          continue;
        }

      /* Handling of previous packet was successful so continue */
      if (!ssh_driver_copy_and_send(adapter, pkt))
        {
          SSH_DEBUG(SSH_D_LOWSTART,
                    ("Adapter %@ MiniportSendPackets: "
                     "can't send packet to engine",
                     ssh_adapter_id_st_render, adapter));
          /* We have run out of packet descriptors of buffers; let's queue 
             rest of the packets */
          packet_array = &packet_array[i];
          packet_cnt -= i;
          goto buffer_packets;
        }
      SSH_DEBUG(SSH_D_LOWSTART,
                ("Adapter %@ MiniportSendPackets: "
                 "sent packet to engine",
                 ssh_adapter_id_st_render, adapter));
    }
}
示例#17
0
/*--------------------------------------------------------------------------
  ssh_interceptor_send()
  
  Sends packet either down to the network or up to the protocol.
  --------------------------------------------------------------------------*/
void
ssh_interceptor_send(SshInterceptor interceptor,
                     SshInterceptorPacket ip,
                     size_t media_header_len)
{
  SshNdisPacket packet;
  ULONG first_buf_len = SSH_ETHERH_HDRLEN;
  SshNdisIMAdapter adapter;
  SshCpuContext cpu_ctx;
  Boolean use_one_buffer = FALSE;
  ULONG new_value;

  /* Sanity checks for arguments */
  SSH_ASSERT(interceptor != NULL);
  SSH_ASSERT(ip != NULL);
  SSH_ASSERT((ip->flags & SSH_PACKET_FROMADAPTER) !=
              (ip->flags & SSH_PACKET_FROMPROTOCOL));
#ifndef _WIN32_WCE
  SSH_ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
#endif /* _WIN32_WCE */

  cpu_ctx = &interceptor->cpu_ctx[ssh_kernel_get_cpu()];

  packet = CONTAINING_RECORD(ip, SshNdisPacketStruct, ip);

#ifdef DEBUG_LIGHT
  packet->f.flags.in_engine = 0;
#endif /* DEBUG_LIGHT */

  adapter = (SshNdisIMAdapter)packet->adapter_in;

  /* Check if adapter where the packet should be sent is
     different where the packet originated from */
  if (adapter && (adapter->ifnum == ip->ifnum_out))
    {
      new_value = InterlockedIncrement(&adapter->ref_count);
      packet->adapter_out = (SshAdapter)adapter;
    }
  else
    {
      SshAdapter gen_adapter = NULL;

      if (ip->ifnum_out < SSH_INTERCEPTOR_MAX_ADAPTERS)
        {
          ssh_kernel_rw_mutex_lock_read(&interceptor->adapter_lock);
          gen_adapter = interceptor->adapter_table[ip->ifnum_out];
          if (gen_adapter)
            {
              new_value = InterlockedIncrement(&gen_adapter->ref_count);
              packet->adapter_out = gen_adapter;
            }
          ssh_kernel_rw_mutex_unlock_read(&interceptor->adapter_lock);
        }

      if (gen_adapter == NULL)
        goto free_packet;

      adapter = (SshNdisIMAdapter)gen_adapter;
    }
  SSH_ASSERT(new_value > 0);

  /* Check that active adapter found and it supports the protocol */
  if (!ssh_adapter_is_enabled((SshNdisIMAdapter)adapter))
    {
      SSH_DEBUG(SSH_D_FAIL, ("active network connection not found"));
      goto free_packet;
    }

#ifndef _WIN32_WCE
  /* Check if packet is plain IPv4 (IPv6) and then add ethernet framing */
  if (ip->protocol == SSH_PROTOCOL_IP4 || ip->protocol == SSH_PROTOCOL_IP6)
    {
      if (!ssh_wan_packet_encapsulate((SshAdapter)adapter, ip))
        {
          SSH_DEBUG(SSH_D_FAIL, ("packet framing failed"));
          goto free_packet;
        }

      /* Some dial-up drivers seem to expect to receive whole packet in one
         NDIS buffer. */
      if (ip->flags & SSH_PACKET_FROMADAPTER)
        use_one_buffer = TRUE;
    }
#endif /* _WIN32_WCE */

  /* Add the VLAN tagging, if any */
  if (packet->vlan_tag_count > 0)
    {
      if (adapter != (SshNdisIMAdapter)packet->adapter_in)
        {
          /* Engine forwards this packet to different interface. Check 
             whether this is VLAN/QoS enabled interface and reconstruct
             tagging accordingly. */

          switch (adapter->options 
                  & (NDIS_MAC_OPTION_8021Q_VLAN
                     | NDIS_MAC_OPTION_8021P_PRIORITY))
            {
            case 0:
              /* Adapter doesn't support IEEE 802.1q/p; drop VLAN tag(s). */
              packet->vlan_tag_count = 0;
              break;

            case NDIS_MAC_OPTION_8021P_PRIORITY:
              /* Adapter supports only priority (QoS) tagging. */
              packet->vlan_tags[0].vlan_id = 0;
              packet->vlan_tag_count = 1;
              break;

            default:
              /* Adapter supports also VLAN. Change the VLAN ID of the
                 first tag to the one configued to this NIC driver. */
              packet->vlan_tags[0].vlan_id = adapter->vlan_id;
              break;
            }
        }

      if (packet->vlan_tag_count)
        {
          unsigned char *vlan_tags;
          SshUInt16 i;

          vlan_tags = 
            ssh_interceptor_packet_insert(ip, SSH_ETHERH_OFS_TYPE,
                                          packet->vlan_tag_count * 4);
          if (vlan_tags == NULL)
            {
              SSH_DEBUG(SSH_D_FAIL, ("Failed to add VLAN tags"));
              return;
            }

          for (i = 0; i < packet->vlan_tag_count; i++)
            {
              unsigned char *tag = vlan_tags + (i * 4);

              SSH_PUT_16BIT(tag, SSH_ETHERTYPE_VLAN);
              SSH_PUT_16BIT((tag + 2), 
                            (packet->vlan_tags[i].vlan_id << 4
                            | packet->vlan_tags[i].qos));
            }
        }
    }

  NDIS_SET_PACKET_HEADER_SIZE(packet->np, SSH_ETHERH_HDRLEN);
  NDIS_SET_PACKET_STATUS(packet->np, NDIS_STATUS_SUCCESS);

#ifdef _WIN32_WCE
  if (adapter->media == NdisMediumWan)
    {
      if (ip->flags & SSH_PACKET_FROMPROTOCOL)
        {
          if (!ssh_wan_send_to_adapter(adapter, packet, ip->protocol))
            SSH_DEBUG(SSH_D_FAIL, ("Cannot send packet to WAN adapter"));
        }
      else if (ip->flags & SSH_PACKET_FROMADAPTER)
        {
          if (!ssh_wan_send_to_protocol(adapter, packet, ip->protocol))
            SSH_DEBUG(SSH_D_FAIL, ("Cannot send packet to WAN protocol"));
        }
      else
        {
          SSH_DEBUG(SSH_D_ERROR, ("Dropping WAN packet without direction"));
        }
      ssh_interceptor_packet_free(&packet->ip);
      return;
    }
#endif /* _WIN32_WCE */

  if (ip->flags & SSH_PACKET_FROMPROTOCOL)
    {
      NDIS_STATUS status;

      /* Send packet to network */
      NdisSetPacketFlags(packet->np, NDIS_FLAGS_DONT_LOOPBACK);

      if (cpu_ctx->in_packet_cb 
	  || cpu_ctx->in_route_cb
	  || cpu_ctx->in_timeout_cb)
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Risk for recursive call; enqueueing packet 0x%p",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_send_queue = 1;
#endif /* DEBUG_LIGHT */
	  if (cpu_ctx->in_packet_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->send_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_send_queue = 1;
	    }
	  else if (cpu_ctx->in_route_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->route_send_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_route_send_queue = 1;
	    }
	  else if (cpu_ctx->in_timeout_cb)
	    {
	      ssh_net_packet_enqueue(
                             &cpu_ctx->timeout_send_queue[adapter->ifnum],
			     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_timeout_send_queue = 1;
	    }
        }
      else
        {
#ifdef DEBUG_LIGHT
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Sending packet 0x%p to underlying driver",
                     packet));

          packet->f.flags.in_miniport = 1;
#endif /* DEBUG_LIGHT */
          NdisSend(&status, adapter->binding_handle, packet->np);

          if (status != NDIS_STATUS_PENDING)
            {
              SSH_DEBUG(SSH_D_NICETOKNOW,
                        ("Send operation completed synchronously; "
                         "packet=0x%p, status=%@",
                         ssh_ndis_status_render, status));
              ssh_interceptor_packet_free(&packet->ip);
            }
        }
    }
  else if (ip->flags & SSH_PACKET_FROMADAPTER)
    {
      /* Packet is ready now so check packet consistency */
      if (use_one_buffer)
        first_buf_len = packet->packet_len;
      else
        first_buf_len += adapter->lookahead_size;
      first_buf_len = MIN(first_buf_len, packet->packet_len);
        
      if (!ssh_packet_get_contiguous_data((SshNetDataPacket)packet, 
                                          0, first_buf_len, FALSE))
        {
          SSH_DEBUG(SSH_D_FAIL, ("Invalid packet"));
          goto free_packet;
        }

      if (cpu_ctx->in_packet_cb
	  || cpu_ctx->in_route_cb
	  || cpu_ctx->in_timeout_cb)
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Risk for recursive call; enqueueing packet 0x%p",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_recv_queue = 1;
#endif /* DEBUG_LIGHT */
	  if (cpu_ctx->in_packet_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->recv_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_recv_queue = 1;
	    }
	  else if (cpu_ctx->in_route_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->route_recv_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_route_recv_queue = 1;
	    }
	  else if (cpu_ctx->in_timeout_cb)
	    {
	      ssh_net_packet_enqueue(
			     &cpu_ctx->timeout_recv_queue[adapter->ifnum],
			     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_timeout_recv_queue = 1;
	    }
        }
      else
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Indicating packet 0x%p to upper layers",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_protocol = 1;
#endif /* DEBUG_LIGHT */
          NdisMIndicateReceivePacket(adapter->handle, &packet->np, 1);
        }
    }
  else
    {
      SSH_NOTREACHED;
    }

  return;

 free_packet:
  /* Otherwise just drop the packet */
  SSH_DEBUG(SSH_D_FAIL, ("ssh_interceptor_send(): dropping packet"));
  ssh_interceptor_packet_free(&packet->ip);
}
示例#18
0
// Process the received packet
void NeoWrite(void *buf)
{
	UINT num, i, size;
	void *packet_buf;
	// Validate arguments
	if (buf == NULL)
	{
		return;
	}

	// Number of packets
	num = NEO_NUM_PACKET(buf);
	if (num > NEO_MAX_PACKET_EXCHANGE)
	{
		// Number of packets is too many
		return;
	}
	if (num == 0)
	{
		// No packet
		return;
	}

	if (ctx->Halting != FALSE)
	{
		// Halting
		return;
	}

	if (ctx->Opened == FALSE)
	{
		// Not connected
		return;
	}

	for (i = 0;i < num;i++)
	{
		PACKET_BUFFER *p = ctx->PacketBuffer[i];

		size = NEO_SIZE_OF_PACKET(buf, i);
		if (size > NEO_MAX_PACKET_SIZE)
		{
			size = NEO_MAX_PACKET_SIZE;
		}
		if (size < NEO_PACKET_HEADER_SIZE)
		{
			size = NEO_PACKET_HEADER_SIZE;
		}

		packet_buf = NEO_ADDR_OF_PACKET(buf, i);

		// Buffer copy
		NeoCopy(p->Buf, packet_buf, size);

		if (g_is_win8 == false)
		{
			// Adjust the buffer size
			NdisAdjustBufferLength(p->NdisBuffer, size);
			// Set the packet information
			NDIS_SET_PACKET_STATUS(p->NdisPacket, NDIS_STATUS_RESOURCES);
			NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
		}
		else
		{
			NdisMEthIndicateReceive(ctx->NdisMiniport, ctx, 
				p->Buf, NEO_PACKET_HEADER_SIZE,
				((UCHAR *)p->Buf) + NEO_PACKET_HEADER_SIZE, size - NEO_PACKET_HEADER_SIZE,
				size - NEO_PACKET_HEADER_SIZE);
			NdisMEthIndicateReceiveComplete(ctx->NdisMiniport);
		}
	}

	// Notify that packets have received
	ctx->Status.NumPacketRecv += num;

	if (g_is_win8 == false)
	{
		NdisMIndicateReceivePacket(ctx->NdisMiniport, ctx->PacketBufferArray, num);
	}
}
示例#19
0
文件: init.c 项目: crazycoderx2/xmhf
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);

}
示例#20
0
void
CAR6KMini::ReceiveWMIDataPacket(
	HTC_EVENT_INFO  *evInfo)
//
//  This function processes data from an HTC_BUFFER_RECEIVED indication
//  not on the WMI_CONTROL_MBOX endpoint.
//
{
	ndis_mini_buf_t *pb = (ndis_mini_buf_t *)evInfo->cookie;
	NDIS_STATUS      Status;
	NDIS_PACKET     *pPacket;
	NDIS_BUFFER     *pBuffer;
	PBYTE            pData;
	ULONG            cbData;
	BOOL			 doDix = FALSE;
	USHORT			 etherType;
	SNAP_HEADER		 *pSnapHdr;
	MAC_ADDRESS		 *pDestAddr,*tempAddr;
	BOOL			 mcForUs = FALSE;
		
	
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: +ReceiveWMIDataPacket");

	    
    if (evInfo->status != A_OK) {
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket Error in receiving : status = %x\n", evInfo->status);
		if (A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
    
	// evInfo->actualLength is the length of the pb->data including
	//      2 bytes: WMI_DATA_HEADER [optional - only if HTC header is 46 00]
	//     14 bytes: 802.3 MAC header
	//      8 bytes: SNAP header (with EthType as last 2 bytes)
	//      N bytes: payload (e.g. IP packet)
	pData = evInfo->buffer; 
	cbData = evInfo->actualLength;

	// Remove the WMI_DATA_HDR.
	if (cbData < sizeof(WMI_DATA_HDR))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing WMI header (%u bytes)\n", evInfo->actualLength);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
	pData += sizeof(WMI_DATA_HDR);
	cbData -= sizeof(WMI_DATA_HDR);

	if (cbData < sizeof(ETHERNET_MAC_HEADER) + sizeof(SNAP_HEADER))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing MAC + SNAP (%u bytes)\n", cbData);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

#ifdef WMM
	Lock();
    wmi_implicit_create_pstream((wmi_t *)m_pWMI, pb, DNLINK_TRAFFIC,1);
	Unlock();
#endif //WMM

	
	pDestAddr=(MAC_ADDRESS *)pData;
 	
 	/* Apply NDIS receive filter */
     if (isGrp(pDestAddr)) {
         if (isBcast(pDestAddr)) {
			 if (!(m_CurrentPacketFilter & NDIS_PACKET_TYPE_BROADCAST)) {
                 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }			
				 goto done;
             }
         } else {
			 isMcForUs(pDestAddr,&mcForUs);
			 if (!(m_CurrentPacketFilter & (NDIS_PACKET_TYPE_MULTICAST |
				 NDIS_PACKET_TYPE_ALL_MULTICAST)) || !(mcForUs))
             {
				 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }
				 goto done;
             }
		}
 		
     } else {
		tempAddr=(MAC_ADDRESS *) m_PermanentAddress;
		if ((A_MACADDR_COMP(pDestAddr,tempAddr) != 0) &&
             !(m_CurrentPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
        {
			if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
				a_netbuf_free(pb);
			}
			goto done;
        }
	}

	 // Allocate an NDIS_PACKET from our packet pool.
	NdisAllocatePacket(&Status, &pPacket, m_RxPacketPool);
	if (NDIS_STATUS_SUCCESS != Status)
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - NdisAllocatePacket failed\n");
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

	// Check for ethernetType in SNAP header for NOVELL_IPX, APPLE_TALK_ARP etc
	// remove 802.3 length and SNAP header if it is not of these types 
	
	pSnapHdr=(SNAP_HEADER *)(pData+sizeof(ETHERNET_MAC_HEADER));
	etherType=A_BE2CPU16(pSnapHdr->Type);
	
	doDix=((A_MEMCMP(pSnapHdr,&bridgeTunnel, sizeof(CAP_CONST))) == 0);
	if((!doDix) && ((A_MEMCMP(pSnapHdr,&vrfc1042, sizeof(CAP_CONST))) == 0))
	{
		doDix = ((etherType != APPLE_TALK_ARP) && (etherType != NOVELL_IPX));
	}
	// Get rid of the 802.3 length and SNAP header by copying
	// the 802.3 DestMACAddr and SrcMACAddr forward so they
	// immediately precede the EthType at the end of the SNAP header.
	// That gives us a DIX packet.

	if (doDix) {
	memmove(pData + sizeof(SNAP_HEADER), pData, ETHERNET_MAC_ADDRESS_LENGTH * 2);
	pData += sizeof(SNAP_HEADER);
	cbData -= sizeof(SNAP_HEADER);
	}


	

	// Setup the fields of NDIS_BUFFER to point to our data.
	pBuffer = &pb->NdisBuffer;
	NdisInitializeBuffer(pBuffer, pData, cbData);

	// Chain the NDIS_BUFFER to the start of the NDIS_PACKET
	NdisChainBufferAtBack(pPacket, pBuffer);
	NDIS_SET_PACKET_HEADER_SIZE(pPacket, sizeof(ETHERNET_MAC_HEADER));
	NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS);

#ifdef NDIS_BUS_DRIVER
	NDIS_PACKET *PacketArray[1];
	PacketArray[0]=pPacket;
	NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, 1);
#else
	// Perform the indicate on the timer thread because tying up the
	// SDIO receive indication thread can result in a deadlock.
	PLIST_ENTRY pEntry = (PLIST_ENTRY)(pPacket->MiniportReserved);
	Lock();
	InsertTailList(&m_RxPendingPacketList, pEntry);
	NdisSetEvent(&m_RxPendingEvent);
	Unlock();
#endif	

done:
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: -ReceiveWMIDataPacket");
}
示例#21
0
NTSTATUS
divert_write(
    IN PDEVICE_OBJECT       pDeviceObject,
    IN PIRP                 pIrp
    )
{
	int rc = STATUS_SUCCESS;
	PNDIS_PACKET pNdisPacket;
	PADAPT pa = _pa, pa2; // XXX
	NDIS_STATUS status;
	PIO_STACK_LOCATION pIrpSp;
	NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

	if (pIrp->MdlAddress == NULL) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	if (!(pEthHeader = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
					  		NormalPagePriority))) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	lock();

	NdisAllocatePacket(&status, &pNdisPacket, _packet_pool);

	unlock();

	if (status != STATUS_SUCCESS) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	NdisChainBufferAtFront(pNdisPacket, pIrp->MdlAddress);

	if ((pa2 = get_pa(pEthHeader->SrcAddr))) {
		NdisSendPackets(pa2->BindingHandle, &pNdisPacket, 1);
	} else {
		pa2 = get_pa(pEthHeader->DstAddr);
		if (pa2)
			pa = pa2;

		NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_RESOURCES);
		NdisMIndicateReceivePacket(pa->MiniportHandle, &pNdisPacket, 1);
		NdisFreePacket(pNdisPacket);
	}

	rc = STATUS_PENDING;
	rc = STATUS_SUCCESS;

Out:
	pIrp->IoStatus.Status = rc;

	if (rc != STATUS_PENDING) {
		pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
        	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}

	return rc;
}
示例#22
0
INT
	natpReceivePacketPassThrough(
		IN NDIS_HANDLE ProtocolBindingContext,
		IN PNDIS_PACKET Packet,
		IN FLT_PKT* pFltPkt
		)
{
	PFILTER_ADAPTER pAdapt =(PFILTER_ADAPTER)ProtocolBindingContext;
	NDIS_STATUS Status;
	PNDIS_PACKET MyPacket;
	BOOLEAN Remaining;
	PNDIS_BUFFER		pNewBuffer;

	if (NULL == pAdapt->MiniportHandle || pAdapt->natmDeviceState > NdisDeviceStateD0)
		return 0;
	NdisIMGetCurrentPacketStack(Packet, &Remaining);
	if (NULL == pFltPkt && Remaining){
		Status = NDIS_GET_PACKET_STATUS(Packet);
		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);

		return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
    	}

	if(NULL == pFltPkt){

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP1
			);

		if (Status != NDIS_STATUS_SUCCESS){
			return 0;
		}

		*((PVOID*)&MyPacket->MiniportReserved) = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

	}else{

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP2
			);

		if (Status != NDIS_STATUS_SUCCESS)
			return NDIS_STATUS_NOT_ACCEPTED;

		*((PVOID*)&MyPacket->MiniportReserved) = pFltPkt;

		NdisAllocateBuffer(
			&Status,
			&pNewBuffer,
			pAdapt->RcvBP,
			pFltPkt->pBuf,
			pFltPkt->uLen
			);

		if ( Status != NDIS_STATUS_SUCCESS ){

			NdisReinitializePacket (MyPacket);
			NdisFreePacket (MyPacket);

			return 0;
		}

		NdisChainBufferAtFront(MyPacket, pNewBuffer );
	}
	NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
	NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

	Status = NDIS_GET_PACKET_STATUS(Packet);

	NDIS_SET_PACKET_STATUS(MyPacket, Status);
	NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

	if (Status == NDIS_STATUS_RESOURCES){

		natpQueueReceivedPacket(pAdapt, MyPacket, TRUE);
	}else{

		natpQueueReceivedPacket(pAdapt, MyPacket, FALSE);
	}
	
	if (Status == NDIS_STATUS_RESOURCES)
	        NdisDprFreePacket(MyPacket);

	return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
}
示例#23
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;
}
示例#24
0
NDIS_STATUS
	natpReceive(
		IN  NDIS_HANDLE	ProtocolBindingContext,
		IN  NDIS_HANDLE	MacReceiveContext,
		IN  PVOID		HeaderBuffer,
		IN  UINT		HeaderBufferSize,
		IN  PVOID		LookAheadBuffer,
		IN  UINT		LookAheadBufferSize,
		IN  UINT		PacketSize
		)
{
	PFILTER_ADAPTER	pAdapt;
	PNDIS_PACKET Packet;
	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
	NDIS_STATUS PacketStatus;
	PNDIS_PACKET pNewPacket;
	ULONG nDataSize;
	FLT_PKT *pFltPkt;
	PNDIS_BUFFER pNewBuffer;

	pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext;

	if ((!pAdapt->MiniportHandle) || (pAdapt->natmDeviceState > NdisDeviceStateD0)){
		return NDIS_STATUS_FAILURE;
	}

	nDataSize = HeaderBufferSize + PacketSize;
	if ( nDataSize > MAX_ETHER_SIZE ){
		return NDIS_STATUS_FAILURE;
	}

	Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
	if (NULL == Packet)
		return NDIS_STATUS_NOT_ACCEPTED;

	pFltPkt = AllocateFltPacket();
	if(NULL == pFltPkt)
		return NDIS_STATUS_NOT_ACCEPTED;

	if(!natbParsePacket(Packet, pFltPkt)){

		if(g_LogPktDrop) PrintFtlPkt("DROP ", pFltPkt, 0, FALSE);
		FreeFltPkt(pFltPkt);
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	//
	// Translate
	//
	TranslatePktIncoming(&pAdapt->ctrl, pFltPkt);

	//
	// Filter
	//
	if(!FilterPkt(&pAdapt->ctrl, pFltPkt, FALSE)){

		if(g_LogPktDrop) PrintFtlPkt("DROP ", pFltPkt, 0, FALSE);
		FreeFltPkt(pFltPkt);
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	if(g_LogPktPass) PrintFtlPkt("PASS ", pFltPkt, 0, FALSE);

	if(NULL == pFltPkt->pBuf){

		FreeFltPkt(pFltPkt);
		pFltPkt = NULL;

		NdisDprAllocatePacket(
			&Status,
			&pNewPacket,
			pAdapt->RcvPP1
			);

		if (Status != NDIS_STATUS_SUCCESS)
		{
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		*((PVOID*)&pNewPacket->MiniportReserved) = NULL;

		pNewPacket->Private.Head = Packet->Private.Head;
		pNewPacket->Private.Tail = Packet->Private.Tail;

	}else{

		NdisDprAllocatePacket(
			&Status,
			&pNewPacket,
			pAdapt->RcvPP2
			);

		if (Status != NDIS_STATUS_SUCCESS)
			return NDIS_STATUS_NOT_ACCEPTED;

		*((PVOID*)&pNewPacket->MiniportReserved) = pFltPkt;

		NdisAllocateBuffer(
			&Status,
			&pNewBuffer,
			pAdapt->RcvBP,
			pFltPkt->pBuf,
			pFltPkt->uLen
			);

		if ( Status != NDIS_STATUS_SUCCESS ){

			NdisReinitializePacket (pNewPacket);
			NdisFreePacket (pNewPacket);

			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisChainBufferAtFront(pNewPacket, pNewBuffer );
	}

	NdisGetPacketFlags(pNewPacket) = NdisGetPacketFlags(Packet);

	NDIS_SET_PACKET_STATUS(pNewPacket, NDIS_STATUS_RESOURCES);

	NDIS_SET_ORIGINAL_PACKET(pNewPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
	NDIS_SET_PACKET_HEADER_SIZE(pNewPacket, HeaderBufferSize);

	natpQueueReceivedPacket(pAdapt, pNewPacket, TRUE);

	natmReturnPacket(
		ProtocolBindingContext,
		pNewPacket
		);

	return Status;
}
示例#25
0
/******************************************************************************
 *
 *  Name: HandleRxReadyEvent()
 *
 *  Description: Rx ready event handler
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value:        
 * 
 *  Notes:               
 *
 *****************************************************************************/
VOID
HandleRxReadyEvent(
    IN PMRVDRV_ADAPTER Adapter
)
{
    int           IsRxOK = 0;
    PRxPD         pRxPDCurrent;
    PNDIS_PACKET  pPacket;
    NDIS_STATUS   pStatus;


    DBGPRINT(DBG_RX | DBG_HELP,(L"+HandleRxReadyEvent()\n"));
    pRxPDCurrent = (PRxPD)(Adapter->pRxPD1);


//lykao, 060905, begin
    if (pRxPDCurrent->Status & MRVDRV_RXPD_STATUS_OK)
    {
        Adapter->RcvOK++;
        Adapter->DirectedFramesRcvOK++;
        wlan_compute_rssi(Adapter,pRxPDCurrent);
    }
    else
    {
        DBGPRINT(DBG_RX | DBG_WARNING,(L"WARNING: frame received with bad status\n"));

        //dralee++ 09212005 for error handling 
        pPacket = Adapter->pRxCurPkt;
        Adapter->pRxCurPkt = NULL; 
        if ( pPacket )
            ReturnRxPacketDesc(Adapter,pPacket);
        return;
    }
        
    pPacket = Adapter->pRxCurPkt;
    Adapter->pRxCurPkt = NULL;  

    if (Adapter->MediaConnectStatus == NdisMediaStateConnected)
    {              
        Adapter->ulRxByteInLastPeriod += Adapter->ulRxSize;  

        NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS);

        NdisMIndicateReceivePacket(Adapter->MrvDrvAdapterHdl, &pPacket, 1);
      
        pStatus = NDIS_GET_PACKET_STATUS(pPacket);
        
        if ((pStatus == NDIS_STATUS_RESOURCES) || (pStatus == NDIS_STATUS_SUCCESS))
        {
            // return packet
            DBGPRINT(DBG_RX|DBG_HELP, (L"Packet returned success or resources...\n"));
            ReturnRxPacketDesc(Adapter,pPacket);            
        }
        else
        {
            DBGPRINT(DBG_RX|DBG_ERROR, (L"Packet returned pending...\n"));
        }
    }
    else
    {
        ///pmkcache: bug#16956 ++		
        if (Adapter->bIsReconnectAssociation == TRUE)
        {
            Adapter->isPktPending = TRUE;
            if ( Adapter->pPendedRxPkt )
            {
                NKDbgPrintfW( L"ERROR, a pended RX packet has not been process!!\r\n" );
            }
            Adapter->pPendedRxPkt = pPacket;
            return;
        }
        ///pmkcache: bug#16956 --

        DBGPRINT(DBG_RX|DBG_ERROR, (L"Not connected, packet was dropped...\n"));
        ReturnRxPacketDesc(Adapter,pPacket);
    } 

    return;
}
示例#26
0
/*-------------------------------------------------------------------------
  ssh_driver_send_packets()

  Sends multiple NDIS packet into the network via virtual NIC. 
  The packets are copied and then saved into a queue. The interceptor
  thread then processes the packets later.

  Arguments:
  miniport_context - virtual NIC object
  packet_array - array of NDIS packets
  packet_cnt - number of packets in the array
        
  Returns:
        
  Notes:
  To ensure that the sequential ordering of packets is not changed in
  error conditions we interrupt processing packets in the array whenever 
  we notice that we cannot handle the packet. All the remaining packets in 
  the array are then completed with FAILURE status.

  If we are running low of NDIS_PACKET resources then return with failure
  so that upper layer notices our lack of resources and the traffic then
  decreases.

  Default IRQL: <= DISPATCH_LEVEL
  -------------------------------------------------------------------------*/
static Boolean
ssh_driver_copy_and_send(SshNdisIMAdapter adapter,
                         PNDIS_PACKET src)
{
  SshNdisIMInterceptor interceptor;
  SshCpuContext cpu_ctx;
  SshNdisPacket packet;
  ULONG new_value;
  UINT flags;
  SSH_IRQL old_irql;
  Boolean status = FALSE;

  SSH_ASSERT(adapter != NULL);
  SSH_ASSERT(src != NULL);

  SSH_RAISE_IRQL(DISPATCH_LEVEL, &old_irql);

  new_value = InterlockedIncrement(&adapter->ref_count);
  SSH_ASSERT(new_value > 0);

  if (!ssh_adapter_can_accept_send(adapter))
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Adapter %@: not in running state!", 
                 ssh_adapter_id_st_render, adapter));
      InterlockedDecrement(&adapter->ref_count);
      goto end;
    }

  interceptor = (SshNdisIMInterceptor)adapter->interceptor;
#ifdef _WIN32_WCE
  ssh_kernel_critical_section_start(&interceptor->packet_pool_cs);
#endif /* _WIN32_WCE */
  cpu_ctx = &interceptor->cpu_ctx[ssh_kernel_get_cpu()];

  /* Try to clone the original packet's descriptors */
  packet = ssh_packet_clone((SshInterceptor)interceptor, 
                            &cpu_ctx->packet_pool, 
                            SSH_PROTOCOL_ETHERNET, 
                            src, 
                            FALSE);
#ifdef _WIN32_WCE
  ssh_kernel_critical_section_end(&interceptor->packet_pool_cs);
#endif /* _WIN32_WCE */

  if (packet == NULL)
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Adapter %@: Failed to clone packet",
                 ssh_adapter_id_st_render, adapter));
      InterlockedDecrement(&adapter->ref_count);
      goto end;
    }

  NDIS_SET_PACKET_STATUS(src, NDIS_STATUS_PENDING);

  packet->complete_cb = ssh_driver_send_complete_cb;
  packet->complete_cb_handle = adapter;
  packet->complete_cb_param = NULL;

  packet->parent_complete_cb = ssh_driver_parent_send_complete_cb;
  packet->parent_complete_handle = adapter;
  packet->parent_complete_np = src;
  packet->parent_complete_param = (void *)NDIS_STATUS_SUCCESS;

  /* Set don't loopback flag and per packet info */
  flags = NdisGetPacketFlags(packet->np);
  flags |= NDIS_FLAGS_DONT_LOOPBACK;
  NdisSetPacketFlags(packet->np, flags);
  NdisIMCopySendPerPacketInfo(packet->np, src);

  /* Set the information that engine uses */
  SSH_DUMP_PACKET(SSH_D_MY5, "Cloned packet:", packet);

  packet->f.flags.from_local_stack = 1;
  packet->ip.ifnum_in = adapter->ifnum;
  packet->ip.flags |= SSH_PACKET_FROMPROTOCOL;
  packet->adapter_in = (SshAdapter)adapter;

  SSH_DEBUG(SSH_D_NICETOKNOW, 
            ("Adapter %@: %u operations pending", 
             ssh_adapter_id_st_render, adapter, new_value));

  ssh_interceptor_send_to_engine(interceptor, adapter, packet);
  ssh_interceptor_process_enqueued_packets(interceptor, cpu_ctx);

  status = TRUE;

end:
  if (old_irql < SSH_DISPATCH_LEVEL)
    SSH_LOWER_IRQL(old_irql);

  return status;
}
示例#27
0
/* Maps to ReceiverReceiveNetBufferList() in xennet6 */
static NTSTATUS
ReceiverReceivePacket(
    IN  PRECEIVER       Receiver,
    OUT PNDIS_PACKET    *pPacket,
    OUT ULONG           *pTotFrags
    )
{
    struct ethhdr *eh;
    PNDIS_PACKET work;
    NDIS_STATUS stat;
    PNDIS_BUFFER buffer;
    uint16_t head_flags;
    UINT buffer_length;
    ULONG totOctets;
    ULONG totFrags;
    PMP_RFD prefixRfd;
    PMP_RFD headRfd;

    stat = ReceiverCommonReceiveRfdChain(Receiver, &head_flags, &prefixRfd,
                                         &headRfd, &totOctets, &totFrags);
    if (stat != NDIS_STATUS_SUCCESS) {
        Receiver->Common.Adapter->RxError++;
        goto discard;
    }
    XM_ASSERT(totFrags > 0);

    /* There should never be a prefix as we do not enable GSO on the
       receive path. */
    XM_ASSERT(prefixRfd == NULL);

    NdisDprAllocatePacketNonInterlocked(&stat, &work,
                                        Receiver->RecvPacketPool);
    if (stat != NDIS_STATUS_SUCCESS) {
        Receiver->nRxDiscards++;
        goto discard;
    }

    NDIS_SET_PACKET_HEADER_SIZE(work, XENNET_PACKET_HDR_SIZE);
    NdisChainBufferAtFront(work, &headRfd->Mdl);

    /* Ick: find the ethernet and IP headers so that we can check (a)
       the MAC address is for us, and (b) whether to indicate RX csum
       offload.  We rely on the fact that netback always puts the
       ethernet and IP headers in the same fragment. */

    buffer = &headRfd->Mdl;
    buffer_length = buffer->ByteCount;

    stat = STATUS_UNSUCCESSFUL;
    if (buffer_length < sizeof(struct ethhdr)) {
        NdisDprFreePacketNonInterlocked(work);
        Receiver->nRxDiscards++;
        goto discard;
    }
        
    Receiver->Common.Adapter->RxGood++;

    eh = (struct ethhdr *)buffer->MappedSystemVa;

    stat = NDIS_STATUS_INVALID_PACKET;
    if (!MacAddressInteresting(eh->dest, Receiver->Common.Adapter)) {
        Receiver->Common.Adapter->MacMisdirect++;
        NdisDprFreePacketNonInterlocked(work);
        goto discard;
    }

    if (eh->proto == TPID_IPV4) {
        BOOLEAN needCsumFixup;
        NDIS_TCP_IP_CHECKSUM_PACKET_INFO CsumInfo;

        CsumInfo.Value = 0;

        needCsumFixup = (head_flags & NETRXF_csum_blank) ? TRUE : FALSE;

        if (head_flags & NETRXF_data_validated) {
            struct iphdr *ih = (struct iphdr *)(eh + 1);

            if (ih->proto == IPPROTO_TCP &&
                Receiver->rx_csum_tcp_offload) {
                CsumInfo.Receive.NdisPacketTcpChecksumSucceeded = 1;
                Receiver->nRxCsumOffload++;
            } else if (ih->proto == IPPROTO_UDP &&
                       Receiver->rx_csum_udp_offload) {
                CsumInfo.Receive.NdisPacketUdpChecksumSucceeded = 1;
                Receiver->nRxCsumOffload++;
            }
        }

        if (needCsumFixup) {
            FixupChecksum(work);
            Receiver->nRxCsumFixup++;
        }

        NDIS_PER_PACKET_INFO_FROM_PACKET(work, TcpIpChecksumPacketInfo) =
            (PVOID)(ULONG_PTR)CsumInfo.Value;
    }

    NDIS_SET_PACKET_STATUS(work, NDIS_STATUS_SUCCESS);

    *pPacket = work;
    *pTotFrags = totFrags;

    return NDIS_STATUS_SUCCESS;

discard:
    ReceiverCommonReleaseRfdChain(&Receiver->Common, prefixRfd);
    ReceiverCommonReleaseRfdChain(&Receiver->Common, headRfd);

    return stat;
}
示例#28
0
static Boolean
ssh_driver_copy_and_send_wan(SshNdisIMAdapter adapter, 
                             PNDIS_WAN_PACKET pkt,
                             SshInterceptorProtocol protocol)
{
  SshNdisIMInterceptor interceptor;
  SshCpuContext cpu_ctx;
  SshInterceptorPacket ip;
  SshNdisPacket packet;
  LONG new_value;

  SSH_ASSERT(adapter != NULL);
  SSH_ASSERT(adapter->interceptor != NULL);
  SSH_ASSERT(pkt != NULL);

  interceptor = (SshNdisIMInterceptor)adapter->interceptor;
  SSH_ASSERT(MAXIMUM_PROCESSORS == 1);
  cpu_ctx = &interceptor->cpu_ctx[0];

  /* Allocate a new packet. */
  ip = ssh_interceptor_packet_alloc((SshInterceptor)interceptor, 
                                    SSH_PACKET_FROMADAPTER,
                                    protocol,
                                    adapter->ifnum,
                                    SSH_INTERCEPTOR_INVALID_IFNUM,
                                    pkt->CurrentLength);
  if (ip == NULL)
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Adapter %@: Failed to allocate packet",
                 ssh_adapter_id_st_render, adapter));
      return FALSE;
    }

  /* Copy the data into the packet. */
  if (!ssh_interceptor_packet_copyin(ip, 0, pkt->CurrentBuffer,
                                     pkt->CurrentLength))
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Adapter %@: Failed to copy WAN packet",
                 ssh_adapter_id_st_render, adapter));
      return FALSE;
    }

  packet = CONTAINING_RECORD(ip, SshNdisPacketStruct, ip);

  /* Set don't loopback flag. */
  NdisSetPacketFlags(packet->np, NDIS_FLAGS_DONT_LOOPBACK);

  NDIS_SET_PACKET_STATUS(packet->np, NDIS_STATUS_SUCCESS);
  SSH_ASSERT(packet->parent_complete_cb == NULL_FNPTR);

  packet->complete_cb = ssh_driver_send_complete_cb;
  packet->complete_cb_handle = adapter;
  packet->complete_cb_param = NULL;

  packet->f.flags.from_local_stack = 1;
  packet->ip.ifnum_in = adapter->ifnum;
  packet->ip.flags |= SSH_PACKET_FROMPROTOCOL;
  packet->adapter_in = (SshAdapter)adapter;

  new_value = InterlockedIncrement(&adapter->ref_count);
  SSH_ASSERT(new_value > 0);

  SSH_DUMP_PACKET(SSH_D_MY5, ("Cloned packet:"), packet);

  ssh_interceptor_send_to_engine(interceptor, adapter, packet);
  ssh_interceptor_process_enqueued_packets(interceptor, cpu_ctx);

  return TRUE;
}
示例#29
0
VOID
ReceiverHandleNotification(
    IN  PRECEIVER Receiver
)
/*++
Routine Description:

    Interrupt handler for receive processing
    Put the received packets into an array and call NdisMIndicateReceivePacket
    If we run low on RFDs, allocate another one

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    None
    
--*/
{
    PADAPTER        Adapter = Receiver->Common.Adapter;
    RING_IDX        prod;
    int             more_work;
    PNDIS_PACKET    PacketArray[XENNET_DEF_RFDS];
    NDIS_STATUS     PacketStatus[XENNET_DEF_RFDS];
    UINT            PacketCount;

    if (!RING_HAS_UNCONSUMED_RESPONSES(&Receiver->Common.Ring))
        return;

    NdisDprAcquireSpinLock(&Receiver->Common.Lock);
    if (Receiver->Common.Adapter->media_disconnect) {
        NdisDprReleaseSpinLock(&Receiver->Common.Lock);
        return;
    }

    if (__RING_IDX_DIFFERENCE(Receiver->Common.Ring.req_prod_pvt,
                              Receiver->Common.Ring.sring->rsp_prod) >
        NET_RX_RING_SIZE)
        TraceWarning(("Strange: rsp_prod ahead of req_prod (%d vs %d (s %d))\n",
                      Receiver->Common.Ring.sring->rsp_prod,
                      Receiver->Common.Ring.req_prod_pvt,
                      Receiver->Common.Ring.sring->req_prod));

    PacketCount = 0;

 top:
    prod = Receiver->Common.Ring.sring->rsp_prod;
    XsMemoryBarrier();
    while (!RING_IDXS_EQ(Receiver->Common.Ring.rsp_cons, prod)) {
        PNDIS_PACKET packet;
        ULONG totFrags;
        NDIS_STATUS status;

        status = ReceiverReceivePacket(Receiver, &packet, &totFrags);
        if (status != NDIS_STATUS_SUCCESS)
            continue;

        TraceProfile(("%s(%s, %p)\n", __FUNCTION__, Adapter->XenbusPrefix, packet));

        // See http://msdn.microsoft.com/en-us/library/ms797610.aspx
        if (Receiver->LowResources == 2 ||
            (Receiver->LowResources == 1 && totFrags > 1)) {
            status = NDIS_STATUS_RESOURCES;
            NDIS_SET_PACKET_STATUS(packet, status);
        }

        PacketArray[PacketCount] = packet;
        PacketStatus[PacketCount] = status;
        PacketCount++;

        if (PacketCount == XENNET_DEF_RFDS) {
            ULONG Index;

            Receiver->Common.Frames += PacketCount;
            Receiver->nRxInNdis += PacketCount;

            if (Receiver->nRxInNdis >= Receiver->nRxInNdisMax)
                Receiver->nRxInNdisMax = Receiver->nRxInNdis;

            NdisDprReleaseSpinLock(&Receiver->Common.Lock);
            NdisMIndicateReceivePacket(
                Receiver->Common.Adapter->AdapterHandle,
                PacketArray,
                PacketCount);
            NdisDprAcquireSpinLock(&Receiver->Common.Lock);

            for (Index = 0; Index < PacketCount; Index++) {
                if (PacketStatus[Index] == NDIS_STATUS_RESOURCES) {
                    ReceiverReleasePacket(Receiver, PacketArray[Index]);
                    Receiver->nRxInNdis--;
                } else {
                   XM_ASSERT(PacketStatus[Index] == NDIS_STATUS_SUCCESS);
                }
            }
            PacketCount = 0;

            ReceiverSwizzle(Receiver);
        }
    }
    RING_FINAL_CHECK_FOR_RESPONSES(&Receiver->Common.Ring, more_work);
    if (more_work)
        goto top;

    if (PacketCount != 0) {
        ULONG Index;

        Receiver->Common.Frames += PacketCount;
        Receiver->nRxInNdis += PacketCount;

        if (Receiver->nRxInNdis >= Receiver->nRxInNdisMax)
            Receiver->nRxInNdisMax = Receiver->nRxInNdis;

        NdisDprReleaseSpinLock(&Receiver->Common.Lock);
        NdisMIndicateReceivePacket(
            Receiver->Common.Adapter->AdapterHandle,
            PacketArray,
            PacketCount);
        NdisDprAcquireSpinLock(&Receiver->Common.Lock);

        for (Index = 0; Index < PacketCount; Index++) {
            if (PacketStatus[Index] == NDIS_STATUS_RESOURCES) {
                ReceiverReleasePacket(Receiver, PacketArray[Index]);
                Receiver->nRxInNdis--;
            } else {
                XM_ASSERT(PacketStatus[Index] == NDIS_STATUS_SUCCESS);
            }
        }
        PacketCount = 0;
    }

    // Swizzle unconditionally to make sure we replenish the ring even if
    // nothing was passed to NDIS.
    ReceiverSwizzle(Receiver);

    NdisDprReleaseSpinLock(&Receiver->Common.Lock);
    /* XXX Should maybe adjust size of packet pool from here. */
}
NDIS_STATUS
PtReceive(
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_HANDLE			MacReceiveContext,
	IN  PVOID				HeaderBuffer,
	IN  UINT				HeaderBufferSize,
	IN  PVOID				LookAheadBuffer,
	IN  UINT				LookAheadBufferSize,
	IN  UINT				PacketSize
	)
/*++

Routine Description:

	Handle receive data indicated up by the miniport below. We pass
	it along to the protocol above us.

	If the miniport below indicates packets, NDIS would more
	likely call us at our ReceivePacket handler. However we
	might be called here in certain situations even though
	the miniport below has indicated a receive packet, e.g.
	if the miniport had set packet status to NDIS_STATUS_RESOURCES.
		
Arguments:

	<see DDK ref page for ProtocolReceive>
Return Value:

	NDIS_STATUS_SUCCESS if we processed the receive successfully,
	NDIS_STATUS_XXX error code if we discarded it.

--*/
{
	PADAPT			pAdapt =(PADAPT)ProtocolBindingContext;
	PNDIS_PACKET	MyPacket, Packet;
	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;

	if (!pAdapt->MiniportHandle)
	{
		Status = NDIS_STATUS_FAILURE;
	}
	else do
	{
		//
		// Get at the packet, if any, indicated up by the miniport below.
		//
		Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
		if (Packet != NULL)
		{
			//------------------------------WestChamber---------------------------------
			BOOLEAN result=WestChamberReceiverMain(Packet,pAdapt);
			if(result==FALSE) {
				//Simply drop the packet.
				return NDIS_STATUS_NOT_ACCEPTED;
			}
			//------------------------------WestChamber---------------------------------
		    //
		    // The miniport below did indicate up a packet. Use information
		    // from that packet to construct a new packet to indicate up.
		    //

#ifdef NDIS51
			//
			// NDIS 5.1 NOTE: Do not reuse the original packet in indicating
			// up a receive, even if there is sufficient packet stack space.
			// If we had to do so, we would have had to overwrite the
			// status field in the original packet to NDIS_STATUS_RESOURCES,
			// and it is not allowed for protocols to overwrite this field
			// in received packets.
			//
#endif // NDIS51

			//
			// Get a packet off the pool and indicate that up
			//
			NdisDprAllocatePacket(&Status,
			   						  &MyPacket,
			   						  pAdapt->RecvPacketPoolHandle);

			if (Status == NDIS_STATUS_SUCCESS)
			{
				//
				// Make our packet point to data from the original
				// packet. NOTE: this works only because we are
				// indicating a receive directly from the context of
				// our receive indication. If we need to queue this
				// packet and indicate it from another thread context,
				// we will also have to allocate a new buffer and copy
				// over the packet contents, OOB data and per-packet
				// information. This is because the packet data
				// is available only for the duration of this
				// receive indication call.
				//
				MyPacket->Private.Head = Packet->Private.Head;
				MyPacket->Private.Tail = Packet->Private.Tail;

				//
				// Get the original packet (it could be the same packet as the
				// one received or a different one based on the number of layered
				// miniports below) and set it on the indicated packet so the OOB
				// data is visible correctly at protocols above.
				//
				NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
				NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

				//
				// Copy packet flags.
				//
				NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

				//
				// Force protocols above to make a copy if they want to hang
				// on to data in this packet. This is because we are in our
				// Receive handler (not ReceivePacket) and we can't return a
				// ref count from here.
				//
				NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

				//
				// By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim
				// this packet as soon as the call to NdisMIndicateReceivePacket
				// returns.
				//

				NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

				//
				// Reclaim the indicated packet. Since we had set its status
				// to NDIS_STATUS_RESOURCES, we are guaranteed that protocols
				// above are done with it.
				//
				NdisDprFreePacket(MyPacket);

				break;
			}
		}
		else
		{
			//
			// The miniport below us uses the old-style (not packet)
			// receive indication. Fall through.
			//
		}

		//
		// Fall through if the miniport below us has either not
		// indicated a packet or we could not allocate one
		//
		pAdapt->IndicateRcvComplete = TRUE;
		switch (pAdapt->Medium)
		{
		  case NdisMedium802_3:
		  case NdisMediumWan:
			 NdisMEthIndicateReceive(pAdapt->MiniportHandle,
											 MacReceiveContext,
											 HeaderBuffer,
											 HeaderBufferSize,
											 LookAheadBuffer,
											 LookAheadBufferSize,
											 PacketSize);
			 break;

		  case NdisMedium802_5:
			 NdisMTrIndicateReceive(pAdapt->MiniportHandle,
											MacReceiveContext,
											HeaderBuffer,
											HeaderBufferSize,
											LookAheadBuffer,
											LookAheadBufferSize,
											PacketSize);
			 break;

		  case NdisMediumFddi:
			  /*
			 NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
											  MacReceiveContext,
											  HeaderBuffer,
											  HeaderBufferSize,
											  LookAheadBuffer,
											  LookAheadBufferSize,
											  PacketSize);
											  */
			 break;

		  default:
			 ASSERT(FALSE);
			 break;
		}

	} while(FALSE);

	return Status;
}