static Boolean
ssh_wan_alloc_buffer(SshInterceptor interceptor,
                     SshUInt32 length,
                     SshNetDataBuffer *buf_return,
                     unsigned char **buf_addr_return)
{
  SshCpuContext cpu_ctx;
  SshNetDataBuffer buffer;
  unsigned char *buf_addr;
  SshUInt32 buf_size;

  SSH_ASSERT(interceptor != NULL);
  SSH_ASSERT(buf_return != NULL);
  SSH_ASSERT(buf_addr_return != NULL);

  ssh_kernel_critical_section_start(&interceptor->packet_pool_cs);
  cpu_ctx = &interceptor->cpu_ctx[ssh_kernel_get_cpu()];
  buffer = ssh_net_buffer_alloc(interceptor, &cpu_ctx->packet_pool);
  ssh_kernel_critical_section_end(&interceptor->packet_pool_cs);  

  if (buffer == NULL)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Out of buffer pool!"));
      return FALSE;
    }

  SSH_RESET_BUFFER(buffer, 0);  

  if (buffer->total_size < length)
    {
      ssh_wan_free_buffer(interceptor, buffer);
      SSH_DEBUG(SSH_D_FAIL, 
                ("Could not allocate contiguous buffer (%u bytes "
                 "requested)", length));
      return FALSE;
    }

  NdisAdjustBufferLength(buffer->nb, length);
  buffer->data_len = length;

  if (!ssh_query_data_block(buffer->nb, &buf_addr, &buf_size))
    {
      ssh_wan_free_buffer(interceptor, buffer);
      SSH_DEBUG(SSH_D_FAIL,
                ("Failed to query buffer address!"));
      return FALSE;
    }

  *buf_return = buffer;
  *buf_addr_return = buf_addr;

  return TRUE;
}
Exemple #2
0
// Process the received packet
void NeoWrite(void *buf)
{
	UINT num, i, size;
	void *packet_buf;
	// Validate arguments
	if (buf == NULL)
	{
		return;
	}

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

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

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

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

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

		packet_buf = NEO_ADDR_OF_PACKET(buf, i);

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

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

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

	if (g_is_win8 == false)
	{
		NdisMIndicateReceivePacket(ctx->NdisMiniport, ctx->PacketBufferArray, num);
	}
}
VOID
NICIndicateReceivedPacket(
    IN PRCB             pRCB,
	IN ULONG            dataoffset,
    IN ULONG            BytesToIndicate,
	IN ULONG            PacketNum
    )
