阅读:1159回复:0
过滤数据报的代码 无效 请这里的老大帮帮忙 全部的分数相送
初学NDIS 对一些老大的代码进行组装 想实现数据报过滤的功能 但是达不到自己想要的效果 我发现一个包都不过滤 不知道为什么 请老大们帮帮忙 我有多少分就给多少分了 谢谢谢啦 在谢谢谢啦
************************************************* /+此函数实现将包描符描述的数据包的内容复制到指定的缓存中 void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength) { PNDIS_BUFFER BuffDT; PUCHAR BuffVA; UINT BuffLen; *pLength=0; BuffLen=0; NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL); while(BuffDT!=(PNDIS_BUFFER)NULL) { NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen); NdisMoveMemory(pBuff,BuffVA,BuffLen); pBuff=pBuff+BuffLen; *pLength+=BuffLen; NdisGetNextBuffer(BuffDT,&BuffDT); } return; } VOID PtTransferDataComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status, IN UINT BytesTransferred ) /*---------------------------------------------------------------------------------- 在底层网卡驱动调用介质相关函数(NdisMXxxIndicateReceive)向上指示 数 据 包 时,如 果 LookAheadBuffer 中不包括全部数据,协议驱动会调用 NdisTransferData 来获得其余的数据, 如果 NdisTransferData 返回PENDING,则这个函数会在传输完成后自动被调用。 由于在 PtReceive 中没有采用介质相关函数(NdisMXxxIndicateReceive)向上指示数据包,而 是用 NdisMIndicateReceivePacket,所以上层协议(tcp/ip等)不会调用 NdisTransferData, 因此这个函数不会被自动调用。 ----------------------------------------------------------------------------------*/ { PADAPT pAdapt = (PADAPT)ProtocolBindingContext; PUCHAR pPacketContent; PRSVD Rsvd; UINT OffsetSize, Result, PacketLen; PNDIS_BUFFER pPacketBuffer; PNDIS_PACKET pBakPacket; PNDIS_BUFFER pBakBuffer; PUCHAR pBakContent; UINT BufferLen; UINT flag = 1; DbgPrint((\"In PtTransferDataComplete\\n\")); // // Returning the Send on the Primary, will point to itself if there is no LBFO // pAdapt = pAdapt->pPrimaryAdapt; Rsvd = (PRSVD)(Packet->MiniportReserved); // pBakPacket 里是 HeaderBuffer + LookAheadBuffer 的内容。 pBakPacket = (PNDIS_PACKET)(Rsvd->OriginalPkt); if(pAdapt->MiniportHandle) { if(pBakPacket == NULL) NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred); else { Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax); CopyPacket2Buffer(pBakPacket, pPacketContent, &OffsetSize); CopyPacket2Buffer(Packet, pPacketContent+OffsetSize, &PacketLen); // if(Monitor_flag) /* { if(Check_Packet((char*)pPacketContent)) { flag = 0; // 不向上指示该包 } } else {} */ //规则判断 if (ICMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 1) { DbgPrint(\"ICMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); flag = 0; } } else {} if (IGMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 2) { DbgPrint(\"IGMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); flag = 0; } } else {} if (TCP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 6) { DbgPrint(\"TCP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); flag = 0; } } else {} if (UDP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 17) { DbgPrint(\"UDP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); flag = 0; } } else {} //规则判断结束 //-------------------------------------------- PacketLen += OffsetSize; // 释放包描述符pBakPacket、缓冲描述符pBakBuffer、内存pBakContent。 NdisUnchainBufferAtFront(pBakPacket, &pBakBuffer); NdisQueryBufferSafe(pBakBuffer, &pBakContent, &BufferLen, 32); NdisFreeBuffer(pBakBuffer); NdisFreeMemory(pBakContent, BUFFER_SIZE, 0); NdisFreePacket(pBakPacket); memset(Packet->MiniportReserved, 0, sizeof(Packet->MiniportReserved)); NdisUnchainBufferAtFront(Packet, &pPacketBuffer); NdisQueryBufferSafe(pPacketBuffer, &pBakContent, &BufferLen, 32); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pBakContent, BUFFER_SIZE, 0); if(!flag) { // 释放资源并返回 NdisFreePacket(Packet); return; } NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketLen); NdisChainBufferAtFront(Packet, pPacketBuffer); Packet->Private.Head->Next=NULL; Packet->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(Packet,14); // 向上层协议驱动指示数据包,防真网卡行为。 NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1); if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING) { MPReturnPacket((NDIS_HANDLE)pAdapt, Packet); } } } return; } NDIS_STATUS PtReceive( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, // 包头 IN UINT HeaderBufferSize, // 包头大小,以太网环境下为14 IN PVOID LookAheadBuffer, // 前视缓冲 IN UINT LookAheadBufferSize, // IN UINT PacketSize // 数据包总大小(不包括包头) ) /*----------------------------------------------------------------------------------- ProtocolReceive这个函数是在低层面向无连接的NIC驱动程序调用NdisMXxxIndicateReceive 函 数向上Indicate数据包时被 NDIS 调 用 的。 同 时 传 递 了 一 个 LookAheadBuffer,但 这 个LookAheadBuffer 里 面 可 能 不 是 数 据 包 的 全 部 内 容, 如 果 不 是 的 话 (LookAheadBufferSize < PacketSize)则需要调用NdisTransferData来获得这个数据包其余的内 容,NdisTransferData只是传递在LookaheadBuffer中没有出现的数据内容, 不是传递整个数据 包。 -----------------------------------------------------------------------------------*/ { PADAPT OutAdapt, pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET MyPacket, Packet, MyPacket1; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PNDIS_BUFFER pPacketBuffer, pBakBuffer; PUCHAR pPacketContent, pBakContent; UINT PacketLen; UINT OffsetSize; UINT BytesTransferred; PRSVD Rsvd = NULL; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificSize= 0; DBGPRINT((\"In PtReceive\\n\")); if(!pAdapt->MiniportHandle) { Status = NDIS_STATUS_FAILURE; } else do { // We should not be getting Receives on a Secondary, this is just specific to our LBFO driver if(pAdapt->isSecondary) { DbgPrint(\"PASSTHRU GETTING RECIEVES ON SECONDARY\\n\"); ASSERT(0); } /* 注释掉,不采用这种方法取得数据包。 // If this was indicated by the miniport below as a packet, then get that packet pointer and indicate // it as a packet as well(with appropriate status). This way the OOB stuff is accessible to the // transport above us. Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); if(Packet != NULL) // 在我的机器上总是为空。 { // // Get a packet off the pool and indicate that up // NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; // // Get the original packet(it could be the same packet as one received or a different one // based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible // correctly at the top. // NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet)); NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // // Set Packet Flags // NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet); // // Make sure the status is set to NDIS_STATUS_RESOURCES. // NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES); NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES); NdisDprFreePacket(MyPacket); break; } } // Fall through if the miniport below us has either not indicated a packet or we could not // allocate one */ if(FALSE){} else if(PacketSize <= LookAheadBufferSize) // 如果 LookAheadBuffer 中包含了全部数据 { // 分配内存 Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint(\"PTReceive:NdisAllocateMemory Failed\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pPacketContent == NULL) { DbgPrint(\"PTReceive:pPacketContent==NULL\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } // 将包头和 LookAheadBuffer 复制到新分配的内存中 NdisZeroMemory(pPacketContent, BUFFER_SIZE); NdisMoveMemory(pPacketContent, HeaderBuffer, HeaderBufferSize); NdisMoveMemory(pPacketContent+ HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize); PacketLen = PacketSize+HeaderBufferSize; // if(Monitor_flag) /* { if(Check_Packet((char*)pPacketContent)) { return NDIS_STATUS_NOT_ACCEPTED; } } else {} */ //规则判断 if (ICMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 1) { DbgPrint(\"ICMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } else {} if (IGMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 2) { DbgPrint(\"IGMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } else {} if (TCP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 6) { DbgPrint(\"TCP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } else {} if (UDP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 17) { DbgPrint(\"UDP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } else {} //规则判断结束 //-------------------------------------------- // 在包池中分配包描述符 NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { // 在缓冲池中分配缓冲描述符,将包描述符与缓冲描述符关联。 NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketLen); NdisChainBufferAtFront(MyPacket, pPacketBuffer); MyPacket->Private.Head->Next = NULL; MyPacket->Private.Tail = NULL; Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt = NULL; NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // 向上层协议驱动指示数据包,防真网卡行为。 NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); if(NDIS_GET_PACKET_STATUS(MyPacket) != NDIS_STATUS_PENDING) { DBGPRINT((\"In PtReceive And Free Memory\\n\")); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0); NdisDprFreePacket(MyPacket); } } break; } else // 如果 LookAheadBuffer 中没有包含全部数据 { // 分配内存 pPacketContent,存放要传输的除 LookAheadBuffer 之外的数据。 Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint(\"PtReceive:NdisAllocateMemory Failed.\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pPacketContent==NULL) { DbgPrint(\"PTReceive:pPacketContent==NULL\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } NdisZeroMemory(pPacketContent,BUFFER_SIZE); // 分配包描述符 MyPacket。 NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); // 分配内存 pBakContent,存放HeaderBuffer + LookAheadBuffer。 Status = NdisAllocateMemory(&pBakContent, BUFFER_SIZE, 0, HighestAcceptableMax); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint(\"PtReceive:NdisAllocateMemory Failed.\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pBakContent == NULL) { DbgPrint(\"PTReceive:pPacketContent==NULL\\n\"); return(NDIS_STATUS_NOT_ACCEPTED); } // 将 HeaderBuffer + LookAheadBuffer 复制到 pBakContent 指向的内存中。 NdisZeroMemory(pBakContent, BUFFER_SIZE); NdisMoveMemory(pBakContent, HeaderBuffer, HeaderBufferSize); NdisMoveMemory(pBakContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize); PacketLen = HeaderBufferSize + PacketSize; // 为要传输的除 LookAheadBuffer 之外的数据分配缓冲描述符(该缓冲描述符与 pPacketContent 指向的内存关联)。 NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketSize-LookAheadBufferSize); // 关联包描述符 MyPacket 与缓冲描述符 pPacketBuffer。 NdisChainBufferAtFront(MyPacket, pPacketBuffer); MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; OffsetSize = HeaderBufferSize + LookAheadBufferSize; // 分配包描述符 MyPacket1。 NdisDprAllocatePacket(&Status, &MyPacket1, pAdapt->RecvPacketPoolHandle); // 分配缓冲描述符 pBakBuffer,与 pBakContent 指向的内存关联。 NdisAllocateBuffer(&Status, &pBakBuffer, pAdapt->RecvBufferPoolHandle, pBakContent, OffsetSize); // 关联包描述符 MyPacket1 与缓冲描述符 pBakBuffer。 NdisChainBufferAtFront(MyPacket1, pBakBuffer); Rsvd = (PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt = (PNDIS_PACKET)MyPacket1; NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // 取得 LookAheadBuffer 之后的数据 NdisTransferData(&Status, pAdapt->BindingHandle, MacReceiveContext, LookAheadBufferSize, // 数据起始地址 PacketSize-LookAheadBufferSize, // 字节数 MyPacket, &BytesTransferred); if(Status != NDIS_STATUS_PENDING) { PtTransferDataComplete((NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred); } break; } pAdapt->IndicateRcvComplete = TRUE; } while(FALSE); return Status; } VOID PtReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) /*++ Routine Description: Called by the adapter below us when it is done indicating a batch of received buffers. Arguments: ProtocolBindingContext Pointer to our adapter structure. Return Value: None --*/ { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; // // We should not be getting Receives on a Secondary, this is just specific to our LBFO driver // if(pAdapt->isSecondary) { DBGPRINT(\"PASSTHRU GETTING RECEIVES ON SECONDARY\\n\"); ASSERT(0); } if((pAdapt->MiniportHandle != NULL) && pAdapt->IndicateRcvComplete) { switch(pAdapt->Medium) { case NdisMedium802_3: NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle); break; case NdisMedium802_5: NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle); break; case NdisMediumFddi: NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle); break; default: ASSERT(0); break; } } pAdapt->IndicateRcvComplete = FALSE; } INT PtReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ) /*++ 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 MyPacket; PRSVD Resvd; PUCHAR pPacketContent; UINT PacketLen; if(!pAdapt->MiniportHandle) { return 0; } // // We should not be getting Receives on a Secondary, this is just specific to our LBFO driver // if(pAdapt->isSecondary) { DBGPRINT(\"PASSTHRU GETTING RECEIVES ON SECONDARY\\n\"); return 0; } //################################### //把数据包内容从Packet拷贝到pPacketContent Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax); if (Status!=NDIS_STATUS_SUCCESS) return 0; CopyPacket2Buffer(Packet, pPacketContent, &PacketLen); //规则判断 if (ICMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 1) { DbgPrint(\"ICMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } if (IGMP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 2) { DbgPrint(\"IGMP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } if (TCP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 6) { DbgPrint(\"TCP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } if (UDP == 1) { if(((char *)pPacketContent)[12] == 8 && ((char *)pPacketContent)[13] == 0 && ((char *)pPacketContent)[23] == 17) { DbgPrint(\"UDP被拦截!\\n\"); NdisFreeMemory(pPacketContent, 2000, 0); return NDIS_STATUS_NOT_ACCEPTED; } } //规则判断结束 //-------------------------------------------- //################################################# // // Get a packet off the pool and indicate that up // NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { Resvd =(PRSVD)(MyPacket->MiniportReserved); Resvd->OriginalPkt = Packet; MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; // // Get the original packet(it could be the same packet as one received or a different one // based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible // correctly at the top. // NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet)); // // Set Packet Flags // 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 { // // 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(0); } } :( :( |
|
|