Ejemplo n.º 1
0
NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket,
				      PCHAR Data, UINT Len ) {
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewData;

    NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG );
    if( !NewData ) return NDIS_STATUS_RESOURCES;

    if( Data ) RtlCopyMemory(NewData, Data, Len);

    NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
    if( Status != NDIS_STATUS_SUCCESS ) {
	ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
	return Status;
    }

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
    if( Status != NDIS_STATUS_SUCCESS ) {
	ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
	FreeNdisPacket( Packet );
	return Status;
    }

    NdisChainBufferAtFront( Packet, Buffer );
    *NdisPacket = Packet;

    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 2
0
NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
				       PCHAR Data, UINT Len,
				       PCHAR File, UINT Line ) {
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewData;

    NewData = exAllocatePool( NonPagedPool, Len );
    if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX

    if( Data )
	RtlCopyMemory(NewData, Data, Len);

    NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
    if( Status != NDIS_STATUS_SUCCESS ) {
	exFreePool( NewData );
	return Status;
    }
    TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
    if( Status != NDIS_STATUS_SUCCESS ) {
	exFreePool( NewData );
	FreeNdisPacket( Packet );
    }
    TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);

    NdisChainBufferAtFront( Packet, Buffer );
    *NdisPacket = Packet;

    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 3
