コード例 #1
0
ファイル: miniport.c プロジェクト: gaddas/NAT-Gateway
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);
        }
    }
}
コード例 #2
0
ファイル: miniport.c プロジェクト: gaddas/NAT-Gateway
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);
}
コード例 #3
0
ファイル: miniport.c プロジェクト: heiden-deng/VisualVNC
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);
			}
		}
    }
}
コード例 #4
0
ファイル: upper_edge.c プロジェクト: patrick-ken/kernel_808l
/*-------------------------------------------------------------------------
  ssh_driver_send_packets()

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

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

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

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

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

  SSH_RAISE_IRQL(DISPATCH_LEVEL, &old_irql);

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

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

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

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

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

  NDIS_SET_PACKET_STATUS(src, NDIS_STATUS_PENDING);

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

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

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

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

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

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

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

  status = TRUE;

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

  return status;
}
コード例 #5
0
ファイル: miniport.c プロジェクト: heiden-deng/VisualVNC
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);
}