阅读:2566回复:22
ProtocolReceivePacket求教
各位高手,我对passthru程序进行了修改。我用的是win2000 ddk,希望用ProtocolReceivePacket函数对接收到的封包进行操作。但是我发现这个函数好像没有起作用。
我在运行中用dbgview查看protocol.c中ProtocolReceivePacket函数的的DBGPRINT输出时,未见任何输出。是不是ProtocolReceivePacket函数没有执行呀? |
|
最新喜欢:txysp |
沙发#
发布于:2004-05-20 09:52
好像是这样的,接收包的时候调用的都是ptreceive,而没有ptreceivepacket。
|
|
板凳#
发布于:2004-05-20 10:08
8139等新网卡用PtReceivePacket,老式的RTL8029等用PtReceive.就这么简单。
|
|
地板#
发布于:2004-05-20 10:19
asmsys老兄,我的网卡是realtek rtl8139(A),应该没有问题呀。
|
|
地下室#
发布于:2004-05-20 10:32
rtl的有点怪,你看看Ptreceive有没有输出就好了,反正总有一个函数被调用的,如果都没有,就是你的程序有问题了。
|
|
5楼#
发布于:2004-05-20 10:44
asmsys老兄,好像Ptrecive真的也没有输出。可能是我的程序有问题。我仍能接收数据可收到的不是对数据包操作后的数据。你认为我最有可能错在哪里呢?你是发送时错了,还是接收时哪里没设好?
|
|
6楼#
发布于:2004-05-20 11:09
这个很难说,贴点代码看看。
|
|
7楼#
发布于:2004-05-20 11:41
好的,这是PtReceivePacket函数的代码
INT PtReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket ) /*++ Routine Description: ReceivePacket handler. Called up by the miniport below when it supports NDIS 4.0 style receives. Re-package the packet and hand it back to NDIS for protocols above us. The re-package part is important since NDIS uses the WrapperReserved part of the packet for its own book-keeping. Also the re-packaging works differently when packets flow-up or down. In the up-path(here) the protocol reserved is owned by the protocol above. We need to use the miniport reserved here. Arguments: ProtocolBindingContext Pointer to our adapter structure. Packet - Pointer to the packet Return Value: == 0 -> We are done with the packet != 0 -> We will keep the packet and call NdisReturnPackets() this many times when done. --*/ { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; NDIS_STATUS Status; PNDIS_PACKET pMyPacket; BOOLEAN Remaining; ULONG MACAddrComp, // ja, 17.08.2003. ulEncPayload, ulUnencPayload; #define szPayloadCopy ETH_MAX_PACKET_SIZE char PayloadCopy[szPayloadCopy]; pEthHdr pETH; PUCHAR pCurr, pEnd, pUnencPayload = NULL; #define searchFor2 \"0123456789aBcDeF\" ULONG const lnSearchfor = strlen(searchFor2); char const chSearchfor[] = searchFor2; // // Drop the packet silently if the upper miniport edge isn\'t initialized or // the miniport edge is in low power state // DBGPRINT((\"PtReceivePacket() \\n\")); if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0)) { DBGPRINT((\"PtReceivePacket() miniport error \\n\")); return 0; } // ja, 17.08.2003. GetPktPayload(pPacket, // Copy payload PayloadCopy, // to area. szPayloadCopy, // Amount of space in area. &ulEncPayload // Return number of bytes in packet. ); DBGPRINT((\"PtReceivePacket() get pketpayload \\n\")); pETH = (pEthHdr)PayloadCopy; // Point to ethernet header. //ETH_COMPARE_NETWORK_ADDRESSES_EQ(pETH->SrcMAC, pAdapt->MACAddress, &MACAddrComp); //if (0==MACAddrComp) // A loopback? //{ //return 0; // Drop packet. //} pCurr = PayloadCopy; // Point to first byte of data. pEnd = pCurr + ulEncPayload - 1; // Point to last byte. for ( // Go through the data. ; ((ULONG)(1 + pEnd - pCurr)) >= // At least as many bytes as that sought after? lnSearchfor; pCurr++ ) if (0==memcmp(pCurr, chSearchfor, lnSearchfor)) // A hit? { Status = PtBuildOrigPkt( // Get original, unencapsulated payload. PayloadCopy, &pUnencPayload, &ulUnencPayload ); DBGPRINT((\"PtReceivePacket() found string \\n\")); if (NDIS_STATUS_SUCCESS!=Status) // A problem? { DBGPRINT((\"PtReceivePacket(): Status from PtBuildOrigPkt() = 0x%08x\\n\", Status)); break; } break; } // if (NULL==pUnencPayload) // Don\'t have unencapsulated payload? //{ //} // // Get a packet off the pool and indicate that up // NdisDprAllocatePacket(&Status, &pMyPacket, pAdapt->RecvPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { PRECV_RSVD RecvRsvd; PNDIS_BUFFER pNewNdisBfr; RecvRsvd = (PRECV_RSVD)(pMyPacket->MiniportReserved); RecvRsvd->OriginalPkt = pPacket; if (NULL!=pUnencPayload) // Have unencapsulated payload? { NdisAllocateBuffer(&Status, // Build new buffer descriptor. &pNewNdisBfr, pAdapt->hRecvBufferPool, pUnencPayload, ulUnencPayload ); if (NDIS_STATUS_SUCCESS!=Status) { DBGPRINT((\"PtReceivePacket() failed to get a buffer, status = 0x%08x\\n\", Status)); ASSERT(0); /* Do something! */ } RecvRsvd->bNewBuffer = TRUE; // Show new NDIS_BUFFER used. NdisChainBufferAtFront(pMyPacket, // Chain new buffer descriptor to new packet. pNewNdisBfr ); } // End \'if\' found desired packet. else { RecvRsvd->bNewBuffer = FALSE; // Original NDIS_BUFFER used. pMyPacket->Private.Head = pPacket->Private.Head; pMyPacket->Private.Tail = pPacket->Private.Tail; } // // Get the original packet (it could be the same packet as the one // received or a different one based on the number of layered miniports // below) and set it on the indicated packet so the OOB data is visible // correctly to protocols above us. // NDIS_SET_ORIGINAL_PACKET(pMyPacket, NDIS_GET_ORIGINAL_PACKET(pPacket)); // // Set Packet Flags // NdisGetPacketFlags(pMyPacket) = NdisGetPacketFlags(pPacket); Status = NDIS_GET_PACKET_STATUS(pPacket); NDIS_SET_PACKET_STATUS(pMyPacket, Status); NDIS_SET_PACKET_HEADER_SIZE(pMyPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)); NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pMyPacket, 1); // // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since // it might have changed! Use the value saved in the local variable. // if (Status == NDIS_STATUS_RESOURCES) { if (NULL!=pUnencPayload) // Have unencapsulated payload? { NdisFreeBuffer(pNewNdisBfr); // Recycle buffer descriptor. NdisFreeMemory(pUnencPayload, // Recycle memory. ulUnencPayload, 0 ); pUnencPayload = NULL; } // // Our ReturnPackets handler will not be called for this packet. // We should reclaim it right here. // NdisDprFreePacket(pMyPacket); } return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0); } // end \'if\' allocated packet descriptor from pool. else { if (NULL!=pUnencPayload) // Have unencapsulated payload? NdisFreeMemory(pUnencPayload, // Recycle memory. ulUnencPayload, 0 ); // // We are out of packets. Silently drop it. // return(0); } } |
|
8楼#
发布于:2004-05-20 12:16
把DBGPRINT((\"PtReceivePacket() \\n\"));
改成DbgPrint(\"PtReceivePacket() \\n\");试一下。 |
|
9楼#
发布于:2004-05-20 15:25
好像不行,我试了,看不到。
|
|
10楼#
发布于:2004-05-20 16:23
还是asmsys老大说得对,先要确定到底是调用哪个函数!不然改了还是白改,说不定改了半天,它从来就没有光顾过你这个函数:)
我的网卡也是8139的,调用的是ptreceive好像以前在这个论坛上有关于这个的讨论,你可以去搜搜。在我这里从来都没有调用ptreceivepacket这个函数,你直接运行微软的那个passthru就可以确定你的网卡到底是调用哪个函数了。那个程序是没很大的问题的,虽然有点BUG但运行,查看到底是调用的那个函数还是绰绰有余的:),确定了到底是哪个函数调用了以后,就好做相应的修改了,如果你网卡调用的是ptreceive这个函数,不管你的ptreceivepacket函数多么正确,他都是不会进入的:) 还有你大概是在passthru上修改的吧,这里面对DBGPRINT定义为 #define DBGPRINT(Fmt) \\ { \\ DbgPrint(\"*** XPASSHTRU.SYS ***\"); \\ DbgPrint (Fmt); \\ } 你可以按照asmsys老大说的改为改成DbgPrint(\"PtReceivePacket() \\n\");看的话可能会更明朗一些,但是不改也无妨,因为就只是多了一个DbgPrint(\"*** XPASSHTRU.SYS ***\");不管他就是了 |
|
11楼#
发布于:2004-05-20 19:40
8139等新网卡用PtReceivePacket,老式的RTL8029等用PtReceive.就这么简单。 其实这个也不一定的,要看MINIPORT是如何上指数据的啦。我的网卡就是8139的,还是只走PtReceive,Modem包一定走PtReceivePacket,因为它是从NDISWAN指上来的。 |
|
12楼#
发布于:2004-05-21 08:58
我先在ptreceive函数中用dbgview发现了输出,是不是表示8139这块网卡走的是ptreceive函数。但是又发现Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);得到的包是空的(null),这是怎么会事呀?
|
|
13楼#
发布于:2004-05-21 09:48
从本质上讲,PtReceive被调用有两种情况:
1、当下层的miniport调用NdisMXxxIndicate的时候,NDIS总是调用ProtocolReceive函数。 2、这时候底层的miniport有可能资源不足,为了能够让上层驱动程序迅速放弃对数据包控制权,它在每一个数据包的带外数据块中设置status属性为NDIS_STATUS_SOURCE,这样就迫使NDIS转而调用ProtocolReceive函数,强迫IMD拷贝每一个数据包。 当情况2发生时,Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);就不返回空。 |
|
14楼#
发布于:2004-05-21 10:33
看来我的这块网卡不走ptreceivepacket,我想把原来在pareceivepacket函数中的操作改在ptreceive中,可是发现了Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);为空。不知我该怎么操作? |
|
15楼#
发布于:2004-05-21 10:58
呵呵。我是一个新手,在测试DDK自带的passthru时,也发现了两样的问题,不过,现在我也不知道该怎么做。
|
|
|
16楼#
发布于:2004-05-21 11:38
你的分真难挣呀:)
不过我还是要告诉你,你所说的问题这里已经讨论过N次了。为什么什么都问,不自己动手。 |
|
17楼#
发布于:2004-05-21 19:18
自己苦苦作不出来才问的,从来都是会者不难。我看论坛原来的贴子,包括按比较包和前视缓冲区的大小的方式操作,我试着调试总是出错。所以才问。希望各位高手能够帮助解答。
|
|
18楼#
发布于:2004-05-21 21:45
如果你不会用softice的话,可以把你认为有错误的代码段的代码一行一行的加上去,直到出现故障为止,这个时候你就应该知道问题出在哪个地方了!这是一种最原始的方法不过比较麻烦,但是很有效!
|
|
19楼#
发布于:2004-05-21 21:49
ntStatus = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableMax);
if(ntStatus != NDIS_STATUS_SUCCESS) { return ntStatus; } NdisZeroMemory(pPacketContent,2000); NdisMoveMemory( pPacketContent, HeaderBuffer, HeaderBufferSize ); NdisMoveMemory( pPacketContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize ); 把包拷贝到内存区pPacketContent,然后你想怎么操作都行,不过别忘了,从新封包然后转发出去就可以了 |
|
上一页
下一页