0
NTSTATUS DispatchWrite(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS status;

	// 取得描述适配器的OPEN_INSTANCE结构的指针
	OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension;
	// 增加IO引用计数
	IoIncrement(pOpen);
	do
	{
		if(!pOpen->bBound)
		{
			status = STATUS_DEVICE_NOT_READY;
			break;
		}

		// 从封包池中申请一个封包
		PNDIS_PACKET pPacket;
		NdisAllocatePacket((NDIS_STATUS*)&status, &pPacket, pOpen->hPacketPool);
		if(status != NDIS_STATUS_SUCCESS)	// 封包被申请完了!
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			break;
		}

		RESERVED(pPacket)->pIrp = pIrp; // 保存IRP指针,在完成例程中还要使用

		// 附加写缓冲区到封包
		NdisChainBufferAtFront(pPacket, pIrp->MdlAddress);

		// 注意,既然我们已经标识此IRP未决,我们必须返回STATUS_PENDING,即便是
		// 我们恰巧同步完成了这个IRP
		IoMarkIrpPending(pIrp);

		// 发送封包到下层NIC设备
		NdisSend((NDIS_STATUS*)&status, pOpen->hAdapter, pPacket);
		if(status != NDIS_STATUS_PENDING)
		{
			ProtocolSendComplete(pOpen, pPacket, status);
		}
		return STATUS_PENDING;		
	}while(FALSE);

	if(status != STATUS_SUCCESS)
	{
		IoDecrement(pOpen);
		pIrp->IoStatus.Information = 0;
		pIrp->IoStatus.Status = status;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}
	return status;
}
Ejemplo n.º 4
0
void
CAR6KMini::car6k_sendEapolKeyMsg (A_UINT8 descType,
                            A_BOOL secure, A_BOOL mic, A_BOOL ack, A_BOOL tx,
                            A_UINT32 index, A_UINT8 isPW,
                            A_BOOL doEncrypt,
                            A_UINT64 keyRSC,
                            const A_UINT8 nonce[],
                            const A_UINT32 keyLength,
                            A_UINT32 keyDataLen,
                            const A_UINT8 *keyData,
                            const A_UINT32 keyBufferLength,
                            A_UINT8  *bssid)
{
    STATION *station;
    station = GetStation(bssid,0);
    NDIS_STATUS Status;
    PNDIS_PACKET pPacket;
    PNDIS_BUFFER pBuffer;
    A_UINT32 *magic;
    A_UINT16 length;

    memset (m_wpa_buffer, 0 , sizeof (m_wpa_buffer));
    crypto_sendEapolKeyMsg ( descType,secure, mic, ack,  tx,
                             index, isPW,doEncrypt,keyRSC,
                             nonce,keyLength,keyDataLen,
                             keyData, keyBufferLength,
                             bssid,m_CurrentAddress,m_keyCounter,&replayCtr,
                             station,m_wpa_buffer,&length);

    NdisAllocatePacket (&Status, &pPacket, m_TxPacketPool);
    magic = (UINT32 *) pPacket->ProtocolReserved;
    if (NDIS_STATUS_SUCCESS != Status)
    {
        NDIS_DEBUG_PRINTF (ATH_LOG_ERR, "AR6K: ERROR - NdisAllocatePacket failed\n");
        return;
    }

    NdisAllocateBuffer (&Status, &pBuffer, m_TxBufferPool, m_wpa_buffer, length);

    if (NDIS_STATUS_SUCCESS != Status)
    {
        NdisFreePacket (pPacket);
        NDIS_DEBUG_PRINTF (ATH_LOG_ERR, "AR6K: ERROR - NdisAllocateBuffer failed\n");
        return;
    }

    pBuffer->Next = NULL;
    NdisChainBufferAtFront (pPacket,pBuffer);
    *(magic) = TAG_WPA_SEND_PCK;
    SendPackets (&pPacket,1);
    return;
}
Ejemplo n.º 5
0
NTSTATUS PacketRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	POPEN_INSTANCE      open;
	PNDIS_PACKET        pPacket;
	NDIS_STATUS         status;
	NTSTATUS            ntStatus;
	PIO_STACK_LOCATION  irpSp;

	// DebugPrint(("Read\n"));

	open = DeviceObject->DeviceExtension;

	IoIncrement(open);

	if(!open->Bound) {
		ntStatus = STATUS_DEVICE_NOT_READY;
		goto ERROR;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	if (irpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {
		ntStatus = STATUS_BUFFER_TOO_SMALL;
		goto ERROR;
	}

	NdisAllocatePacket( &status, &pPacket, open->PacketPool );
	if (status != NDIS_STATUS_SUCCESS) {
		// DebugPrint(("Packet: Read- No free packets\n"));
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ERROR;
	}

	RESERVED(pPacket)->Irp=Irp;
	RESERVED(pPacket)->pMdl=NULL;
	IoMarkIrpPending(Irp);

	IoSetCancelRoutine(Irp, PacketCancelRoutine);

	ExInterlockedInsertTailList(
			&open->RcvList,
			&RESERVED(pPacket)->ListElement,
			&open->RcvQSpinLock);

	return STATUS_PENDING;

ERROR:
	Irp->IoStatus.Status = ntStatus;
	IoCompleteRequest (Irp, IO_NO_INCREMENT);
	IoDecrement(open);
	return ntStatus;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
// Create a packet buffer
PACKET_BUFFER *NeoNewPacketBuffer()
{
	PACKET_BUFFER *p;
	NDIS_STATUS ret;

	// Memory allocation
	p = NeoZeroMalloc(sizeof(PACKET_BUFFER));
	// Memory allocation for packet
	p->Buf = NeoMalloc(NEO_MAX_PACKET_SIZE);
	// Allocate the buffer pool
	NdisAllocateBufferPool(&ret, &p->BufferPool, 1);
	// Allocate the buffer
	NdisAllocateBuffer(&ret, &p->NdisBuffer, p->BufferPool, p->Buf, NEO_MAX_PACKET_SIZE);
	// Secure the packet pool
	NdisAllocatePacketPool(&ret, &p->PacketPool, 1, PROTOCOL_RESERVED_SIZE_IN_PACKET);
	// Secure the packet
	NdisAllocatePacket(&ret, &p->NdisPacket, p->PacketPool);
	NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
	// Attach the buffer to the packet
	NdisChainBufferAtFront(p->NdisPacket, p->NdisBuffer);

	return p;
}
Ejemplo n.º 8
0
NTSTATUS
NdisProtWrite(
    IN PDEVICE_OBJECT       pDeviceObject,
    IN PIRP                 pIrp
)
/*++

Routine Description:

    Dispatch routine to handle IRP_MJ_WRITE.

Arguments:

    pDeviceObject - pointer to our device object
    pIrp - Pointer to request packet

Return Value:

    NT status code.

--*/
{
    PIO_STACK_LOCATION      pIrpSp;
    ULONG                   DataLength;
    NTSTATUS                NtStatus;
    NDIS_STATUS             Status;
    PNDISPROT_OPEN_CONTEXT   pOpenContext;
    PNDIS_PACKET            pNdisPacket;
    PNDIS_BUFFER            pNdisBuffer;
    NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;
#ifdef NDIS51
    PVOID                   CancelId;
#endif

    UNREFERENCED_PARAMETER(pDeviceObject);

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    pOpenContext = pIrpSp->FileObject->FsContext;

    pNdisPacket = NULL;

    do
    {
        if (pOpenContext == NULL)
        {
            DEBUGP(DL_WARN, ("Write: FileObject %p not yet associated with a device\n",
                             pIrpSp->FileObject));
            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        NPROT_STRUCT_ASSERT(pOpenContext, oc);

        if (pIrp->MdlAddress == NULL)
        {
            DEBUGP(DL_FATAL, ("Write: NULL MDL address on IRP %p\n", pIrp));
            NtStatus = STATUS_INVALID_PARAMETER;
            break;
        }
        //
        // Try to get a virtual address for the MDL.
        //

        pEthHeader = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);

        if (pEthHeader == NULL)
        {
            DEBUGP(DL_FATAL, ("Write: MmGetSystemAddr failed for"
                              " IRP %p, MDL %p\n",
                              pIrp, pIrp->MdlAddress));
            NtStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        //
        // Sanity-check the length.
        //
        DataLength = MmGetMdlByteCount(pIrp->MdlAddress);
        if (DataLength < sizeof(NDISPROT_ETH_HEADER))
        {
            DEBUGP(DL_WARN, ("Write: too small to be a valid packet (%d bytes)\n",
                             DataLength));
            NtStatus = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        if (DataLength > (pOpenContext->MaxFrameSize + sizeof(NDISPROT_ETH_HEADER)))
        {
            DEBUGP(DL_WARN, ("Write: Open %p: data length (%d)"
                             " larger than max frame size (%d)\n",
                             pOpenContext, DataLength, pOpenContext->MaxFrameSize));

            NtStatus = STATUS_INVALID_BUFFER_SIZE;
            break;
        }

        //
        // To prevent applications from sending packets with spoofed
        // mac address, we will do the following check to make sure the source
        // address in the packet is same as the current MAC address of the NIC.
        //
        if ((pIrp->RequestorMode == UserMode) &&
                !NPROT_MEM_CMP(pEthHeader->SrcAddr, pOpenContext->CurrentAddress, NPROT_MAC_ADDR_LEN))
        {
            DEBUGP(DL_WARN, ("Write: Failing with invalid Source address"));
            NtStatus = STATUS_INVALID_PARAMETER;
            break;
        }

        NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);

        if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NUIOO_BIND_FLAGS, NUIOO_BIND_ACTIVE))
        {
            NPROT_RELEASE_LOCK(&pOpenContext->Lock);

            DEBUGP(DL_FATAL, ("Write: Open %p is not bound"
                              " or in low power state\n", pOpenContext));

            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        //
        //  Allocate a send packet.
        //
        NPROT_ASSERT(pOpenContext->SendPacketPool != NULL);
        NdisAllocatePacket(
            &Status,
            &pNdisPacket,
            pOpenContext->SendPacketPool);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            NPROT_RELEASE_LOCK(&pOpenContext->Lock);

            DEBUGP(DL_FATAL, ("Write: open %p, failed to alloc send pkt\n",
                              pOpenContext));
            NtStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        //
        //  Allocate a send buffer if necessary.
        //
        if (pOpenContext->bRunningOnWin9x)
        {
            NdisAllocateBuffer(
                &Status,
                &pNdisBuffer,
                pOpenContext->SendBufferPool,
                pEthHeader,
                DataLength);

            if (Status != NDIS_STATUS_SUCCESS)
            {
                NPROT_RELEASE_LOCK(&pOpenContext->Lock);

                NdisFreePacket(pNdisPacket);

                DEBUGP(DL_FATAL, ("Write: open %p, failed to alloc send buf\n",
                                  pOpenContext));
                NtStatus = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }
        else
        {
            pNdisBuffer = pIrp->MdlAddress;
        }

        NdisInterlockedIncrement((PLONG)&pOpenContext->PendedSendCount);

        NPROT_REF_OPEN(pOpenContext);  // pended send

        IoMarkIrpPending(pIrp);

        //
        //  Initialize the packet ref count. This packet will be freed
        //  when this count goes to zero.
        //
        NPROT_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 = NPROT_GET_NEXT_CANCEL_ID();
        NDIS_SET_PACKET_CANCEL_ID(pNdisPacket, CancelId);
        pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pOpenContext;
        pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNdisPacket;

        NPROT_INSERT_TAIL_LIST(&pOpenContext->PendedWrites, &pIrp->Tail.Overlay.ListEntry);

        IoSetCancelRoutine(pIrp, NdisProtCancelWrite);

#endif // NDIS51

        NPROT_RELEASE_LOCK(&pOpenContext->Lock);

        //
        //  Set a back pointer from the packet to the IRP.
        //
        NPROT_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp;

        NtStatus = STATUS_PENDING;

        pNdisBuffer->Next = NULL;
        NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

#if SEND_DBG
        {
            PUCHAR      pData;

            pData = MmGetSystemAddressForMdlSafe(pNdisBuffer, NormalPagePriority);
            NPROT_ASSERT(pEthHeader == pData);

            DEBUGP(DL_VERY_LOUD,
                   ("Write: MDL %p, MdlFlags %x, SystemAddr %p, %d bytes\n",
                    pIrp->MdlAddress, pIrp->MdlAddress->MdlFlags, pData, DataLength));

            DEBUGPDUMP(DL_VERY_LOUD, pData, MIN(DataLength, 48));
        }
#endif // SEND_DBG

        NdisSendPackets(pOpenContext->BindingHandle, &pNdisPacket, 1);

    }
    while (FALSE);

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

    return (NtStatus);
}
Ejemplo n.º 9
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");
}
Ejemplo n.º 10
0
/*+
 *
 * AllocateAdapterMemory
 *
 * Routine Description:
 *
 *     This routine allocates memory for:
 *
 *     - Transmit descriptor ring
 *     - Receive descriptor ring
 *     - Receive buffers
 *     - Transmit buffer
 *     - Setup buffer
 *
 * Arguments:
 *
 *     Adapter - The adapter to allocate memory for.
 *
 * Functional description
 *
 *     For each allocated zone, we maintain a set of pointers:
 *        - virtual & physical addresses of the allocated block
 *        - virtual & physical addresses of the aligned structure (descriptor ring, buffer,...)
 *          whithin  the block
 *
 * Return Value:
 *
 *     Returns FALSE if an allocation fails.
 *
-*/
extern
BOOLEAN
AllocateAdapterMemory(
        IN PDC21X4_ADAPTER Adapter
        )
{
   PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
   PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;

   NDIS_STATUS Status;

   PRCV_HEADER RcvHeader;
   PNDIS_PACKET Packet;

   ULONG AllocSize;
   PULONG AllocVa;
   NDIS_PHYSICAL_ADDRESS AllocPa;
   ULONG Va;

   ULONG Pa;

   UINT i;
   ULONG Offset;

   INT TransmitDescriptorRingSize;
   INT ReceiveDescriptorRingSize;

   Adapter->RcvHeaderSize =
           ((RCV_HEADER_SIZE + Adapter->CacheLineSize - 1) / Adapter->CacheLineSize)
         * Adapter->CacheLineSize;


#if _DBG
   DbgPrint("Alloc Rcv_ring[%d desc.], Txm_ring[%d desc.], setup_buf[%d]...\n",
      Adapter->ReceiveRingSize,
      TRANSMIT_RING_SIZE,
      DC21X4_SETUP_BUFFER_SIZE
      );
#endif

   // Allocate space for transmit descriptor ring,
   // the receive descriptor ring and the setup buffer

   TransmitDescriptorRingSize =
      Adapter->DescriptorSize * TRANSMIT_RING_SIZE;
   ReceiveDescriptorRingSize =
      Adapter->DescriptorSize * Adapter->ReceiveRingSize;

   Adapter->DescriptorRing.AllocSize =
      TransmitDescriptorRingSize
      + ReceiveDescriptorRingSize
      + DC21X4_SETUP_BUFFER_SIZE
      + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->DescriptorRing.AllocSize,
      FALSE,                                           // NON-CACHED
      (PVOID *)&Adapter->DescriptorRing.AllocVa,       // virtual ...
      &Adapter->DescriptorRing.AllocPa                 // and physical address of the allocation
      );

   // Check the allocation success

   if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
      return FALSE;
   }
   if (NdisGetPhysicalAddressHigh(Adapter->DescriptorRing.AllocPa) != 0) {
      return FALSE;
   }

   NdisZeroMemory (
      (PVOID)(Adapter->DescriptorRing.AllocVa),
      (ULONG)(Adapter->DescriptorRing.AllocSize)
      );

   // Align to the next cache line boundary

   AlignStructure (
      &Adapter->DescriptorRing,
      Adapter->CacheLineSize
      );

   Adapter->TransmitDescriptorRingVa = Adapter->DescriptorRing.Va;
   Adapter->TransmitDescriptorRingPa = Adapter->DescriptorRing.Pa;
   Offset = TransmitDescriptorRingSize;

   Adapter->ReceiveDescriptorRingVa =  Adapter->DescriptorRing.Va + Offset;
   Adapter->ReceiveDescriptorRingPa =  Adapter->DescriptorRing.Pa + Offset;
   Offset += ReceiveDescriptorRingSize;

   Adapter->SetupBufferVa = Adapter->DescriptorRing.Va + Offset;
   Adapter->SetupBufferPa = Adapter->DescriptorRing.Pa + Offset;

   //Initialize the setup buffer

   NdisZeroMemory (
      (PVOID)(Adapter->SetupBufferVa),
      DC21X4_SETUP_BUFFER_SIZE
      );


   // Allocate a pool of NDIS buffers

   NdisAllocateBufferPool(
        &Status,
        &Adapter->FlushBufferPoolHandle,
        ( Adapter->ReceiveRingSize
        + Adapter->ExtraReceiveBuffers
        + DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS
        + DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS )
        );

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


   //  Allocate a pool of packets.
#if _DBG
   DbgPrint("Allocate PacketPool [%d packets]\n",
      Adapter->ExtraReceivePackets);
#endif
   NdisAllocatePacketPool(
      &Status,
      &Adapter->ReceivePacketPool,
      Adapter->ExtraReceivePackets,
      0
      );

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

   // Allocate all of the packets out of the packet pool
   // and place them on a queue.

   for (i = 0; i < Adapter->ExtraReceivePackets; i++) {

      // Allocate a packet from the pool.
      NdisAllocatePacket(
         &Status,
         &Packet,
         Adapter->ReceivePacketPool
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return(FALSE);
      }

      // Set the header size in the packet's Out-Of-Band information.
      // All other fields in the Out-Of-Band information have been
      // initialized to 0 by NdisAllocatePacket().

      NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

      // Place it on the receive packet free list.

      RCV_RESERVED(Packet)->Next = Adapter->FreePacketList;
      Adapter->FreePacketList = Packet;
   }

   //  Clear out the free receive list of buffers.
   Adapter->FreeRcvList = NULL;


   //  We allocate the receive buffers.  We allocate both
   //  the buffers for the descriptor ring and the extra
   //  buffers and place them all on the free queue.

#if _DBG
   DbgPrint("Allocate Receive Buffers [%d]\n",
      Adapter->ExtraReceiveBuffers+Adapter->ReceiveRingSize);
#endif

   // Attempt to allocate all the receive buffer space
   // in one block
   // If it fails,allocate each buffer individually

   //  Allocation size
   Adapter->RcvBufferSpace.AllocSize =
      ((Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize)
      * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize))
      + Adapter->CacheLineSize;


   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->RcvBufferSpace.AllocSize,
      TRUE,
      (PVOID *)&Adapter->RcvBufferSpace.AllocVa,
      &Adapter->RcvBufferSpace.AllocPa
      );

   // Check the allocation success
   if (((PVOID)Adapter->RcvBufferSpace.AllocVa != (PVOID)NULL)
      && (NdisGetPhysicalAddressHigh(Adapter->RcvBufferSpace.AllocPa) == 0)) {

        NdisZeroMemory (
          (PVOID)(Adapter->RcvBufferSpace.AllocVa),
          (ULONG)(Adapter->RcvBufferSpace.AllocSize)
          );

       // Align to the next cache line boundary

       AlignStructure (
          &Adapter->RcvBufferSpace,
          Adapter->CacheLineSize
          );

       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize;
       Offset=0;
   }
   else
   {
       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize
                 + Adapter->CacheLineSize;


       Adapter->RcvBufferSpace.Va=0;
   }

   for (i = 0;
      i < (Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize);
      i++
      ) {

      if (Adapter->RcvBufferSpace.Va != 0) {

          Va = Adapter->RcvBufferSpace.Va + Offset;
          Pa = Adapter->RcvBufferSpace.Pa + Offset;
          Offset += AllocSize;

      }
      else
      {
          //  Allocate a receive buffer.

          NdisMAllocateSharedMemory(
             Adapter->MiniportAdapterHandle,
             AllocSize,
             TRUE,
             (PVOID *)&AllocVa,
             &AllocPa
             );
          if (((PVOID)AllocVa == (PVOID)NULL)
             || (NdisGetPhysicalAddressHigh(AllocPa) != 0)) {
             return FALSE;
          }

          NdisZeroMemory(AllocVa, AllocSize);

          //  Align on the cache line boundary

          Offset = Adapter->CacheLineSize - ((ULONG)AllocVa % Adapter->CacheLineSize);
          Va = (ULONG)(AllocVa) + Offset;
          Pa = NdisGetPhysicalAddressLow(AllocPa) + Offset;

      }

      //The receive header points to the aligned va.

      RcvHeader = (PRCV_HEADER)Va;

      RcvHeader->AllocVa = (ULONG)AllocVa;
      RcvHeader->AllocPa = AllocPa;
      RcvHeader->AllocSize = (USHORT)AllocSize;

      // These addresses point to the data buffer

      RcvHeader->Va = (ULONG)(Va + Adapter->RcvHeaderSize);
      RcvHeader->Pa = Pa + Adapter->RcvHeaderSize;
      RcvHeader->Size = DC21X4_RECEIVE_BUFFER_SIZE;

#if DBG
      RcvHeader->Signature = 'dHxR';
#if _DBG
      DbgPrint(
         "%-3d RcvHeader: %lx, RcvBuffer: %lx/%lx, HeaderSize: %lx\n",
         i,RcvHeader,
         RcvHeader->Va,
         RcvHeader->Pa,
         Adapter->RcvHeaderSize
         );
#endif
#endif
      //  Allocate an NDIS flush buffer for each receive buffer.

      NdisAllocateBuffer(
         &Status,
         &RcvHeader->FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)RcvHeader->Va,
         DC21X4_RECEIVE_BUFFER_SIZE
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }

      // Grab a packet off of the free packet list and
      // associate it with the buffer.

      Packet = Adapter->FreePacketList;
      Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;

      // Chain the buffer on the packet.

      NdisChainBufferAtFront(Packet, RcvHeader->FlushBuffer);

      // Save a pointer to the receive header with the packet.

      RCV_RESERVED(Packet)->RcvHeader = RcvHeader;

      // Save the packet with the receive header.

      RcvHeader->Packet = Packet;

      // Place the descriptor on the free queue.

      RcvHeader->Next = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader;

      Adapter->CurrentReceiveBufferCount++;
   }


