阅读:2011回复:5
IMD下MPSendPackets中转发数据包问题(有代码)
SendBuffer是将一个数据包缓冲区(完整包内容,从NDIS_PACKET中取得)发送出去的
并不是自定义包。而是根据系统原来的Packet 发送。 现在的问题是,调用这个函数后对8139等老网卡支持不好。 TCP连接不太稳定,有些机器蓝屏。 请高手帮忙解决。 NDIS_STATUS SendBuffer( PUCHAR SndBuffer, ULONG BufferSize, PNDIS_PACKET Packet, PADAPT pAdapter ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; PNDIS_BUFFER pNdisBuffer; PNDIS_PACKET pNdisPacket; ULONG bufLength; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificInfoSize = 0; PUCHAR pPacketContent8; UINT BufferLen; do { // 自己构造发送的包,不要NdisMSendComplete通知上层释放 NdisAcquireSpinLock(&pAdapter->Lock); if (pAdapter->PTDeviceState > NdisDeviceStateD0) { NdisReleaseSpinLock(&pAdapter->Lock); status = NDIS_STATUS_FAILURE; break; } pAdapter->OutstandingSends++; NdisReleaseSpinLock(&pAdapter->Lock); if (status == NDIS_STATUS_SUCCESS) { PSEND_RSVD SendRsvd; //分配Packet NdisAllocatePacket( &status, &pNdisPacket, pAdapter->SendPacketPoolHandle); if (status != NDIS_STATUS_SUCCESS) { DBGPRINT(("NdisAllocatePacket Error!\n")); return status; } //分配Buffer NdisAllocateBuffer(&status, &pNdisBuffer, pAdapter->SendPacketPoolHandle, SndBuffer, BufferSize); if( status != NDIS_STATUS_SUCCESS ) { DBGPRINT(("NdisAllocateBuffer Error!\n")); return status; } //DBGPRINT(("buffer(%d):%08X - %08X(%08X) - %08X - %08X(%08X)!\n",BufferSize,Packet->Private.Head,pNdisBuffer,&pNdisBuffer,pNdisPacket->Private.Head,SndBuffer,&SndBuffer)); pNdisBuffer->Next = NULL; //连接packet NdisChainBufferAtFront(pNdisPacket, pNdisBuffer); SendRsvd = (PSEND_RSVD)(pNdisPacket->ProtocolReserved); SendRsvd->OriginalPkt = Packet; SendRsvd->Flag = 0x1721; pNdisPacket->Private.Head->Next=NULL; pNdisPacket->Private.Tail=NULL; NdisGetPacketFlags(pNdisPacket) = NdisGetPacketFlags(Packet); //NdisSetPacketFlags(pNdisPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包 NDIS_SET_PACKET_HEADER_SIZE(pNdisPacket,14); NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pNdisPacket), NDIS_OOB_DATA_FROM_PACKET(Packet), sizeof(NDIS_PACKET_OOB_DATA)); NdisIMCopySendPerPacketInfo(pNdisPacket, Packet); NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO( Packet, &MediaSpecificInfo, &MediaSpecificInfoSize); if (MediaSpecificInfo || MediaSpecificInfoSize) { NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO( pNdisPacket, MediaSpecificInfo, MediaSpecificInfoSize); } NdisSend(&status, pAdapter->BindingHandle, pNdisPacket); if (status != NDIS_STATUS_PENDING) { /* DBGPRINT(("-------->2\n")); NdisIMCopySendCompletePerPacketInfo (Packet, pNdisPacket); NdisUnchainBufferAtFront(pNdisPacket ,&pNdisBuffer); while (pNdisBuffer!=NULL) { NdisFreeMemory((UCHAR *)(pNdisBuffer->StartVa) + pNdisBuffer->ByteOffset,pNdisBuffer->ByteCount,0); NdisFreeBuffer(pNdisBuffer); NdisUnchainBufferAtFront(pNdisPacket,&pNdisBuffer); } NdisDprFreePacket(pNdisPacket); */ NdisUnchainBufferAtFront(Packet,&pNdisBuffer); DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer)); NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent8,&BufferLen,32); DBGPRINT(("<!> NdisQueryBufferSafe :%08X,%d----------\n",pPacketContent8,BufferLen)); NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pPacketContent8,BufferLen,0); NdisDprFreePacket(Packet); } } else { // 若这里编译不过,请直接返回NDIS_STATUS_FAILURE代替 ADAPT_DECR_PENDING_SENDS(pAdapter); } }while(FALSE); return status; } VOID PtSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) /*++ Routine Description: Called by NDIS when the miniport below had completed a send. We should complete the corresponding upper-edge send this represents. Arguments: ProtocolBindingContext - Points to ADAPT structure Packet - Low level packet being completed Status - status of send Return Value: None --*/ { PADAPT pAdapt = (PADAPT)ProtocolBindingContext; PNDIS_PACKET Pkt; NDIS_HANDLE PoolHandle; PNDIS_BUFFER pNdisBuffer; PUCHAR pPacketContent8; UINT BufferLen; #ifdef NDIS51 // // Packet stacking: // // Determine if the packet we are completing is the one we allocated. If so, then // get the original packet from the reserved area and completed it and free the // allocated packet. If this is the packet that was sent down to us, then just // complete it // PoolHandle = NdisGetPoolFromPacket(Packet); if (PoolHandle != pAdapt->SendPacketPoolHandle) { // // We had passed down a packet belonging to the protocol above us. // // DBGPRINT(("PtSendComp: Adapt %p, Stacked Packet %p\n", pAdapt, Packet)); NdisMSendComplete(pAdapt->MiniportHandle, Packet, Status); } else #endif // NDIS51 { PSEND_RSVD SendRsvd; SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved); Pkt = SendRsvd->OriginalPkt; if(SendRsvd->Flag == 0x1721) { /* NdisUnchainBufferAtFront(Packet,&pNdisBuffer); DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer)); while (pNdisBuffer!=NULL) { NdisFreeMemory((UCHAR *)(pNdisBuffer->StartVa) + pNdisBuffer->ByteOffset,pNdisBuffer->ByteCount,0); NdisFreeBuffer(pNdisBuffer); NdisUnchainBufferAtFront(Packet,&pNdisBuffer); } #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif NdisDprFreePacket(Packet); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); */ NdisUnchainBufferAtFront(Packet,&pNdisBuffer); DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer)); NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent8,&BufferLen,32); DBGPRINT(("<!> NdisQueryBufferSafe :%08X,%d----------\n",pPacketContent8,BufferLen)); NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pPacketContent8,BufferLen,0); NdisDprFreePacket(Packet); } else { #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif NdisDprFreePacket(Packet); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); } } // // Decrease the outstanding send count // ADAPT_DECR_PENDING_SENDS(pAdapt); } |
|
沙发#
发布于:2008-02-18 17:45
直接用MpSendPackets不就成了。。。。。。。。
你跟他的区别就差距在一个是原始数据,一个是自己填充的 我的代码是这样的。 NdisAllocatePacket(&Status,&MyPacket,pAdapt->SendPacketPoolHandle); if(NT_SUCCESS(Status)) { //用上面的包内容 pPacketContent 分配一个新的缓冲区 PacketBuffer NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->SendPacketPoolHandle,pPacketContent,PacketLen); //把这个新分配的缓冲区 连接到 刚分配的新的包上 NdisChainBufferAtFront( MyPacket, PacketBuffer); Rsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved); Rsvd ->OriginalPkt = NULL; MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包 跟你的基本一样吧。。 出问题可能就在一些标志位的设置上应该。我也遇到了一定的问题。 |
|
板凳#
发布于:2008-02-20 09:40
xp 2k3 nt5下我过了
vista又出问题了 标志位? |
|
地板#
发布于:2008-02-20 10:08
你说的对 老网卡支持不好 最后是怎么解决的
我的程序跟你差距不大 可是也是对一些卡没作用 |
|
地下室#
发布于:2008-02-20 10:42
留个QQ,交流下
|
|
5楼#
发布于:2008-02-21 11:15
MSN:gonina@sina.com
QQ:5754888 加哪个都成 1周了,,至今都没解决好一部分卡 不能发包的问题 |
|