阅读:2021回复:5
求助:在PtReceivePacket中创建ARP包,调用NdisSend发送,调试时电脑重启……
小弟刚刚学习NDIS中间层编程。想利用passthru实现一个在PtReceivePacket中创建ARP包,调用NdisSend发送的程序。看了以前的一些帖子,仿照论坛上前辈的代码自己写了一个,在PtReceivePacket添加了创建包和发送包的代码,在PtSendComplete中添加了处理Pending的代码。但是一调试机器就重启。水平有限实在是改不出来了,只能求各位前辈指点一下了。非常感谢!代码如下:
INT PtReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ) { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; NDIS_STATUS Status; PNDIS_PACKET MyPacket; BOOLEAN Remaining; ////////////////////////////////////////////////////////////////// PNDIS_PACKET MyARPPacket; PNDIS_BUFFER MyARPBuffer; PUCHAR MyARPPacketContent; PSEND_RSVD SendRsvd; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; ////////////////////////////////////////////////////////////////// if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0)) { return 0; } ////////////////////////////////////////////////////////////////// ////创建一个自己的ARP包发出去 HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; Status = NdisAllocateMemory(&MyARPPacketContent, 60, 0, HighestAcceptableAddress); if (Status != NDIS_STATUS_SUCCESS) { return NDIS_STATUS_FAILURE; } else//手写一个ARP包 { //目的MAC MyARPPacketContent[0] = 0x00; MyARPPacketContent[1] = 0x15; MyARPPacketContent[2] = 0xF2; MyARPPacketContent[3] = 0xC1; MyARPPacketContent[4] = 0xB7; MyARPPacketContent[5] = 0x26; //源MAC MyARPPacketContent[6] = 0x00; MyARPPacketContent[7] = 0x22; MyARPPacketContent[8] = 0x19; MyARPPacketContent[9] = 0x0E; MyARPPacketContent[10] = 0x2D; MyARPPacketContent[11] = 0x1F; //协议类型 MyARPPacketContent[12] = 0x08; MyARPPacketContent[13] = 0x06; //硬件类型 MyARPPacketContent[14] = 0x00; MyARPPacketContent[15] = 0x01; //协议类型 MyARPPacketContent[16] = 0x08; MyARPPacketContent[17] = 0x00; //硬件地址长度 MyARPPacketContent[18] = 0x06; //协议地址长度 MyARPPacketContent[19] = 0x04; //操作 MyARPPacketContent[20] = 0x00; MyARPPacketContent[21] = 0x01; //发送者硬件地址 MyARPPacketContent[22] = 0x00; MyARPPacketContent[23] = 0x22; MyARPPacketContent[24] = 0x19; MyARPPacketContent[25] = 0x0E; MyARPPacketContent[26] = 0x2D; MyARPPacketContent[27] = 0x1F; //发送者IP地址 MyARPPacketContent[28] = 0xc0; MyARPPacketContent[29] = 0xa8; MyARPPacketContent[30] = 0x00; MyARPPacketContent[31] = 0x25; //目的硬件地址 MyARPPacketContent[32] = 0x00; MyARPPacketContent[33] = 0x15; MyARPPacketContent[34] = 0xF2; MyARPPacketContent[35] = 0xC1; MyARPPacketContent[36] = 0xB7; MyARPPacketContent[37] = 0x26; //目的IP地址 MyARPPacketContent[38] = 0xc0; MyARPPacketContent[39] = 0xa8; MyARPPacketContent[40] = 0x00; MyARPPacketContent[41] = 0x21; MyARPPacketContent[42] = 0x00; MyARPPacketContent[43] = 0x00; MyARPPacketContent[44] = 0x00; MyARPPacketContent[45] = 0x00; MyARPPacketContent[46] = 0x00; MyARPPacketContent[47] = 0x00; MyARPPacketContent[48] = 0x00; MyARPPacketContent[49] = 0x00; MyARPPacketContent[50] = 0x00; MyARPPacketContent[51] = 0x00; MyARPPacketContent[52] = 0x00; MyARPPacketContent[53] = 0x00; MyARPPacketContent[54] = 0x00; MyARPPacketContent[55] = 0x00; MyARPPacketContent[56] = 0x00; MyARPPacketContent[57] = 0x00; MyARPPacketContent[58] = 0x00; MyARPPacketContent[59] = 0x00; } NdisAllocateBuffer(&Status, &MyARPBuffer, pAdapt->SendPacketPoolHandle, MyARPPacketContent, 60);//分配一个缓冲描述符 if (Status == NDIS_STATUS_FAILURE) { NdisFreeMemory(MyARPPacketContent, 60, 0); return NDIS_STATUS_FAILURE; } NdisAllocatePacket(&Status, &MyARPPacket, pAdapt->SendPacketPoolHandle);//分配一个包描述符 if (Status == NDIS_STATUS_FAILURE) { NdisFreeMemory(MyARPPacketContent, 60, 0); return NDIS_STATUS_FAILURE; } NdisChainBufferAtFront(MyARPPacket, MyARPBuffer);//将缓冲描述符链入包描述符 MyARPPacket->Private.Head->Next = NULL; MyARPPacket->Private.Tail = NULL; SendRsvd = (PSEND_RSVD)(MyARPPacket->ProtocolReserved);//设置Reserved SendRsvd->OriginalPkt = NULL; NdisSetPacketFlags(MyARPPacket, NDIS_FLAGS_DONT_LOOPBACK); NdisSend(&Status, pAdapt->BindingHandle, MyARPPacket);//发送 if (Status != NDIS_STATUS_PENDING) { NdisUnchainBufferAtFront(MyARPPacket, &MyARPBuffer);//释放包描述符与缓冲描述符的连接 NdisDprFreePacket(MyARPPacket);//释放包描述符 NdisFreeBuffer(MyARPBuffer);//释放缓冲描述符 NdisFreeMemory(MyARPPacketContent, 60, 0);//释放内存 } ////////////////////////////////////////////////////////////////// #ifdef NDIS51 (VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining); if (Remaining) { Status = NDIS_GET_PACKET_STATUS(Packet); NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1); return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0); } #endif NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { PRECV_RSVD RecvRsvd; RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved); RecvRsvd->OriginalPkt = Packet; MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet)); NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet); Status = NDIS_GET_PACKET_STATUS(Packet); NDIS_SET_PACKET_STATUS(MyPacket, Status); NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet)); NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); if (Status == NDIS_STATUS_RESOURCES) { NdisDprFreePacket(MyPacket); } return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0); } else { return(0); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VOID PtSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) { PADAPT pAdapt = (PADAPT)ProtocolBindingContext; PNDIS_PACKET Pkt; NDIS_HANDLE PoolHandle; ////////////////////////////////////////////////////////////////// PNDIS_BUFFER MyARPBuffer; PVOID MyARPPacketContent; PSEND_RSVD SendRsvd; ////////////////////////////////////////////////////////////////// #ifdef NDIS51 PoolHandle = NdisGetPoolFromPacket(Packet); if (PoolHandle != pAdapt->SendPacketPoolHandle) { NdisMSendComplete(pAdapt->MiniportHandle, Packet, Status); } else #endif // NDIS51 { SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved); Pkt = SendRsvd->OriginalPkt; #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif ////////////////////////////////////////////////////////////////// ////释放内存 if (Pkt == NULL) { NdisQueryPacket(Packet, NULL, NULL, &MyARPBuffer, NULL);//找到第一个缓冲描述符 NdisQueryBuffer(MyARPBuffer, &MyARPPacketContent, NULL);//找到缓冲描述符的映射的内存地址 NdisUnchainBufferAtFront(Packet, &MyARPBuffer);//释放包描述符与缓冲描述符的连接 NdisDprFreePacket(Packet);//释放包描述符 NdisFreeBuffer(MyARPBuffer);//释放缓冲描述符 NdisFreeMemory(MyARPPacketContent, 60, 0);//释放内存 } else { NdisDprFreePacket(Packet); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); } /////////////////////////////////////////////////////////////////// } ADAPT_DECR_PENDING_SENDS(pAdapt); } 祝大家中秋快乐哈! |
|
沙发#
发布于:2008-09-13 12:51
#ifndef WIN9X
NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif 当Pkt为NULL时会出错的。 |
|
板凳#
发布于:2008-09-15 22:14
Re:求助:在PtReceivePacket中创建ARP包,调用NdisSend发送,调试
楼上的大哥:我把那一句屏蔽了还是不行啊。而且我觉得问题好像不是在那儿,我是在xp环境下编译的应该不会走到那一句。谢谢! |
|
地板#
发布于:2008-09-16 09:49
楼上的大哥:我把那一句屏蔽了还是不行啊。而且我觉得问题好像不是在那儿,我是在xp环境下编译的应该不会走到那一句。谢谢!
==>那是#ifndef 如果没有定义WIN9X |
|
地下室#
发布于:2008-10-11 13:58
有两点:
1 NdisAllocateBuffer(&Status, &MyARPBuffer, pAdapt->SendPacketPoolHandle, MyARPPacketContent, 60);//分配一个缓冲描述符 从包池去分配缓冲区描述表? 2 最好不要在接受函数里去发送包 |
|
|
5楼#
发布于:2008-10-11 22:35
Before calling NdisFreePacket, the driver either must call NdisFreeBuffer as many times as necessary to release all buffer descriptors chained to the packet, or it must call an NdisUnchainBufferAtXxx function as many times as necessary to save all pointers to buffer descriptors.
--from ddk read above carefully, either...or..., not both, that's the reason I think. |
|