#if _DBG
   DbgPrint("Init Rcv ring..\n");
#endif

   //  Assign the receive buffers to the descriptors.

   for (i = 0,
      ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa,
      Pa = Adapter->ReceiveDescriptorRingPa;
      i < Adapter->ReceiveRingSize;
      i++,
      (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize,
      Pa += Adapter->DescriptorSize
      ) {

      // Grab a receive buffer from the free list.

      ASSERT(Adapter->FreeRcvList != NULL);
      RcvHeader = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader->Next;

      Adapter->CurrentReceiveBufferCount--;

      // Associate the buffer with the descriptor.

      ReceiveDescriptor->RcvHeader = RcvHeader;
      ReceiveDescriptor->FirstBufferAddress = RcvHeader->Pa;


      ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
      ReceiveDescriptor->Control = DC21X4_RECEIVE_BUFFER_SIZE;

      ReceiveDescriptor->Next =
         (PDC21X4_RECEIVE_DESCRIPTOR)((PCHAR)ReceiveDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring

   (PCHAR)ReceiveDescriptor -= Adapter->DescriptorSize;
   ReceiveDescriptor->Control |= DC21X4_RDES_SECOND_ADDR_CHAINED;
   ReceiveDescriptor->SecondBufferAddress = Adapter->ReceiveDescriptorRingPa;
   ReceiveDescriptor->Next =
      (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;

#if _DBG
   DbgPrint("Init Txm ring..\n");
#endif

   // Initialize the Transmit Descriptor ring

   for (i=0,
      TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa,
      Pa = Adapter->TransmitDescriptorRingPa;
      i < TRANSMIT_RING_SIZE;
      i++,
      (PCHAR)TransmitDescriptor += Adapter->DescriptorSize,
      Pa += Adapter->DescriptorSize
      ) {

      TransmitDescriptor->MapTableIndex = i * NUMBER_OF_SEGMENT_PER_DESC;
      TransmitDescriptor->DescriptorPa = Pa;
      TransmitDescriptor->Next =
         (PDC21X4_TRANSMIT_DESCRIPTOR)((PCHAR)TransmitDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring
   (PCHAR)TransmitDescriptor -= Adapter->DescriptorSize;
   TransmitDescriptor->Control = DC21X4_TDES_SECOND_ADDR_CHAINED;
   TransmitDescriptor->SecondBufferAddress = Adapter->TransmitDescriptorRingPa;
   TransmitDescriptor->Next =
      (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;


   // Txm buffers

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

      Adapter->MaxTransmitBuffer[i].AllocSize =
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize;

      NdisMAllocateSharedMemory(
         Adapter->MiniportAdapterHandle,
         Adapter->MaxTransmitBuffer[i].AllocSize,
         TRUE,                                           // CACHED
         (PVOID *)&Adapter->MaxTransmitBuffer[i].AllocVa,   // virtual ...
         &Adapter->MaxTransmitBuffer[i].AllocPa             // and physical address of the buffer allocation
         );

      // Check the allocation success

      if (((PVOID)Adapter->MaxTransmitBuffer[i].AllocVa == (PVOID)NULL)
         || (NdisGetPhysicalAddressHigh(Adapter->MaxTransmitBuffer[i].AllocPa) != 0)) {
         return FALSE;
      }

      // Align the buffer on the cache line boundary

      AlignStructure (
         &Adapter->MaxTransmitBuffer[i],
         Adapter->CacheLineSize
         );


      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MaxTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MaxTransmitBuffer[i].Va,
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE
         );

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

   // Allocate the minimal packet buffers

   Adapter->MinTransmitBuffer[0].AllocSize =
       (DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS * DC21X4_MIN_TRANSMIT_BUFFER_SIZE)
     + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
     Adapter->MiniportAdapterHandle,
     Adapter->MinTransmitBuffer[0].AllocSize,
     TRUE,                                              // CACHED
     (PVOID *)&Adapter->MinTransmitBuffer[0].AllocVa,   // virtual ...
     &Adapter->MinTransmitBuffer[0].AllocPa             // and physical address of the buffer allocation
     );

   // Check the allocation success

   if (((PVOID)Adapter->MinTransmitBuffer[0].AllocVa == (PVOID)NULL)
       || (NdisGetPhysicalAddressHigh(Adapter->MinTransmitBuffer[0].AllocPa) != 0)) {

	  Adapter->DontUseMinTransmitBuffer = TRUE;
      return TRUE;
   }

   // Align the buffer on the cache line boundary

   AlignStructure (
      &Adapter->MinTransmitBuffer[0],
      Adapter->CacheLineSize
      );

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

      Offset = i * DC21X4_MIN_TRANSMIT_BUFFER_SIZE;

      Adapter->MinTransmitBuffer[i].Va =
          Adapter->MinTransmitBuffer[0].Va + Offset;

      Adapter->MinTransmitBuffer[i].Pa =
          Adapter->MinTransmitBuffer[0].Pa + Offset;

      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MinTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MinTransmitBuffer[i].Va,
         DC21X4_MIN_TRANSMIT_BUFFER_SIZE
         );

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

   // Allocation has completed successfully

   return TRUE;
}
Ejemplo n.º 11
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.º 12
0
VOID
MPSendPackets(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN PPNDIS_PACKET           PacketArray,
    IN UINT                    NumberOfPackets
    )
/*++

Routine Description:

    Send Packet Array handler. Either this or our SendPacket handler is called
    based on which one is enabled in our Miniport Characteristics.

Arguments:

    MiniportAdapterContext     Pointer to our adapter
    PacketArray                Set of packets to send
    NumberOfPackets            Self-explanatory

Return Value:

    None

--*/
{
    PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS         Status;
    UINT                i;
    PVOID               MediaSpecificInfo = NULL;
    UINT                MediaSpecificInfoSize = 0;
    

    for (i = 0; i < NumberOfPackets; i++)
    {
        PNDIS_PACKET    Packet, MyPacket;
        ULONG          SndFltAction;

        Packet = PacketArray[i];

        //
        // The driver should fail the send if the virtual miniport is in low 
        // power state
        //
        if (pAdapt->MPDeviceState > NdisDeviceStateD0)
        {
            NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
                            Packet,
                            NDIS_STATUS_FAILURE);
            continue;
        }

        //
        // Call Send Packet Filter
        //
        SndFltAction = FltFilterSendPacket(
                        pAdapt,
                        Packet,
                        FALSE // Caller is running at IRQL <= DISPATCH_LEVEL
                        );

        //
        // Possibly Block (Drop) Packet
        // ----------------------------
        // Lying send. Report SUCCESS, even though it really hasn't
        // been sent.
        //
        if( SndFltAction & ACTION_BLOCK_PACKET ) {
            NdisMSendComplete( ADAPT_MINIPORT_HANDLE(pAdapt), Packet, NDIS_STATUS_SUCCESS);
            continue;
        }

#ifdef NDIS51

        //
        // Use NDIS 5.1 packet stacking:
        //
        {
            PNDIS_PACKET_STACK        pStack;
            BOOLEAN                   Remaining;

            //
            // Packet stacks: Check if we can use the same packet for sending down.
            //
            pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
            if (Remaining)
            {
                //
                // We can reuse "Packet".
                //
                // NOTE: if we needed to keep per-packet information in packets
                // sent down, we can use pStack->IMReserved[].
                //
                ASSERT(pStack);
                //
                // If the below miniport is going to low power state, stop sending down any packet.
                //
                NdisAcquireSpinLock(&pAdapt->Lock);
                if (pAdapt->PTDeviceState > NdisDeviceStateD0)
                {
                    NdisReleaseSpinLock(&pAdapt->Lock);
                    NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
                                        Packet,
                                        NDIS_STATUS_FAILURE);
                }
                else
                {
                    pAdapt->OutstandingSends++;
                    NdisReleaseSpinLock(&pAdapt->Lock);
                
                    NdisSend(&Status,
                              pAdapt->BindingHandle,
                              Packet);
        
                    if (Status != NDIS_STATUS_PENDING)
                    {
                        NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
                                            Packet,
                                            Status);
                   
                        ADAPT_DECR_PENDING_SENDS(pAdapt);
                    }
                }
                continue;
            }
        }
#endif
        do 
        {
            NdisAcquireSpinLock(&pAdapt->Lock);
            //
            // If the below miniport is going to low power state, stop sending down any packet.
            //
            if (pAdapt->PTDeviceState > NdisDeviceStateD0)
            {
                NdisReleaseSpinLock(&pAdapt->Lock);
                Status = NDIS_STATUS_FAILURE;
                break;
            }
            pAdapt->OutstandingSends++;
            NdisReleaseSpinLock(&pAdapt->Lock);
            
            NdisAllocatePacket(&Status,
                               &MyPacket,
                               pAdapt->SendPacketPoolHandle);

            if (Status == NDIS_STATUS_SUCCESS)
            {
                PSEND_RSVD        SendRsvd;

                SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
                SendRsvd->OriginalPkt = Packet;

                MyPacket->Private.Flags = NdisGetPacketFlags(Packet);

                MyPacket->Private.Head = Packet->Private.Head;
                MyPacket->Private.Tail = Packet->Private.Tail;
#ifdef WIN9X
                //
                // Work around the fact that NDIS does not initialize this
                // to FALSE on Win9x.
                //
                MyPacket->Private.ValidCounts = FALSE;
#endif // WIN9X

                //
                // Copy the OOB data from the original packet to the new
                // packet.
                //
                NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
                            NDIS_OOB_DATA_FROM_PACKET(Packet),
                            sizeof(NDIS_PACKET_OOB_DATA));
                //
                // Copy relevant parts of the per packet info into the new packet
                //
#ifndef WIN9X
                NdisIMCopySendPerPacketInfo(MyPacket, Packet);
#endif

                //
                // Copy the Media specific information
                //
                NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
                                                    &MediaSpecificInfo,
                                                    &MediaSpecificInfoSize);

                if (MediaSpecificInfo || MediaSpecificInfoSize)
                {
                    NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
                                                        MediaSpecificInfo,
                                                        MediaSpecificInfoSize);
                }

                NdisSend(&Status,
                         pAdapt->BindingHandle,
                         MyPacket);

                if (Status != NDIS_STATUS_PENDING)
                {
#ifndef WIN9X
                    NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
#endif
                    NdisFreePacket(MyPacket);
                    ADAPT_DECR_PENDING_SENDS(pAdapt);
                }
            }
            else
            {
                //
                // The driver cannot allocate a packet.
                // 
                ADAPT_DECR_PENDING_SENDS(pAdapt);
            }
        }
        while (FALSE);

        if (Status != NDIS_STATUS_PENDING)
        {
            NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
                              Packet,
                              Status);
        }
    }
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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.º 15
0
VOID
MPSendPackets(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN PPNDIS_PACKET           PacketArray,
    IN UINT                    NumberOfPackets
    )