/*++

Routine Description:

    Initialize the packet to describe the received data and
    indicate to NDIS.
        
Arguments:

    pRCB - pointer to the RCB block    
    BytesToIndicate - number of bytes to indicate

Return value:

    VOID
--*/
{
    ULONG           PacketLength;
    PNDIS_BUFFER    CurrentBuffer = NULL;
    PETH_HEADER     pEthHeader = NULL;
    PMP_ADAPTER     Adapter = pRCB->Adapter;
    KIRQL           oldIrql;	
	PVOID  VirtualAddress=NULL;
	ASSERT(     PacketNum   <    RCB_BUFFERARRAY_SIZE);
	ASSERT((dataoffset+BytesToIndicate) <  pRCB->ulBufferSize);


    

	
    //NdisAdjustBufferLength(pRCB->Buffer, BytesToIndicate);
	//MmInitializeMdl(pRCB->BufferArray[PacketNum],pRCB->pDataForNTB+dataoffset,BytesToIndicate);
	VirtualAddress=MmGetMdlVirtualAddress(pRCB->BufferArray[PacketNum]);
	ASSERT(VirtualAddress!=NULL);
	NdisMoveMemory(VirtualAddress,pRCB->pDataForNTB+dataoffset,BytesToIndicate);
	NdisAdjustBufferLength(pRCB->BufferArray[PacketNum], BytesToIndicate);
	//NdisMoveMemory(pRCB->pDataForNet+NIC_BUFFER_SIZE*PacketNum,pRCB->pDataForNTB+dataoffset,BytesToIndicate);
    //
    // Prepare the recv packet
    //

    NdisReinitializePacket(pRCB->PacketArray[PacketNum]);

    *((PRCB *)pRCB->PacketArray[PacketNum]->MiniportReserved) = pRCB;

    //
    // Chain the TCB buffers to the packet
    //
    NdisChainBufferAtBack(pRCB->PacketArray[PacketNum], pRCB->BufferArray[PacketNum]);

    NdisQueryPacket(pRCB->PacketArray[PacketNum], NULL, NULL, &CurrentBuffer, (PUINT) &PacketLength);

    ASSERT(CurrentBuffer == pRCB->BufferArray[PacketNum]);

    pEthHeader = (PETH_HEADER)(pRCB->pDataForNTB+dataoffset);

    if(PacketLength >= sizeof(ETH_HEADER) && 
        Adapter->PacketFilter &&
        NICIsPacketAcceptable(Adapter, pEthHeader->DstAddr)){
            
        DEBUGP(MP_LOUD, ("Src Address = %02x-%02x-%02x-%02x-%02x-%02x", 
            pEthHeader->SrcAddr[0],
            pEthHeader->SrcAddr[1],
            pEthHeader->SrcAddr[2],
            pEthHeader->SrcAddr[3],
            pEthHeader->SrcAddr[4],
            pEthHeader->SrcAddr[5]));

        DEBUGP(MP_LOUD, ("  Dest Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 
            pEthHeader->DstAddr[0],
            pEthHeader->DstAddr[1],
            pEthHeader->DstAddr[2],
            pEthHeader->DstAddr[3],
            pEthHeader->DstAddr[4],
            pEthHeader->DstAddr[5]));

        DEBUGP(MP_LOUD, ("Indicating packet = %p, Packet Length = %d\n", 
                            pRCB->PacketArray[PacketNum], PacketLength));

        NdisInterlockedIncrement(&pRCB->Ref);


        NDIS_SET_PACKET_STATUS(pRCB->PacketArray[PacketNum], NDIS_STATUS_SUCCESS);
        Adapter->nPacketsIndicated++;

        //
        // NDIS expects the indication to happen at DISPATCH_LEVEL if the
        // device is assinged any I/O resources in the IRP_MN_START_DEVICE_IRP.
        // Since this sample is flexible enough to be used as a standalone
        // virtual miniport talking to another device or part of a WDM stack for
        // devices consuming hw resources such as ISA, PCI, PCMCIA. I have to
        // do the following check. You should avoid raising the IRQL, if you
        // know for sure that your device wouldn't have any I/O resources. This
        // would be the case if your driver is talking to USB, 1394, etc.
        //
        if(Adapter->IsHardwareDevice){
            
            KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
            NdisMIndicateReceivePacket(Adapter->AdapterHandle,
                            &pRCB->PacketArray[PacketNum],
                            1);
            KeLowerIrql(oldIrql);            
            
        }else{
        
            NdisMIndicateReceivePacket(Adapter->AdapterHandle,
                            &pRCB->PacketArray[PacketNum],
                            1);
        }

    }else {
        DEBUGP(MP_VERY_LOUD, 
                ("Invalid packet or filter is not set packet = %p,Packet Length = %d\n",
                pRCB->PacketArray, PacketLength));        
    }            

}
Exemple #4
0
NDIS_STATUS
shared_flush(
	IN shared_info_t *shared,
	IN uchar *va,
	IN ULONG pa,
	IN ULONG len,
	IN BOOLEAN writetodevice
)
{
#ifndef NDIS60
	PNDIS_BUFFER b;
	NDIS_STATUS status;
	NDIS_PHYSICAL_ADDRESS npa;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp buffer descriptor */
	NdisAllocateBuffer(&status, &b, shared->rxbufferpool, va, len);
	if (status != NDIS_STATUS_SUCCESS) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateBuffer error 0x%x\n",
			shared->id, shared->unit, status));
		return status;
	}

	/* flush processor cache */
	NdisAdjustBufferLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	npa.HighPart = 0;
	npa.LowPart = pa;

#ifndef USEWDK


	if (!writetodevice)
		NdisMUpdateSharedMemory(shared->adapterhandle, len, va, npa);

#endif /* USEWDK */

	/* free the temp buffer descriptor */
	NdisFreeBuffer(b);
#else /* NDIS60 */
	PMDL b;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp MDL */
	b = NdisAllocateMdl(shared->adapterhandle, va, len);
	if (b == NULL) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateMdl error\n", shared->id, shared->unit));
		return NDIS_STATUS_FAILURE;
	}

	/* flush processor cache */
	NdisAdjustMdlLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	/* free the temp MDL */
	NdisFreeMdl(b);
#endif /* NDIS60 */
	return NDIS_STATUS_SUCCESS;
}