阅读:3565回复:7
过滤ICMP的源码 -->
NDIS_STATUS
PtReceive( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) /*++ Routine Description: LBFO - need to use primary for all receives Arguments: Return Value: --*/ { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET MyPacket, Packet; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; //UINT PhysicalBufferCount, BufferCount,TotalPacketLength; //PNDIS_BUFFER *FirstBuffer; PVOID virtualAddress; PNDIS_BUFFER firstBuffer, nextBuffer; ULONG totalLength; 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 the packet and filter /*NdisQueryPacket(Packet, &PhysicalBufferCount, &BufferCount, FirstBuffer, &TotalPacketLength); */ NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, &totalLength); while( firstBuffer != NULL) { NdisQueryBuffer(firstBuffer, &virtualAddress, &totalLength); if(!virtualAddress) { // // System is running low on memory resources. // So fail the read. // //status = STATUS_INSUFFICIENT_RESOURCES; //goto CleanExit; break; } else { if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) { Status = NDIS_STATUS_FAILURE; return Status; } } NdisGetNextBuffer(firstBuffer, &nextBuffer); firstBuffer = nextBuffer; } // // 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 // pAdapt->IndicateRcvComplete = TRUE; switch(pAdapt->Medium) { case NdisMedium802_3: NdisMEthIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; case NdisMedium802_5: NdisMTrIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; case NdisMediumFddi: NdisMFddiIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; default: ASSERT(0); break; } } while(FALSE); return Status; } 没测试地,请大有指教 ! |
|
|
沙发#
发布于:2001-08-20 21:35
else
{ if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) { 里的12、13、23等数字是什么意思 |
|
板凳#
发布于:2001-08-21 08:29
可能你真的没测试过,你的过滤ICMP代码可能无法执行到。
我也在写这方面的东西,因为我家里有两台机器,所以调试起来很方便。 从我安装passthru(8月2号)到现在,我还没见到一次 Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); 返回的packet为非NULL,全是NULL。 最初,我也打算将过滤代码加入到这个调用后面的括号内,不过发现 不行后,也就改为直接访问HeaderBuffer和LookAheadBuffer了,这样 效果不错。我一直弄不懂packet为什么从不返回非NULL,如果有哪位大虾知道,麻烦告诉小弟一声。 if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) 这里好像也有问题: mac帧中帧类型字段代表IP包的连续两个字节是08,00 你的08,06好像是ARP报文(前边有文章,自己去看吧) 我使用的比较: if(((PUSHORT)VA)[6]==0x0008) // Intel芯片上要倒过来 { // 是IP包 } else { // 不是IP包 } |
|
地板#
发布于:2001-08-21 20:37
以太包一般是14个字节的mac+20个字节的ip头+20个字节的tcp头+数据
if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) 的virtualAddress)[12]是第13和14字节=8,表明上层是ip包,那么virtualAddress)[13]表示什么意思,virtualAddress)[23]又表示什么意思,6和17是什么意思. |
|
地下室#
发布于:2001-08-22 09:13
以太网的13,14个字节表示网络层的协议类型:
0x08 0x00 ->ip 0x08 0x06 ->arp 0x08 0x35 ->rarp 如果是IP协议,则第23个字节又表示传输层协议: 1 -> icmp 2 -> igmp 6 -> tcp 17 ->udp 多个朋友多条路 |
|
|
5楼#
发布于:2001-09-03 16:48
按照我的理解,ndisquerybuffer和ndisgetnextbuffer
二者组合,穷举可以得到一个完整的ip包,而这个ip包的 包头可以判断是不是icmp包。可是在下面的代码while中, 循环中,每次得到包的一个buffer,都去判断 if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) 是不是不对呀???,自需要在得到包头的时候判断一次就可以了。 这是一点疑问。请大家指点 if(Packet != NULL) { NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, &totalLength); while( firstBuffer != NULL) { NdisQueryBuffer(firstBuffer, &virtualAddress, &totalLength); if(!virtualAddress) { break; } else { if ((((char*)virtualAddress)[12] == 8)&& (((char*)virtualAddress)[13] == 6)&& (((char*)virtualAddress)[23] == 17)) { Status = NDIS_STATUS_FAILURE; return Status; } } NdisGetNextBuffer(firstBuffer, &nextBuffer); firstBuffer = nextBuffer; } |
|
|
6楼#
发布于:2001-09-03 17:12
谢谢,该功能早又纠正:")
|
|
|
7楼#
发布于:2001-09-03 17:23
digital,请问你能不能告诉我完整的ip包帧头的
结构?或者那里能够找到答案?看起来好像tcp/ip 的东西到处都有,可是我就是没有找到我想要的。 比如,那几个字节是表示ip地址的? 另外,按照其他人的说话,你的 NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); 应该会返回null,那你是这么的得到一个完整的 收到的ndis_packet呢?请多多指点,最好给我这一 小部分的源码,谢谢!:) |
|
|