/*++

Routine Description:

    Send Packet Array handler. Either this or our SendPacket handler is called
    based on which one is enabled in our Miniport Characteristics.

Arguments:

    MiniportAdapterContext     Pointer to our adapter
    PacketArray                Set of packets to send
    NumberOfPackets            Self-explanatory

Return Value:

    None

--*/
{
    PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS         Status;
    UINT                i;
    PVOID               MediaSpecificInfo = NULL;
    UINT                MediaSpecificInfoSize = 0;
	FILTER_STATUS		fStatus;
	PUCHAR				pBuffer;
	int					nBufLen;
    

    for (i = 0; i < NumberOfPackets; i++)
    {
        PNDIS_PACKET    Packet, MyPacket;

        Packet = PacketArray[i];

		//KdPrint(("微端口MPSendPackets方法,开始报文分析\n"));
		getMemoryCopyFromPacket(Packet, &pBuffer, &nBufLen);
		KdPrint(("\n==> 微端口MPSendPackets方法,开始分析报文\n"));
		fStatus = analyzeBuffer(pAdapt, pBuffer, &nBufLen, MODE_SEND);
		//fStatus = AnalysisPacket(Packet, FALSE);
		//fStatus = FILTER_STATUS_PASS;
		if (fStatus == FILTER_STATUS_DROP)
		{
			//丢弃
			KdPrint(("<== 微端口MPSendPackets方法,进入FILTER_STATUS_DROP模式\n"));
			freeMemory(pBuffer);
			// 在这个函数中,任何一个被放弃的包,都必须调用NdisMSendComplete。
			NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), Packet, NDIS_STATUS_FAILURE);
			continue; 
		}
		/*
		else if (fStatus == FILTER_STATUS_MODIFY_REDIRECT)
		{
			//没有发送时接收转发这种情况
		}
		*/
		else if (fStatus == FILTER_STATUS_MODIFY_SEND)
		{
			//修改+发送
			KdPrint(("<== 微端口MPSendPackets方法,进入FILTER_STATUS_MODIFY_SEND模式\n"));
			MyPacket = createPacketFromMemory_SendPool(pAdapt, pBuffer, nBufLen);
			//freePacketBufferOnly(Packet);

			// The driver should fail the send if the virtual miniport is in low 
			// power state
			//
			if (pAdapt->MPDeviceState > NdisDeviceStateD0)
			{
				NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
					Packet,
					NDIS_STATUS_FAILURE);
				continue;
			}
			//这里原来有NDIS51的一个简化处理,放在此文件最下面了
			do 
			{
				PSEND_RSVD        SendRsvd;

				NdisAcquireSpinLock(&pAdapt->Lock);
				//
				// If the below miniport is going to low power state, stop sending down any packet.
				//
				if (pAdapt->PTDeviceState > NdisDeviceStateD0)
				{
					NdisReleaseSpinLock(&pAdapt->Lock);
					Status = NDIS_STATUS_FAILURE;
					break;
				}
				pAdapt->OutstandingSends++;
				NdisReleaseSpinLock(&pAdapt->Lock);
				
				//NdisAllocatePacket(&Status,
				//	&MyPacket,
				//	pAdapt->SendPacketPoolHandle);
				
				SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
				SendRsvd->OriginalPkt = Packet;
				
				NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
				NdisSetPacketFlags(MyPacket, NDIS_FLAGS_RESERVED4); //我们做个标记
				
				//现在我们自己构造buffer,所以不需要用原packet的buffer了
				//NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
				//NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);
				
				//
				// Copy the OOB data from the original packet to the new
				// packet.
				//
				NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
					NDIS_OOB_DATA_FROM_PACKET(Packet),
					sizeof(NDIS_PACKET_OOB_DATA));
				//
				// Copy relevant parts of the per packet info into the new packet
				//
				NdisIMCopySendPerPacketInfo(MyPacket, Packet);
				
				//
				// Copy the Media specific information
				//
				NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
					&MediaSpecificInfo,
					&MediaSpecificInfoSize);
				
				if (MediaSpecificInfo || MediaSpecificInfoSize)
				{
					NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
						MediaSpecificInfo,
						MediaSpecificInfoSize);
				}
				
				NdisSend(&Status,
					pAdapt->BindingHandle,
					MyPacket);
				
				if (Status != NDIS_STATUS_PENDING)
				{
					NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
					//NdisFreePacket(MyPacket);
					freePacketBufferAndMemory(MyPacket);
					ADAPT_DECR_PENDING_SENDS(pAdapt);
				}
			}
			while (FALSE);
			
			if (Status != NDIS_STATUS_PENDING)
			{
				NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
					Packet,
					Status);
			}
		}
		else //FILTER_STATUS_PASS
		{
			//按PASS处理
			KdPrint(("<== 微端口MPSendPackets方法,进入FILTER_STATUS_PASS模式\n"));
			freeMemory(pBuffer);
			//
			// The driver should fail the send if the virtual miniport is in low 
			// power state
			//
			if (pAdapt->MPDeviceState > NdisDeviceStateD0)
			{
				NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
								Packet,
								NDIS_STATUS_FAILURE);
				continue;
			}
			//这里原来有NDIS51的一个简化处理,放在此文件最下面了
			do 
			{
				NdisAcquireSpinLock(&pAdapt->Lock);
				//
				// If the below miniport is going to low power state, stop sending down any packet.
				//
				if (pAdapt->PTDeviceState > NdisDeviceStateD0)
				{
					NdisReleaseSpinLock(&pAdapt->Lock);
					Status = NDIS_STATUS_FAILURE;
					break;
				}
				pAdapt->OutstandingSends++;
				NdisReleaseSpinLock(&pAdapt->Lock);
            
				NdisAllocatePacket(&Status,
								   &MyPacket,
								   pAdapt->SendPacketPoolHandle);

				if (Status == NDIS_STATUS_SUCCESS)
				{
					PSEND_RSVD        SendRsvd;

					SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
					SendRsvd->OriginalPkt = Packet;

					NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
					NdisClearPacketFlags(MyPacket, NDIS_FLAGS_RESERVED4); //防止和上面的包混淆

					NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
					NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);

					//
					// Copy the OOB data from the original packet to the new
					// packet.
					//
					NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
								NDIS_OOB_DATA_FROM_PACKET(Packet),
								sizeof(NDIS_PACKET_OOB_DATA));
					//
					// Copy relevant parts of the per packet info into the new packet
					//
					NdisIMCopySendPerPacketInfo(MyPacket, Packet);

					//
					// Copy the Media specific information
					//
					NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
														&MediaSpecificInfo,
														&MediaSpecificInfoSize);

					if (MediaSpecificInfo || MediaSpecificInfoSize)
					{
						NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
															MediaSpecificInfo,
															MediaSpecificInfoSize);
					}

					NdisSend(&Status,
							 pAdapt->BindingHandle,
							 MyPacket);

					if (Status != NDIS_STATUS_PENDING)
					{
						NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
						NdisFreePacket(MyPacket);
						ADAPT_DECR_PENDING_SENDS(pAdapt);
					}
				}
				else
				{
					//
					// The driver cannot allocate a packet.
					// 
					ADAPT_DECR_PENDING_SENDS(pAdapt);
				}
			}
			while (FALSE);

			if (Status != NDIS_STATUS_PENDING)
			{
				NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
								  Packet,
								  Status);
			}
		}
    }
}
Ejemplo n.º 16
0
NDIS_STATUS
NdisuioReceive(
    IN NDIS_HANDLE                  ProtocolBindingContext,
    IN NDIS_HANDLE                  MacReceiveContext,
    IN PVOID                        pHeaderBuffer,
    IN UINT                         HeaderBufferSize,
    IN PVOID                        pLookaheadBuffer,
    IN UINT                         LookaheadBufferSize,
    IN UINT                         PacketSize
    )
