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); } } }
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); } } } }
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); }
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); }