阅读:1760回复:0
NDIS 收报文截获问题
将收上来的报文是 IP AH ICMP 格式的报文,我在PPReceive函数中去掉报文中的AH层,然后存储在新申请的buffer中,
将该buffer挂载在新的 Packet 中提交给上层,但发现上层返回的ICMP报文是IP ICMP [IP AH ICMP]格式,寻思良久,不知道问题出在哪里? 请高人指点呀。 谢谢!! PPReceive函数如下: NDIS_STATUS PPReceive ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) { PADAPT pAdapt = (PADAPT)ProtocolBindingContext; PNDIS_PACKET MyPacket, Packet; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; BOOLEAN bDecision; pEthHdr pETH; if ((!pAdapt->MiniportHandle) || (pAdapt->MiniportDeviceState > NdisDeviceStateD0)) { Status = NDIS_STATUS_FAILURE; } else do { // // Get at the packet, if any, indicated up by the miniport below. // Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); if (Packet != NULL) { // // The miniport below did indicate up a packet. Use information // from that packet to construct a new packet to indicate up. // // // Make our packet point to data from the original // packet. NOTE: this works only because we are // indicating a receive directly from the context of // our receive indication. If we need to queue this // packet and indicate it from another thread context, // we will also have to allocate a new buffer and copy // over the packet contents, OOB data and per-packet // information. This is because the packet data // is available only for the duration of this // receive indication call. // // // Get a packet off the pool and indicate that up // //drop loopback packet if (IsLoopbackPacket(pAdapt, Packet)) // A loopback? { return 0; // Drop packet. } NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { PRECV_RSVD RecvRsvd; PNDIS_BUFFER NewNdisBfr; BOOLEAN Ret; RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved); RecvRsvd->OriginalPkt = Packet; //filter for ESP/AH Status = FilterPacket( pAdapt, Packet, NULL, FALSE, &bDecision ); if(bDecision) { Ret = PStripAhEsp(pAdapt, Packet, MyPacket); } if(!bDecision || !Ret ) { RecvRsvd->bNewBuffer = FALSE; MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->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 at protocols above. // NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet)); NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // // Copy packet flags. // NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet); // // Force protocols above to make a copy if they want to hang // on to data in this packet. This is because we are in our // Receive handler (not ReceivePacket) and we can't return a // ref count from here. // NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES); // // By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim // this packet as soon as the call to NdisMIndicateReceivePacket // returns. // NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); // // Reclaim the indicated packet. Since we had set its status // to NDIS_STATUS_RESOURCES, we are guaranteed that protocols // above are done with it. // DestroyMyPacket(MyPacket); NdisDprFreePacket(MyPacket); break; } } else { // // The miniport below us uses the old-style (not packet) // receive indication. Fall through. // } // // 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: case NdisMediumWan: NdisMEthIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; default: break; } } while(FALSE); return Status; } BOOLEAN PStripAhEsp ( IN PADAPT pAdapt, IN PNDIS_PACKET original_packet, OUT PNDIS_PACKET MyPacket ) { NDIS_STATUS Status; #define szPayloadCopy ETH_MAX_PACKET_SIZE char PayloadCopy[szPayloadCopy]; pIPHdr pIPH; pAHHdr pAH; USHORT IPHdrl; PUCHAR pUnencPayload = NULL; ULONG UnEncPayloadl; ULONG EncPayloadl; PNDIS_BUFFER NewNdisBfr; PRECV_RSVD RecvRsvd; //get a copy of the packet to local buffer GetPktPayload( original_packet, PayloadCopy, szPayloadCopy, &EncPayloadl ); pIPH = (pIPHdr)(PayloadCopy + sizeof(EthHdr)); IPHdrl = pIPH->IPHdrLen * 4; //alloc new memery UnEncPayloadl = EncPayloadl - sizeof(AHHdr); Status = NdisAllocateMemoryWithTag( &pUnencPayload, UnEncPayloadl, TAG ); if (NDIS_STATUS_SUCCESS != Status) { return FALSE; } //build new packet with no AH/ESP NdisMoveMemory( pUnencPayload, PayloadCopy, sizeof(EthHdr) + IPHdrl ); NdisMoveMemory( pUnencPayload + sizeof(EthHdr) + IPHdrl, PayloadCopy + sizeof(EthHdr) + IPHdrl + sizeof(AHHdr), EncPayloadl - sizeof(EthHdr) - IPHdrl - sizeof(AHHdr) ); pIPH = (pIPHdr)(pUnencPayload + sizeof(EthHdr)); pIPH->TotalLength = (USHORT)RtlUlongByteSwap((UnEncPayloadl - sizeof(EthHdr))<<16); pIPH->Protocol = 1; pIPH->Checksum = 0; pIPH->Checksum = GetIPChecksum((PUSHORT)pIPH, IPHdrl); //build new buffer descriptor and chain it to MyPacket NdisAllocateBuffer( &Status, &NewNdisBfr, pAdapt->hRecvBufferPool, pUnencPayload, UnEncPayloadl ); if( NDIS_STATUS_SUCCESS != Status ) { NdisFreeMemory( pUnencPayload, UnEncPayloadl, 0 ); pUnencPayload = NULL; return FALSE; } RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved); RecvRsvd->bNewBuffer = TRUE; NdisChainBufferAtFront( MyPacket, NewNdisBfr ); /* MyPacket->Private.Head = original_packet->Private.Head; MyPacket->Private.Tail = original_packet->Private.Tail; */ return TRUE; } |
|