/*++

Routine Description:

    Our protocol receive handler called by NDIS, typically if we have
    a miniport below that doesn't indicate packets.

    We make a local packet/buffer copy of this data, queue it up, and
    kick off the read service routine.

Arguments:

    ProtocolBindingContext - pointer to open context
    MacReceiveContext - for use in NdisTransferData
    pHeaderBuffer - pointer to data header
    HeaderBufferSize - size of the above
    pLookaheadBuffer - pointer to buffer containing lookahead data
    LookaheadBufferSize - size of the above
    PacketSize - size of the entire packet, minus header size.

Return Value:

    NDIS_STATUS_NOT_ACCEPTED - if this packet is uninteresting
    NDIS_STATUS_SUCCESS - if we processed this successfully

--*/
{
    PNDISUIO_OPEN_CONTEXT   pOpenContext;
    NDIS_STATUS             Status;
    PNDISUIO_ETH_HEADER     pEthHeader;
    PNDIS_PACKET            pRcvPacket;
    PUCHAR                  pRcvData;
    UINT                    BytesTransferred;
    PNDIS_BUFFER            pOriginalNdisBuffer, pPartialNdisBuffer;
    PIRP					pIrp;
    PLIST_ENTRY				pIrpEntry;
    ULONG					BytesRemaining; // at pDst
	PPACKET_GROUP			pGroup;

	//ULONG                   pDst;
	
    pOpenContext = (PNDISUIO_OPEN_CONTEXT)ProtocolBindingContext;
    NUIO_STRUCT_ASSERT(pOpenContext, oc);
    pRcvPacket = NULL;
    pRcvData = NULL;
    Status = NDIS_STATUS_SUCCESS;

    DEBUGP(DL_LOUD, ("Receive: Open %p, LookaheadBufferSize %d, PacketSize %d\n",
		pOpenContext, LookaheadBufferSize, PacketSize));
    
	NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->ReceivedPackets, 1);

	do
    {
        if (HeaderBufferSize != sizeof(NDISUIO_ETH_HEADER))
        {
            Status = NDIS_STATUS_NOT_ACCEPTED;
            break;
        }

        pEthHeader = (PNDISUIO_ETH_HEADER)pHeaderBuffer;

		NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);

		//
		// Someone is reading, and this is the first packet.
		//
		if (!NUIO_IS_LIST_EMPTY(&pOpenContext->PendedReads) &&
			NUIO_IS_LIST_EMPTY(&pOpenContext->RecvPktQueue))
		{
			//
			//  Get the first pended Read IRP
			//
			pIrpEntry = pOpenContext->PendedReads.Flink;
			pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);
			
			//
			// We don't have to worry about the situation where the IRP is cancelled
			// after we remove it from the queue and before we reset the cancel
			// routine because the cancel routine has been coded to cancel an IRP
			// only if it's in the queue.
			//
			IoSetCancelRoutine(pIrp, NULL);

			NUIO_REMOVE_ENTRY_LIST(pIrpEntry);
			
			pOpenContext->PendedReadCount--;

			NUIO_RELEASE_LOCK(&pOpenContext->Lock);

			NUIO_DEREF_OPEN(pOpenContext);  // Service: dequeue rcv packet

			//
			//  Copy as much data as possible from the receive packet to
			//  the IRP MDL.
			//
#ifndef WIN9X
			pGroup = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
			//NUIO_ASSERT(pDst != NULL);  // since it was already mapped
#else
			pGroup = MmGetSystemAddressForMdl(pIrp->MdlAddress);  // Win9x
#endif
			BytesRemaining = MmGetMdlByteCount(pIrp->MdlAddress);
			
			BytesRemaining -= sizeof(PACKET_GROUP);

			//
			//  copy the ethernet header into the actual readbuffer
			//
			NdisMoveMappedMemory(pGroup->Data, pHeaderBuffer, HeaderBufferSize);
			
			if (PacketSize == LookaheadBufferSize)
			{
				BytesTransferred = MIN(LookaheadBufferSize, BytesRemaining);

				NdisCopyLookaheadData(pGroup->Data + HeaderBufferSize,
					pLookaheadBuffer,
					BytesTransferred,
					pOpenContext->MacOptions);

				pGroup->Length = BytesTransferred + HeaderBufferSize;
				
				pIrp->IoStatus.Information = pGroup->Length + sizeof(PACKET_GROUP);
				pIrp->IoStatus.Status = STATUS_SUCCESS;				
		
				DEBUGP(DL_LOUD, ("Receive: %d bytes\n", pIrp->IoStatus.Information));
		
				IoCompleteRequest(pIrp, IO_NO_INCREMENT);
			}
			else
			{
				BytesTransferred = 0;

				NdisAllocatePacket(
					&Status,
					&pRcvPacket,
					pOpenContext->RecvBufferPool
					);
				
				if (Status != NDIS_STATUS_SUCCESS)
					goto ERROR;
				
				//
				//  Allocate an MDL to map the portion of the buffer following the
				//  header
				//
				pPartialNdisBuffer = IoAllocateMdl(pGroup->Data, BytesRemaining, FALSE, FALSE, NULL);
				
				if (pPartialNdisBuffer == NULL)
				{
					NdisFreePacket(pRcvPacket);
					Status = NDIS_STATUS_RESOURCES;
					goto ERROR;
				}
				
				//
				//  Build the mdl to point to the the portion of the buffer following
				//  the header
				//
				IoBuildPartialMdl(
					pIrp->MdlAddress,
					pPartialNdisBuffer,
					pGroup->Data + HeaderBufferSize,
					0);
				
				//
				//  Clear the next link in the new MDL
				//
				
				pPartialNdisBuffer->Next = NULL;
				
				//
				//  Get a pointer to the packet itself.
				//
				
				NUIO_IRP_FROM_RCV_PKT(pRcvPacket) = pIrp;
				NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pRcvPacket) = pPartialNdisBuffer;
				
				//
				//  Attach our partial MDL to the packet
				//
				
				NdisChainBufferAtFront(pRcvPacket, pPartialNdisBuffer);
				
				//
				//  Call the Mac to transfer the packet
				//
				
				NdisTransferData(
					&Status,
					pOpenContext->BindingHandle,
					MacReceiveContext,
					0,  // ByteOffset
					PacketSize,
					pRcvPacket,
					&BytesTransferred);

ERROR:					
				//
				//  If it didn't pend, call the completeion routine now
				//
				if (Status != NDIS_STATUS_PENDING)
				{
					NdisuioTransferDataComplete(
						(NDIS_HANDLE)pOpenContext,
						pRcvPacket,
						Status,
						BytesTransferred);
				}
			}

			break;
		}

		NUIO_RELEASE_LOCK(&pOpenContext->Lock);

		//
        //  Allocate resources for queueing this up.
        //
        pRcvPacket = ndisuioAllocateReceivePacket(
			pOpenContext,
			PacketSize + HeaderBufferSize,
			&pRcvData
			);

        if (pRcvPacket == NULL)
        {
            Status = NDIS_STATUS_NOT_ACCEPTED;
            break;
        }

        NdisMoveMappedMemory(pRcvData, pHeaderBuffer, HeaderBufferSize);

        //
        //  Check if the entire packet is within the lookahead.
        //
        if (PacketSize == LookaheadBufferSize)
        {
            NdisCopyLookaheadData(pRcvData + HeaderBufferSize,
                                  pLookaheadBuffer,
                                  LookaheadBufferSize,
                                  pOpenContext->MacOptions);
            //
            //  Queue this up for receive processing, and
            //  try to complete some read IRPs.
            //
            ndisuioQueueReceivePacket(pOpenContext, pRcvPacket);
        }
        else
        {
            //
            //  Allocate an NDIS buffer to map the receive area
            //  at an offset "HeaderBufferSize" from the current
            //  start. This is so that NdisTransferData can copy
            //  in at the right point in the destination buffer.
            //

            NdisAllocateBuffer(
                &Status,
                &pPartialNdisBuffer,
                pOpenContext->RecvBufferPool,
                pRcvData + HeaderBufferSize,
                PacketSize);
            
            if (Status == NDIS_STATUS_SUCCESS)
            {
                //
                //  Unlink and save away the original NDIS Buffer
                //  that maps the full receive buffer.
                //
                NdisUnchainBufferAtFront(pRcvPacket, &pOriginalNdisBuffer);
                NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pRcvPacket) = pOriginalNdisBuffer;
				NUIO_IRP_FROM_RCV_PKT(pRcvPacket) = NULL;

                //
                //  Link in the partial buffer for NdisTransferData to
                //  operate on.
                //
                NdisChainBufferAtBack(pRcvPacket, pPartialNdisBuffer);

                DEBUGP(DL_LOUD, ("Receive: setting up for TransferData:"
                        " Pkt %p, OriginalBuf %p, PartialBuf %p\n",
                        pRcvPacket, pOriginalNdisBuffer, pPartialNdisBuffer));

                NdisTransferData(
                    &Status,
                    pOpenContext->BindingHandle,
                    MacReceiveContext,
                    0,  // ByteOffset
                    PacketSize,
                    pRcvPacket,
                    &BytesTransferred);
            }
            else
            {
                //
                //  Failure handled below in TransferDataComplete.
                //
                BytesTransferred = 0;
            }
    
            if (Status != NDIS_STATUS_PENDING)
            {
                NdisuioTransferDataComplete(
                    (NDIS_HANDLE)pOpenContext,
                    pRcvPacket,
                    Status,
                    BytesTransferred);
            }
        }
    } while (FALSE);

	if (Status != NDIS_STATUS_SUCCESS && Status != NDIS_STATUS_PENDING)
		NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->DroppedPackets, 1);

    return Status;
}
Ejemplo n.º 17
0
NDIS_STATUS
MPSend(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN PNDIS_PACKET            Packet,
    IN UINT                    Flags
    )
/*++

Routine Description:

    Send Packet handler. Either this or our SendPackets (array) handler is called
    based on which one is enabled in our Miniport Characteristics.

Arguments:

    MiniportAdapterContext    Pointer to the adapter
    Packet                    Packet to send
    Flags                     Unused, passed down below

Return Value:

    Return code from NdisSend

--*/
{
    PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS         Status;
	FILTER_STATUS		fStatus;
    PNDIS_PACKET        MyPacket;
    PVOID               MediaSpecificInfo = NULL;
    ULONG               MediaSpecificInfoSize = 0;

    //
    // The driver should fail the send if the virtual miniport is in low 
    // power state
    //
    if (pAdapt->MPDeviceState > NdisDeviceStateD0)
    {
         return NDIS_STATUS_FAILURE;
    }
	//***************************此函数作废!!!!!!!!!!!!!!!************************************
	//KdPrint(("微端口MPSend方法,开始报文分析\n"));
	fStatus = AnalysisPacket(Packet, MODE_SEND);
	//getPacketBuffer(Packet, )
	//fStatus = FILTER_STATUS_PASS;
	if (fStatus == FILTER_STATUS_DROP)
	{
		return NDIS_STATUS_FAILURE;
	}
	else if(fStatus == FILTER_STATUS_MODIFY_REDIRECT)
	{
		// 转发......
		// 修改包中的目标地址,和正常发送一样将包向下发送
		// TODO.
	}

#ifdef NDIS51
    //
    // Use NDIS 5.1 packet stacking:
    //
    {
        PNDIS_PACKET_STACK        pStack;
        BOOLEAN                   Remaining;

        //
        // Packet stacks: Check if we can use the same packet for sending down.
        //

        pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
        if (Remaining)
        {
            //
            // We can reuse "Packet".
            //
            // NOTE: if we needed to keep per-packet information in packets
            // sent down, we can use pStack->IMReserved[].
            //
            ASSERT(pStack);
            //
            // If the below miniport is going to low power state, stop sending down any packet.
            //
            NdisAcquireSpinLock(&pAdapt->Lock);
            if (pAdapt->PTDeviceState > NdisDeviceStateD0)
            {
                NdisReleaseSpinLock(&pAdapt->Lock);
                return NDIS_STATUS_FAILURE;
            }
            pAdapt->OutstandingSends++;
            NdisReleaseSpinLock(&pAdapt->Lock);
            NdisSend(&Status,
                     pAdapt->BindingHandle,
                     Packet);

            if (Status != NDIS_STATUS_PENDING)
            {
                ADAPT_DECR_PENDING_SENDS(pAdapt);
            }

            return(Status);
        }
    }
#endif // NDIS51

    //
    // We are either not using packet stacks, or there isn't stack space
    // in the original packet passed down to us. Allocate a new packet
    // to wrap the data with.
    //
    //
    // If the below miniport is going to low power state, stop sending down any packet.
    //
    NdisAcquireSpinLock(&pAdapt->Lock);
    if (pAdapt->PTDeviceState > NdisDeviceStateD0)
    {
        NdisReleaseSpinLock(&pAdapt->Lock);
        return NDIS_STATUS_FAILURE;
    
    }
    pAdapt->OutstandingSends++;
    NdisReleaseSpinLock(&pAdapt->Lock);
    
    NdisAllocatePacket(&Status,
                       &MyPacket,
                       pAdapt->SendPacketPoolHandle);

    if (Status == NDIS_STATUS_SUCCESS)
    {
        PSEND_RSVD            SendRsvd;

        //
        // Save a pointer to the original packet in our reserved
        // area in the new packet. This is needed so that we can
        // get back to the original packet when the new packet's send
        // is completed.
        //
        SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
        SendRsvd->OriginalPkt = Packet;

        NdisGetPacketFlags(MyPacket) = Flags;

        //
        // Set up the new packet so that it describes the same
        // data as the original packet.
        //
        NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
        NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);
#ifdef WIN9X
        //
        // Work around the fact that NDIS does not initialize this
        // to FALSE on Win9x.
        //
        NDIS_PACKET_VALID_COUNTS(MyPacket) = FALSE;
#endif

        //
        // Copy the OOB Offset from the original packet to the new
        // packet.
        //
        NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
                       NDIS_OOB_DATA_FROM_PACKET(Packet),
                       sizeof(NDIS_PACKET_OOB_DATA));

#ifndef WIN9X
        //
        // Copy the right parts of per packet info into the new packet.
        // This API is not available on Win9x since task offload is
        // not supported on that platform.
        //
        NdisIMCopySendPerPacketInfo(MyPacket, Packet);
#endif
        
        //
        // Copy the Media specific information
        //
        NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
                                            &MediaSpecificInfo,
                                            &MediaSpecificInfoSize);

        if (MediaSpecificInfo || MediaSpecificInfoSize)
        {
            NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
                                                MediaSpecificInfo,
                                                MediaSpecificInfoSize);
        }

        NdisSend(&Status,
                 pAdapt->BindingHandle,
                 MyPacket);


        if (Status != NDIS_STATUS_PENDING)
        {
#ifndef WIN9X
            NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
#endif
            NdisFreePacket(MyPacket);
            ADAPT_DECR_PENDING_SENDS(pAdapt);
        }
    }
    else
    {
        ADAPT_DECR_PENDING_SENDS(pAdapt);
        //
        // We are out of packets. Silently drop it. Alternatively we can deal with it:
        //    - By keeping separate send and receive pools
        //    - Dynamically allocate more pools as needed and free them when not needed
        //
    }

    return(Status);
}
Ejemplo n.º 18
0
NTSTATUS netgSendToMiniport(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) {
	PIO_STACK_LOCATION  pIrpSp;
	NTSTATUS            NtStatus = STATUS_SUCCESS;
	NDIS_STATUS         Status;
	ULONG               BytesReturned = 0;
	PUCHAR              ioBuffer = NULL;
	ULONG               inputBufferLength;
	ULONG               outputBufferLength, Remaining;
	POPEN_CONTEXT       pOpenContext;
	PNDIS_PACKET        pNdisPacket;
    PNDIS_BUFFER        pNdisBuffer;

	DBGPRINT(("      netgSendToMiniport Called \n"));

	UNREFERENCED_PARAMETER(pDeviceObject);

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

	pOpenContext = pIrpSp->FileObject->FsContext;
	ioBuffer = pIrp->AssociatedIrp.SystemBuffer;
	inputBufferLength  = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
	outputBufferLength = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
	Remaining = outputBufferLength;

	DBGPRINT(("==> netgSendToMiniport: FileObject %p\n", pIrpSp->FileObject ));

	if( !pOpenContext ) {
		DBGPRINT(( "      Invalid Handle\n" ));
		NtStatus = STATUS_INVALID_HANDLE;
		goto CompleteTheIRP;
	}

	DBGPRINT(("     Len: %d Data: %x%x...\n", pIrpSp->Parameters.DeviceIoControl.InputBufferLength, ioBuffer[0], ioBuffer[1]));

	// Allocate a send packet.
	pNdisPacket = NULL;
	NdisAllocatePacket(&Status, &pNdisPacket, pOpenContext->SendPacketPool);
	if (Status != NDIS_STATUS_SUCCESS) {
		DBGPRINT(("     netgSendToMiniport: open %p, failed to alloc send pkt\n", pOpenContext));
        NtStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto CompleteTheIRP;
    }

	// Allocate a send buffer.
	NdisAllocateBuffer(&Status, &pNdisBuffer, pOpenContext->SendBufferPool, ioBuffer, inputBufferLength);
    if (Status != NDIS_STATUS_SUCCESS) {
        NdisFreePacket(pNdisPacket);
        DBGPRINT(("     netgSendToMiniport: open %p, failed to alloc send buf\n", pOpenContext));
        NtStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto CompleteTheIRP;
	}

	IoMarkIrpPending(pIrp);
	((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->RefCount = 1;
	(((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->pIrp) = pIrp;
	NtStatus = STATUS_PENDING;

	pNdisBuffer->Next = NULL;
	NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
	NdisSendPackets(pOpenContext->pAdapt->BindingHandle, &pNdisPacket, 1);

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

	DBGPRINT(("<== netgSendToMiniport\n"));
	return NtStatus;
}
Ejemplo n.º 19
0
VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
  // allocate a buffer for reading/writing

  PNDIS_BUFFER pNdisBuffer;
  PNDIS_PACKET pPacket;
  

  //  Try to get a packet from our list of free ones
  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);
  
  if (*pStatus != NDIS_STATUS_SUCCESS) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    return;
  }
  
  pPacket = *ppPacket;
  
  // Buffers used asynchronously must be page locked
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
      break;
    
    case IOCTL_EPACKET_WRITE:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
      break;
    
    default:
      // recycle the packet
      NdisReinitializePacket(pPacket);
    
      // Put the packet on the free queue
      NdisFreePacket(pPacket);
    
      *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      *pStatus = NDIS_STATUS_NOT_ACCEPTED;
      return;
  }
  
  RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;
  
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                         pDiocParms->cbOutBuffer);
      break;
    
    case IOCTL_EPACKET_WRITE:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)RESERVED(pPacket)->lpBuffer,
                         pDiocParms->cbInBuffer);
      break;
  }
  
  if (*pStatus == NDIS_STATUS_SUCCESS)
    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet
  else {
    NdisReinitializePacket(pPacket);  // recycle the packet
    NdisFreePacket(pPacket);          // Put the packet on the free queue
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
  }
}
Ejemplo n.º 20
0
int divert_filter(
   IN PADAPT         pAdapt,
   IN NDIS_HANDLE    MacReceiveContext,
   IN PVOID          HeaderBuffer,
   IN UINT           HeaderBufferSize,
   IN PVOID          LookAheadBuffer,
   IN UINT           LookAheadBufferSize,
   IN UINT           PacketSize
   )
{
#define MAC_SIZE 14
	USHORT               EtherType;
	ULONG                NumberOfBytesRead;
	struct ether_header  *pEthHdr;      // See ../B2Winet/ethernet.h
	struct ip            *pIPHeader;
	struct tcphdr	     *tcp;
	int rc = 0;
	struct divert_packet *dp, *cur;
	NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	NdisDprAcquireSpinLock(&pAdapt->Lock);

	pEthHdr = (struct ether_header * )HeaderBuffer;
	pEthHeader = pEthHdr;

	if (ntohs( pEthHdr->ether_type ) != ETHERTYPE_IP)
		goto Out;

	if (get_pa(pEthHeader->SrcAddr))
		goto Out;

	pIPHeader = (struct ip * )LookAheadBuffer;

	if (LookAheadBufferSize < 40)
		goto Out;

	if (pIPHeader->ip_p != IPPROTO_TCP)
		goto Out;

	tcp = (struct tcphr*) (pIPHeader + 1);

#if 0
	if (ntohs(tcp->th_dport) == 666)
		rc = 1;
#endif

	lock();

	if (!_open)
		goto Outl;

	dp = get_packet();
	if (!dp) {
		DbgPrint("Out of queue - shit\n");
		goto Outl;
	}

	if (LookAheadBufferSize != PacketSize) {
		NDIS_STATUS status;
		PNDIS_PACKET pkt;
		PNDIS_BUFFER buf;
		int len;

		if ((PacketSize + MAC_SIZE) > sizeof(dp->dp_packet)) {
			DbgPrint("cAZZOOOOOOOOOOOOOOOOOOOOOOOOOOo\n");
			goto Fanculo;
		}

		NdisAllocatePacket(&status, &pkt, _packet_pool);
		NdisAllocateBuffer(&status, &buf, _buf_pool,
				   dp->dp_packet + MAC_SIZE,
				   sizeof(dp->dp_packet) - MAC_SIZE);
		NdisChainBufferAtFront(pkt, buf);
		NdisTransferData(&status, pAdapt->BindingHandle,
				 MacReceiveContext, 0,
				 PacketSize, pkt, &len);
		NdisFreeBuffer(buf);
		NdisFreePacket(pkt);
	} else {
		NdisCopyLookaheadData(dp->dp_packet + MAC_SIZE,
				      LookAheadBuffer,
				      LookAheadBufferSize,
				      0);
	}

Fanculo:
	rc = 1;

	memcpy(dp->dp_packet, pEthHdr, MAC_SIZE);

	dp->dp_len   = PacketSize + MAC_SIZE;
	dp->dp_flags = 1;

	kick_pending();

Outl:
	unlock();
Out:
	NdisDprReleaseSpinLock(&pAdapt->Lock);

	return rc;
#undef MAC_SIZE
}
Ejemplo n.º 21
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.º 22
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;
}
Ejemplo n.º 23
0
NTSTATUS
SendPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN  PTP_ADDRESS			Address,
	IN  UCHAR				DestinationAddressNode[],
	IN	PUCHAR				UserData,
	IN	ULONG				UserDataLength,
	IN	PIO_STACK_LOCATION	IrpSp,
	IN  UCHAR				Option,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetHeader = NULL;
	PNDIS_BUFFER	packetHeaderBuffer = NULL;
	ULONG			packetHeaderLength;

	PNDIS_BUFFER	userDataBuffer = NULL;
	PUCHAR			paddingData = NULL;
	PNDIS_BUFFER	paddingDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;
	USHORT			etherType;


	packetHeaderLength = ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}
	if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	ASSERT( packetHeaderLength + UserDataLength <= ETHERNET_HEADER_LENGTH + DeviceContext->MaxUserData );
	
	DebugPrint( 3, ("SendPacketAlloc, packetHeaderLength = %d, NumberOfAllockPackets = %d\n", packetHeaderLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( FALSE );
			LPX_ASSERT( status == NDIS_STATUS_RESOURCES );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

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

		packetHeader = (PCHAR)&RESERVED(packet)->EthernetHeader;

		NdisAllocateBuffer( &status,
							&packetHeaderBuffer,
							DeviceContext->LpxBufferPool,
							packetHeader,
							packetHeaderLength );

		if (!NT_SUCCESS(status)) {

			ASSERT( status == NDIS_STATUS_FAILURE ); 
			ASSERT( FALSE );
			break;
		}

		if (UserData && UserDataLength) {
			
			NdisAllocateBuffer( &status,
								&userDataBuffer,
								DeviceContext->LpxBufferPool,
								UserData,
								UserDataLength );

			if(!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}
		}

//////////////////////////////////////////////////////////////////////////
//
//	Add padding to fix Under-60byte bug of NDAS chip 2.0.
//

		if (packetHeaderLength == ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER)) {

			UINT		    totalPacketLength;

			totalPacketLength = packetHeaderLength + UserDataLength;

			if (totalPacketLength >= ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER) + 4 && totalPacketLength <= 56) {

			    LONG			paddingLen = 60 - totalPacketLength;
			
				DebugPrint( 4, ("[LpxSmp]TransmitDataPacket: Adding padding to support NDAS chip 2.0\n") );

				status = LpxAllocateMemoryWithLpxTag( &paddingData, paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				NdisAllocateBuffer( &status,
									&paddingDataBuffer,
									DeviceContext->LpxBufferPool,
									paddingData,
									paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				RtlZeroMemory( paddingData, paddingLen );

				RtlCopyMemory( paddingData + paddingLen - 4, UserData + UserDataLength - 4, 4 );
			}
		}

//
//	End of padding routine.
//
//////////////////////////////////////////////////////////////////////////

	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RtlCopyMemory( &packetHeader[0],
					   DestinationAddressNode,
					   ETHERNET_ADDRESS_LENGTH );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH],
					   Address->NetworkName->Node,
					   ETHERNET_ADDRESS_LENGTH );

		etherType = HTONS( ETH_P_LPX );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH*2],
					   &etherType,
					   2 );

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
						   DestinationAddressNode,
						   ETHERNET_ADDRESS_LENGTH );	
		}

		if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

			if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		
				RtlCopyMemory( RESERVED(packet)->OptionSourceAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			
			} else {
			
				RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			}
		}

#endif

		RESERVED(packet)->LpxHeader.PacketSize = HTONS( (USHORT)(packetHeaderLength - ETHERNET_HEADER_LENGTH + UserDataLength) );
		RESERVED(packet)->LpxHeader.Option = Option;

		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->IrpSp  = IrpSp;
		RESERVED(packet)->Type   = LPX_PACKET_TYPE_SEND;
		RESERVED(packet)->Packet = packet;
		
		if (IrpSp == NULL) {

			DebugPrint( 3, ("[LPX] PacketAllocate: No IrpSp\n") ) ;
		}
	
		if (paddingDataBuffer)
			NdisChainBufferAtFront( packet, paddingDataBuffer );
		
		if (userDataBuffer)
			NdisChainBufferAtFront( packet, userDataBuffer );
		
		NdisChainBufferAtFront( packet, packetHeaderBuffer );

		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
	} else {

		if (paddingDataBuffer)
			NdisFreeBuffer( paddingDataBuffer );

		if( paddingData)
			LpxFreeMemoryWithLpxTag( paddingData );

		if (userDataBuffer)
			NdisFreeBuffer( userDataBuffer );

		if (packetHeaderBuffer)
			NdisFreeBuffer( packetHeaderBuffer );
		
		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n") );
	}

	return status;
}
Ejemplo n.º 24
0
NDIS_STATUS
MPSend(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN PNDIS_PACKET            Packet,
    IN UINT                    Flags
    )
/*++

Routine Description:

    Send Packet handler. Either this or our SendPackets (array) handler is called
    based on which one is enabled in our Miniport Characteristics.

Arguments:

    MiniportAdapterContext    Pointer to the adapter
    Packet                    Packet to send
    Flags                     Unused, passed down below

Return Value:

    Return code from NdisSend

--*/
{
    PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS         Status;
    PNDIS_PACKET        MyPacket;
    PVOID               MediaSpecificInfo = NULL;
    ULONG               MediaSpecificInfoSize = 0;
    ULONG               SndFltAction;

    //
    // The driver should fail the send if the virtual miniport is in low 
    // power state
    //
    if (pAdapt->MPDeviceState > NdisDeviceStateD0) {
         return NDIS_STATUS_FAILURE;
    }

	//
	// Call Send Packet Filter
	//
	SndFltAction = FltFilterSendPacket(
                     pAdapt,
                     Packet,
                     TRUE     // Caller is running at IRQL DISPATCH_LEVEL
                     );

	//
	// Possibly Block (Drop) Packet
	// ----------------------------
	// Lying send. Report SUCCESS, even though it really hasn't
	// been sent.
	//
	if( SndFltAction & ACTION_BLOCK_PACKET) {
      return NDIS_STATUS_SUCCESS;
   }

#ifdef NDIS51
    //
    // Use NDIS 5.1 packet stacking:
    //
    {
        PNDIS_PACKET_STACK        pStack;
        BOOLEAN                   Remaining;

        //
        // Packet stacks: Check if we can use the same packet for sending down.
        //

        pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
        if (Remaining)
        {
            //
            // We can reuse "Packet".
            //
            // NOTE: if we needed to keep per-packet information in packets
            // sent down, we can use pStack->IMReserved[].
            //
            ASSERT(pStack);
            //
            // If the below miniport is going to low power state, stop sending down any packet.
            //
            NdisAcquireSpinLock(&pAdapt->Lock);
            if (pAdapt->PTDeviceState > NdisDeviceStateD0)
            {
                NdisReleaseSpinLock(&pAdapt->Lock);
                return NDIS_STATUS_FAILURE;
            }
            pAdapt->OutstandingSends++;
            NdisReleaseSpinLock(&pAdapt->Lock);
            NdisSend(&Status,
                     pAdapt->BindingHandle,
                     Packet);

            if (Status != NDIS_STATUS_PENDING)
            {
                ADAPT_DECR_PENDING_SENDS(pAdapt);
            }

            return(Status);
        }
    }
#endif // NDIS51

    //
    // We are either not using packet stacks, or there isn't stack space
    // in the original packet passed down to us. Allocate a new packet
    // to wrap the data with.
    //
    //
    // If the below miniport is going to low power state, stop sending down any packet.
    //
    NdisAcquireSpinLock(&pAdapt->Lock);
    if (pAdapt->PTDeviceState > NdisDeviceStateD0)
    {
        NdisReleaseSpinLock(&pAdapt->Lock);
        return NDIS_STATUS_FAILURE;
    
    }
    pAdapt->OutstandingSends++;
    NdisReleaseSpinLock(&pAdapt->Lock);
    
    NdisAllocatePacket(&Status,
                       &MyPacket,
                       pAdapt->SendPacketPoolHandle);

    if (Status == NDIS_STATUS_SUCCESS)
    {
        PSEND_RSVD            SendRsvd;

        //
        // Save a pointer to the original packet in our reserved
        // area in the new packet. This is needed so that we can
        // get back to the original packet when the new packet's send
        // is completed.
        //
        SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
        SendRsvd->OriginalPkt = Packet;

        MyPacket->Private.Flags = Flags;

        //
        // Set up the new packet so that it describes the same
        // data as the original packet.
        //
        MyPacket->Private.Head = Packet->Private.Head;
        MyPacket->Private.Tail = Packet->Private.Tail;
#ifdef WIN9X
        //
        // Work around the fact that NDIS does not initialize this
        // to FALSE on Win9x.
        //
        MyPacket->Private.ValidCounts = FALSE;
#endif

        //
        // Copy the OOB Offset from the original packet to the new
        // packet.
        //
        NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
                       NDIS_OOB_DATA_FROM_PACKET(Packet),
                       sizeof(NDIS_PACKET_OOB_DATA));

#ifndef WIN9X
        //
        // Copy the right parts of per packet info into the new packet.
        // This API is not available on Win9x since task offload is
        // not supported on that platform.
        //
        NdisIMCopySendPerPacketInfo(MyPacket, Packet);
#endif
        
        //
        // Copy the Media specific information
        //
        NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
                                            &MediaSpecificInfo,
                                            &MediaSpecificInfoSize);

        if (MediaSpecificInfo || MediaSpecificInfoSize)
        {
            NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
                                                MediaSpecificInfo,
                                                MediaSpecificInfoSize);
        }

        NdisSend(&Status,
                 pAdapt->BindingHandle,
                 MyPacket);


        if (Status != NDIS_STATUS_PENDING)
        {
#ifndef WIN9X
            NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
#endif
            NdisFreePacket(MyPacket);
            ADAPT_DECR_PENDING_SENDS(pAdapt);
        }
    }
    else
    {
        ADAPT_DECR_PENDING_SENDS(pAdapt);
        //
        // We are out of packets. Silently drop it. Alternatively we can deal with it:
        //    - By keeping separate send and receive pools
        //    - Dynamically allocate more pools as needed and free them when not needed
        //
    }

    return(Status);
}
Ejemplo n.º 25
0
NTSTATUS
RcvPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN	ULONG				PacketDataLength,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetData = NULL;
	PNDIS_BUFFER	packetDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;


	DebugPrint( 3, ("RcvPacketAlloc, PacketLength = %d, NumberOfAllockPackets = %d\n", PacketDataLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	ASSERT( PacketDataLength <= DeviceContext->MaxUserData );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( status == NDIS_STATUS_RESOURCES );
			ASSERT( FALSE );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

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

		if (PacketDataLength) {
		
			status = LpxAllocateMemoryWithLpxTag( &packetData,
												  PacketDataLength );

			if (status != NDIS_STATUS_SUCCESS) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
			
				break;
			}

			NdisAllocateBuffer( &status,
								&packetDataBuffer,
								DeviceContext->LpxBufferPool,
								packetData,
								PacketDataLength );

			if (!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}

			NdisChainBufferAtFront( packet, packetDataBuffer );
		}
	
	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE;
		RESERVED(packet)->Packet = packet;
	
		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
#if __LPX_STATISTICS__
		
		KeQuerySystemTime( &RESERVED(packet)->RecvTime2 );
		RESERVED(packet)->DeviceContext = DeviceContext;

#endif

	} else {

		if (packetDataBuffer)
			NdisFreeBuffer( packetDataBuffer );
		
		if (packetData)
			LpxFreeMemoryWithLpxTag( packetData );

		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]RcvPacketAlloc: Can't Allocate Buffer For CopyData!!!\n") );
	}

	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
NTSTATUS
PacketAllocate(
    IN	PSERVICE_POINT		ServicePoint,
    IN	ULONG				PacketLength,
    IN	PDEVICE_CONTEXT		DeviceContext,
    IN	UCHAR				Type,
    IN	PUCHAR				CopyData,
    IN	ULONG				CopyDataLength,
    IN	PIO_STACK_LOCATION	IrpSp,
    OUT	PNDIS_PACKET		*Packet
)
{
    NTSTATUS		status;
    PUCHAR			packetData;
    PNDIS_BUFFER	pNdisBuffer;
    PNDIS_BUFFER	pNdisBufferData;
    PNDIS_PACKET	packet;
    USHORT			port;

    DebugPrint(3, ("PacketAllocate, PacketLength = %d, Numberofpackets = %d\n", PacketLength, NumberOfPackets));

    //	if(ServicePoint && ServicePoint->SmpState == SMP_SYN_RECV)
    //		return STATUS_INSUFFICIENT_RESOURCES;

    if(DeviceContext == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

    if(DeviceContext->LpxPacketPool == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext->LpxPacketPool is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

    NdisAllocatePacket(&status,	&packet, DeviceContext->LpxPacketPool);

    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LPX]PacketAllocate: NdisAllocatePacket Failed!!!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = NdisAllocateMemory(
                 &packetData,
                 PacketLength
             );
    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LpxSmp]PacketAllocate: Can't Allocate Memory packet.\n"));

        NdisFreePacket(packet);
        *Packet = NULL;

        return status;
    }

    NdisAllocateBuffer(
        &status,
        &pNdisBuffer,
        DeviceContext->LpxBufferPool,
        packetData,
        PacketLength
    );
    if(!NT_SUCCESS(status)) {
        NdisFreePacket(packet);
        *Packet = NULL;
        NdisFreeMemory(packetData);
        DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer!!!\n"));

        return status;
    }

    switch(Type) {

    case SEND_TYPE:

        if(ServicePoint && &ServicePoint->SmpContext) {
            RtlCopyMemory(&packetData[0],
                          ServicePoint->DestinationAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH],
                          ServicePoint->SourceAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            port = HTONS(ETH_P_LPX);
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH*2],
                          &port, //&ServicePoint->DestinationAddress.Port,
                          2
                         );
        }

        if(CopyDataLength) {

            NdisAllocateBuffer(
                &status,
                &pNdisBufferData,
                DeviceContext->LpxBufferPool,
                CopyData,
                CopyDataLength
            );
            if(!NT_SUCCESS(status)) {
                NdisFreePacket(packet);
                *Packet = NULL;
                NdisFreeMemory(packetData);
                DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n"));

                return status;
            }

            NdisChainBufferAtFront(packet, pNdisBufferData);
        }
        break;

    case RECEIVE_TYPE:

        NdisMoveMappedMemory(
            packetData,
            CopyData,
            CopyDataLength
        );

        break;
    }

    //	RESERVED(packet)->ServicePoint = ServicePoint;
    RESERVED(packet)->Cloned = 0;
    RESERVED(packet)->IrpSp = IrpSp;
    RESERVED(packet)->Type = Type;
    RESERVED(packet)->LpxSmpHeader = NULL;

    if(IrpSp == NULL) {
        DebugPrint(2, ("[LPX] PacketAllocate: No IrpSp\n")) ;
    }

    NdisChainBufferAtFront(packet, pNdisBuffer);

    InterlockedIncrement(&NumberOfPackets);

    *Packet = packet;
    return STATUS_SUCCESS;
}