//========================================================================== // PRODUCT: RusRoute - MaaSoftware routing firewall software driver // (C) Copyright Moiseenko A.A., MaaSoftware, 2003-2008. All Rights Reserved. // http://www.maasoftware.ru http://www.maasoftware.com // http://www.rusroute.ru http://www.rusroute.com // support@maasoftware.ru // You can use this driver sample for free for non commercial use //========================================================================== // FILE: Service.cpp // // AUTHOR: Andrey A. Moiseenko // // OVERVIEW Common adapter services. // ~~~~~~~~ // DATE: 28.10.2003 //========================================================================== #include "perm.h" #include "temp.h" #ifdef _DEBUG //#define DEBUG_TO_LAN_INTERFACE 2 #endif //#define MaaPrint PrintDbg void * gxx3; void IndicateReceiveMyPacket(CMaaAdapterInfo * pInfo, CDrvPacket * MyPacket) { // TODO::: CDrvPacketContext * MyContext = PacketCtx(MyPacket->m_pPacket); PrintDbg("IndicateReceiveMyPacket = MyPkt=%p, NdisPkt=%p, Orig=%p, buf=%p", MyPacket, MyPacket->m_pPacket, MyContext->m_OriginalPacket, MyContext->m_pBuffer); CMaaAdapter * pAdapter = pInfo->m_pBind; if (!pAdapter) { return; } pAdapter->aLock(); PADAPT pAdapt = pInfo->m_pAdapt; if (!pInfo->m_pAdapt->MiniportHandle || pAdapt->PTDeviceState > NdisDeviceStateD0) { pAdapter->aUnLock(); pAdapter->ReturnPacket(MyPacket); return; } //pInfo->m_pAdapt->OutstandingSends++; pAdapter->aUnLock(); //_byte * va = GetPtr ( MyPacket->m_pPacket ); //int len = GetLength ( MyPacket->m_pPacket ); //int HdrLen = pAdapter -> m_pFrame -> GetRecvHeaderLength (); if (!pInfo->m_pAdapt->MiniportHandle || pInfo->m_pAdapt->MPDeviceState > NdisDeviceStateD0) { } else { _byte * va = GetPtr (MyPacket->m_pPacket); int len = GetLength(MyPacket->m_pPacket); int HdrLen = pAdapter->m_pFrame->GetRecvHeaderLength(); PNDIS_PACKET p1; NDIS_STATUS Status; NdisAllocatePacket(&Status, &p1, pInfo->m_pAdapt->RecvIndicatePacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { NdisReinitializePacket(p1); PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET(p1); Memzero(OurOOB, sizeof(NDIS_PACKET_OOB_DATA)); // this line fills PacketCtx by zeros !!!!!! NdisZeroMemory(p1->MiniportReserved, sizeof(p1->MiniportReserved)); NDIS_PACKET_FIRST_NDIS_BUFFER(p1) = NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket->m_pPacket); NDIS_PACKET_LAST_NDIS_BUFFER(p1) = NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket->m_pPacket); NdisGetPacketFlags(p1) = NdisGetPacketFlags(MyPacket->m_pPacket); //NdisZeroMemory(p1->MacReserved, sizeof(p1->MacReserved)); NDIS_SET_PACKET_STATUS(p1, NDIS_STATUS_RESOURCES); NDIS_SET_PACKET_HEADER_SIZE(p1, pAdapter->m_pFrame->GetHeaderLength()); *(CDrvPacket **)(p1->MiniportReserved) = MyPacket; //__asm int 1; gxx3 = "NdisMIndicateReceivePacket"; //MaaPrint("NdisMIndicateReceivePacket"); PrintDbg("NdisMIndicateReceivePacket"); KIRQL Old = KeGetCurrentIrql(); if (Old != DISPATCH_LEVEL) { if (DISPATCH_LEVEL > Old) { KfRaiseIrql(DISPATCH_LEVEL); } else { KeLowerIrql(DISPATCH_LEVEL); } } NDIS_SET_PACKET_STATUS(p1, NDIS_STATUS_RESOURCES); //NDIS_SET_PACKET_STATUS(p1, NDIS_STATUS_SUCCESS); NdisMIndicateReceivePacket(pInfo->m_pAdapt->MiniportHandle, &p1, 1); //NdisMEthIndicateReceive(pInfo->m_pAdapt->MiniportHandle, (NDIS_HANDLE)(va + HdrLen), (PCHAR)va, HdrLen, va + HdrLen, len - HdrLen, len - HdrLen); //NdisMEthIndicateReceiveComplete(pInfo->m_pAdapt->MiniportHandle); KIRQL Irql = KeGetCurrentIrql(); if (Irql != Old) { if (Old > Irql) { KfRaiseIrql(Old); } else { KeLowerIrql(Old); } } if (NDIS_GET_PACKET_STATUS(p1) == NDIS_STATUS_PENDING) { //__asm int 1; gxx3 = "NDIS_GET_PACKET_STATUS(p1) == NDIS_STATUS_PENDING"; return; } NdisFreePacket(p1); //gxx3 = "NdisMEthIndicateReceiveComplete"; //NdisMEthIndicateReceiveComplete(pInfo->m_pAdapt->MiniportHandle); } //CMaaGetCheckIrql ChkIrql("Need: IndicateReceiveMyPacket()"); #if 0 KIRQL Old = KeGetCurrentIrql(); if (Old != DISPATCH_LEVEL) { if (DISPATCH_LEVEL > Old) { KfRaiseIrql(DISPATCH_LEVEL); } else { KeLowerIrql(DISPATCH_LEVEL); } } NDIS_SET_PACKET_STATUS(MyPacket->m_pPacket, NDIS_STATUS_RESOURCES); NdisMIndicateReceivePacket(pInfo->m_pAdapt->MiniportHandle, &MyPacket->m_pPacket, 1); //NdisMEthIndicateReceive(pInfo->m_pAdapt->MiniportHandle, (NDIS_HANDLE)(va + HdrLen), (PCHAR)va, HdrLen, va + HdrLen, len - HdrLen, len - HdrLen); //NdisMEthIndicateReceiveComplete(pInfo->m_pAdapt->MiniportHandle); KIRQL Irql = KeGetCurrentIrql(); if (Irql != Old) { if (Old > Irql) { KfRaiseIrql(Old); } else { KeLowerIrql(Old); } } #endif #if 0 PNDIS_PACKET p1; NDIS_STATUS Status; NdisAllocatePacket(&Status, &p1, pInfo->m_pAdapt->RecvIndicatePacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { NdisReinitializePacket(p1); NDIS_PACKET_FIRST_NDIS_BUFFER(p1) = NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket->m_pPacket); NDIS_PACKET_LAST_NDIS_BUFFER(p1) = NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket->m_pPacket); NdisGetPacketFlags(p1) = 0;//NdisGetPacketFlags(Packet); //NdisZeroMemory(p1->MacReserved, sizeof(p1->MacReserved)); NDIS_SET_PACKET_STATUS(p1, NDIS_STATUS_RESOURCES); NDIS_SET_PACKET_HEADER_SIZE(p1, pAdapter->m_pFrame->GetHeaderLength()); gxx3 = "NdisMIndicateReceivePacket"; PrintDbg("NdisMIndicateReceivePacket"); NdisMIndicateReceivePacket(pInfo->m_pAdapt->MiniportHandle, &p1, 1); if (NDIS_GET_PACKET_STATUS(p1) != NDIS_STATUS_RESOURCES) { //__asm int 1; gxx3 = "NDIS_GET_PACKET_STATUS(p1) != NDIS_STATUS_RESOURCES"; } NdisFreePacket(p1); //gxx3 = "NdisMEthIndicateReceiveComplete"; //NdisMEthIndicateReceiveComplete(pInfo->m_pAdapt->MiniportHandle); } #if 0 // NdisGetPacketFlags(MyPacket->m_pPacket) = 0;//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->m_pPacket, NDIS_STATUS_RESOURCES); //NDIS_SET_PACKET_STATUS(MyPacket->m_pPacket, NDIS_STATUS_SUCCESS); // // By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim // this packet as soon as the call to NdisMIndicateReceivePacket // returns. // //if (pAdapt->MiniportHandle != NULL) /* CMaaGetCheckIrql ChkIrql("Need: IndicateReceiveMyPacket()"); KIRQL Old = KeGetCurrentIrql(); if (Old != DISPATCH_LEVEL) { if (DISPATCH_LEVEL > Old) { KfRaiseIrql(DISPATCH_LEVEL); } else { KeLowerIrql(DISPATCH_LEVEL); } } //( pBind -> m_pProtocol -> m_Chars.Ndis40Chars.Ndis30Chars.ReceiveHandler )( pBind -> m_ProtocolBindingContext, va + HdrLen, va, HdrLen, va + HdrLen, len - HdrLen, len - HdrLen ); */ { NDIS_SET_PACKET_HEADER_SIZE(MyPacket->m_pPacket, pAdapter->m_pFrame->GetHeaderLength()); gxx3 = "Serialized callers of NdisMIndicateReceivePacket must run at IRQL = DISPATCH_LEVEL. Deserialized callers of NdisMIndicateReceivePacket can run at IRQL <= DISPATCH_LEVEL."; //__asm int 1; gxx3 = "NdisMIndicateReceivePacket"; PrintDbg("NdisMIndicateReceivePacket"); NdisMIndicateReceivePacket(pInfo->m_pAdapt->MiniportHandle, &MyPacket->m_pPacket, 1); if (NDIS_GET_PACKET_STATUS(MyPacket->m_pPacket) != NDIS_STATUS_RESOURCES) { __asm int 1; gxx3 = "NDIS_GET_PACKET_STATUS(MyPacket->m_pPacket) != NDIS_STATUS_RESOURCES"; } //gxx3 = "NdisMEthIndicateReceiveComplete"; //NdisMEthIndicateReceiveComplete(pInfo->m_pAdapt->MiniportHandle); } //(pBind->m_pProtocol->m_Chars.Ndis40Chars.Ndis30Chars.ReceiveCompleteHandler)(pBind->m_ProtocolBindingContext); /* KIRQL Irql = KeGetCurrentIrql(); if (Irql != Old) { if (Old > Irql) { KfRaiseIrql(Old); } else { KeLowerIrql(Old); } } */ //return; #endif #endif } if (pAdapter) { pAdapter->ReturnPacket(MyPacket); } } void SendMyPacket(CMaaAdapterInfo * pInfo, CDrvPacket * MyPacket) { // TODO::: CDrvPacketContext * MyContext = PacketCtx(MyPacket->m_pPacket); PrintDbg("SendMyPacket = MyPkt=%p, NdisPkt=%p, Orig=%p", MyPacket, MyPacket->m_pPacket, MyContext->m_OriginalPacket); CMaaAdapter * pAdapter = pInfo->m_pBind; if (!pAdapter) { return; } if (!MyPacket || !MyPacket->m_pPacket || MyContext->m_Index != MyPacket) { PrintDbg("error: MyContext->m_Index = %p, != %p", MyContext->m_Index, MyPacket); //__asm int 1; //++//MyContext->m_Index = MyPacket; } pAdapter->aLock(); PADAPT pAdapt = pInfo->m_pAdapt; if (!pInfo->m_pAdapt->MiniportHandle || pAdapt->PTDeviceState > NdisDeviceStateD0) { pAdapter->aUnLock(); pAdapter->ReturnPacket(MyPacket); return; } pInfo->m_pAdapt->OutstandingSends++; pAdapter->aUnLock(); NDIS_STATUS Status; //__asm int 1; gxx3 = "NdisSend"; //NdisGetPacketFlags(MyPacket->m_pPacket) = 0;//NdisGetPacketFlags(Packet); NdisSend(&Status, pInfo->m_pAdapt->BindingHandle, MyPacket->m_pPacket); if ( Status != NDIS_STATUS_PENDING ) { pAdapter->ReturnPacket(MyPacket); pAdapter->aLock(); pInfo->m_pAdapt->OutstandingSends--; pAdapter->aUnLock(); } } //--------------------------------------------------------------------------- CMaaService::CMaaService ( CMaaAdapterInfo * pAdapterInfo ) : m_Info ( *pAdapterInfo ), m_InfoObtained ( 0 ), m_DrvPackets(PACKETS), m_IsError ( 1 ), // fail flag m_ChgFlg ( 0 ) { m_FrameLimit = CRusRoute_FRAME_LIMIT_TOTAL - ReserverLengthForBiggerHeader; //!!!INT3; switch ( m_Info.m_SelectedMedium ) { // Accepted medium (winxp): NdisMediumDix, NdisMedium802_3, NdisMediumWan case NdisMedium802_3: case NdisMediumDix: case NdisMediumWan: m_pFrame = pdo->pEthFrame; break; case NdisMediumFddi: m_pFrame = pdo->pFddiFrame; break; case NdisMedium802_5: m_pFrame = pdo->pTokenRingFrame; break; default: m_pFrame = NULL; // return; //m_pFrame = pdo->pEthFrame; } m_MaxFrameSize = m_pFrame ? m_pFrame -> GetTypicalFrameSize () : 1514; } //--------------------------------------------------------------------------- CMaaService::~CMaaService () { } //--------------------------------------------------------------------------- void CMaaService::Init () { //Lock (); while ( 1 ) { if ( !m_pFrame || !m_DrvPackets || !CMaaAdapterBase::IsOK () ) { break; } for (int i = 0; i < PACKETS; i++) { m_FreeList.AddAtBack(&m_DrvPackets[i]); m_DrvPackets[i].m_pPacket = NULL; m_DrvPackets[i].m_pService = this; //m_Info.m_Number; m_DrvPackets[i].m_CommonPacketListItem.m_pDrvPacket = &m_DrvPackets[i]; } m_IsError = 0; break; } //UnLock (); } //--------------------------------------------------------------------------- void CMaaService::OnInfoObtained ( eInfo Info ) { int x = m_InfoObtained; m_InfoObtained |= Info; if (m_InfoObtained != x && (m_InfoObtained & (eInfoCurrentMac|eInfoMaxFrameSize)) == (eInfoCurrentMac | eInfoMaxFrameSize)) { //__asm int 1; pdo->OnValidAdapterAppeared(this); } } //--------------------------------------------------------------------------- BOOL CMaaService::IsOK () { return CMaaAdapterBase::IsOK() && !m_IsError; } //--------------------------------------------------------------------------- void * gxx2; void CMaaService::aLock() { //__asm int 1; gxx2 = "aLock(): NdisAcquireSpinLock(&m_Info.m_pAdapt->Lock);"; NdisAcquireSpinLock(&m_Info.m_pAdapt->Lock); } void CMaaService::aUnLock() { //__asm int 1; gxx2 = "aUnLock(): NdisReleaseSpinLock(&m_Info.m_pAdapt->Lock);"; NdisReleaseSpinLock(&m_Info.m_pAdapt->Lock); } //--------------------------------------------------------------------------- CDrvPacket * CMaaService::DublicatePacket(PNDIS_PACKET ArbitraryPacket, int IsReceive) { PrintDbg("CMaaService::DublicatePacket() for %p, %d", ArbitraryPacket, IsReceive); //__asm int 1; CDrvPacket * DrvPkt = GetFreePacket(IsReceive); if (!DrvPkt) { PrintDbg("CMaaService::DublicatePacket() returning NULL, point 1"); return NULL; } if (!IsReceive) { DrvPkt->m_Status = DRV_SEND; } else { DrvPkt->m_Status = DRV_RECEIVE; } PNDIS_BUFFER pBuff; UINT Size, Offset = 0; void * pOldVA; //NDIS_STATUS Status; PNDIS_PACKET p1 = DrvPkt->m_pPacket; if (PacketCtx(p1)->m_Index != DrvPkt) { PrintDbg("PacketCtx(p1)->m_Index = %p, != DrvPkt = %p", PacketCtx(p1)->m_Index, DrvPkt); //__asm int 1; } PNDIS_BUFFER nb = NULL; NdisQueryPacket(p1, NULL, NULL, &nb, NULL); void * pVA = NULL; NdisQueryBuffer(nb, &pVA, &Size); PrintDbg("CMaaService::DublicatePacket(): using packet %p (Ndis: %p), pVA=%p", DrvPkt, p1, pVA); NdisQueryPacket(ArbitraryPacket, NULL, NULL, &pBuff, NULL); while(pBuff) { NdisQueryBuffer(pBuff, &pOldVA, &Size); if ((int)(Offset + Size) > m_MaxFrameSize /*- GetMaxAddInfoSize ()*/) { Size = m_MaxFrameSize /*- GetMaxAddInfoSize ()*/ - Offset; DrvPkt->m_Status |= DRV_PACKET_ERROR; DrvPkt->m_ErrorCode = eTooBigFrame; } NdisMoveMemory((char *)pVA + Offset, pOldVA, Size); Offset += Size; NdisGetNextBuffer(pBuff, &pBuff); } NdisAdjustBufferLength(nb, Offset); NdisGetPacketFlags(p1) = NdisGetPacketFlags(ArbitraryPacket); // copy any packet flags over, see the DDK // NdisClearPacketFlags(p1, -1); // NdisSetPacketFlags(p1, NdisGetPacketFlags(ArbitraryPacket)); // Copy the Out of Band data, if any // PNDIS_PACKET_OOB_DATA OOB = NDIS_OOB_DATA_FROM_PACKET ( ArbitraryPacket ); // PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET(p1); // NdisMoveMemory ( OurOOB, OOB, sizeof ( NDIS_PACKET_OOB_DATA ) ); // set the original packet's status so NDIS won't complete it //13.06.2007// NDIS_SET_PACKET_STATUS ( ArbitraryPacket, NDIS_STATUS_PENDING ); //!!!pContext -> m_Index = pMyPacket; // 6.11.2003 I think it is no needed // pContext -> m_OriginalPacket = ArbitraryPacket; PrintDbg("CMaaService::DublicatePacket(): return packet %p (Ndis: %p), pVA=%p", DrvPkt, p1, pVA); return DrvPkt; } //--------------------------------------------------------------------------- // Поиск свободного пакета CDrvPacket * CMaaService::GetFreePacket(int IsReceive, int IsInternal) { PrintDbg("CMaaService::GetFreePacket(%d, )", IsReceive); CDrvPacket * Ret; if ( ! IsInternal ) { //Lock (); } Lock(); if (m_Info.m_bStatusClosing) { UnLock(); return NULL; } Ret = m_FreeList.GetFromFront (); if (Ret) { m_Info.m_PacketsProcessing++; } UnLock(); if (!Ret)// && IsReceive) { Ret = GetInterceptedPacket(); if (Ret) { aLock(); if (Ret->m_Status & DRV_RECEIVE) { m_Info.m_RecvPacketsDropped++; } else { m_Info.m_SendPacketsDropped++; } aUnLock(); } } else { NDIS_STATUS Status; PNDIS_PACKET p1 = NULL; PNDIS_BUFFER nb = NULL; void * pVA = NULL; CDrvPacket * DrvPkt = Ret; aLock(); if (!IsReceive) { DrvPkt->m_Status = DRV_SEND; pVA = m_Info.m_pAdapt->m_Sb; if (pVA) { m_Info.m_pAdapt->m_Sb = *(void **)pVA; NdisAllocatePacket(&Status, &p1, m_Info.m_pAdapt->SendPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { NdisAllocateBuffer(&Status, &nb, m_Info.m_pAdapt->SendBufferPoolHandle, pVA, 2048); if (Status == NDIS_STATUS_SUCCESS) { NdisReinitializePacket(p1); //NdisZeroMemory(p1->MacReserved, sizeof(p1->MacReserved)); NdisChainBufferAtFront(p1, nb); CDrvPacketContext * x = PacketCtx(p1); x->m_OriginalPacket = NULL; x->m_pBuffer = NULL; x->m_Index = DrvPkt; DrvPkt->m_pPacket = p1; } } } if (!p1 || !nb || !pVA) { if (p1) { NdisFreePacket(p1); p1 = NULL; } if (pVA) { *(void **)pVA = m_Info.m_pAdapt->m_Sb; m_Info.m_pAdapt->m_Sb = pVA; pVA = NULL; } } } else { DrvPkt->m_Status = DRV_RECEIVE; pVA = m_Info.m_pAdapt->m_Rb; if (pVA) { m_Info.m_pAdapt->m_Rb = *(void **)pVA; NdisAllocatePacket(&Status, &p1, m_Info.m_pAdapt->RecvPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { NdisAllocateBuffer(&Status, &nb, m_Info.m_pAdapt->RecvBufferPoolHandle, pVA, 2048); if (Status == NDIS_STATUS_SUCCESS) { NdisReinitializePacket(p1); //NdisZeroMemory(p1->MacReserved, sizeof(p1->MacReserved)); NdisChainBufferAtFront(p1, nb); CDrvPacketContext * x = PacketCtx(p1); x->m_OriginalPacket = NULL; x->m_pBuffer = NULL; x->m_Index = DrvPkt; DrvPkt->m_pPacket = p1; } } } if (!p1 || !nb || !pVA) { if (p1) { NdisFreePacket(p1); p1 = NULL; } if (pVA) { *(void **)pVA = m_Info.m_pAdapt->m_Rb; m_Info.m_pAdapt->m_Rb = pVA; pVA = NULL; } } } aUnLock(); if (!pVA) { Lock(); m_FreeList.AddAtFront(DrvPkt); UnLock(); PrintDbg("CMaaService::GetFreePacket(), point 2: returning NULL"); return NULL; } } if (Ret) { //NdisZeroMemory(Ret->m_pPacket->MacReserved, sizeof(Ret->m_pPacket->MacReserved)); PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET(Ret->m_pPacket); Memzero(OurOOB, sizeof(NDIS_PACKET_OOB_DATA)); // this line fills PacketCtx by zeros !!!!!! NdisGetPacketFlags(Ret->m_pPacket) = 0; NDIS_SET_PACKET_STATUS(Ret->m_pPacket, NDIS_STATUS_SUCCESS); CDrvPacketContext * x = PacketCtx(Ret->m_pPacket); x->m_OriginalPacket = NULL; x->m_pBuffer = NULL; x->m_Index = Ret; //Ret->m_pPacket = p1; PrintDbg("GetFreePacket() returns %p ...", Ret); //MyPacket -> Next = MyPacket -> Prev = NULL; AdjustLength(Ret->m_pPacket, m_MaxFrameSize); Ret->m_Status = (IsReceive & ~0x10000000) ? DRV_RECEIVE : DRV_SEND; } else { //__asm int 1; //MaaPrint("GetFreePacket() returns NULL ..."); PrintDbg("GetFreePacket() returns NULL ..."); } PrintDbg("...Using packet %p", Ret); return Ret; } //--------------------------------------------------------------------------- void CMaaService::ReturnPacket(CDrvPacket * Packet) { // Context is not locked !!!!!!!!!!!! PrintDbg("ReturnPacket(%p)", Packet); if (!Packet) { //__asm int 1; return; } PNDIS_PACKET p1 = Packet->m_pPacket; PNDIS_BUFFER nb = NULL; NdisUnchainBufferAtFront(p1, &nb); void * pVA; UINT Size; NdisQueryBuffer(nb, &pVA, &Size); CDrvPacketContext * x = PacketCtx(p1); x->m_Index = NULL; Packet->m_pPacket = NULL; aLock(); if (!(Packet->m_Status & DRV_RECEIVE)) { *(void **)pVA = m_Info.m_pAdapt->m_Sb; m_Info.m_pAdapt->m_Sb = pVA; NdisFreeBuffer(nb); NdisFreePacket(p1); } else { *(void **)pVA = m_Info.m_pAdapt->m_Rb; m_Info.m_pAdapt->m_Rb = pVA; NdisFreeBuffer(nb); NdisFreePacket(p1); } aUnLock(); Lock(); m_FreeList.AddAtFront ( Packet ); m_Info.m_PacketsProcessing--; UnLock(); } //--------------------------------------------------------------------------- /* int CMaaService::IsMyContext ( void * addr ) { if ( m_PagesStart <= ( _byte * ) addr && ( _byte * ) addr < m_PagesEnd ) { return 1; } return 0; } //--------------------------------------------------------------------------- int CMaaService::IsMyPacket ( PNDIS_PACKET Packet ) { return IsMyContext ( GetPtr ( Packet ) ); } */ //--------------------------------------------------------------------------- void CMaaService::OnRecvPacket ( CDrvPacket * MyPacket, PNDIS_STATUS Status ) { PrintDbg("CMaaService::OnRecvPacket"); //__asm int 1; /* Lock(); int xx = m_FreeList.GetCount(); UnLock(); PrintDbg("FreePackets: %d", xx); */ // Status is not used #ifdef DUMP_PACKETS { _byte * va = GetPtr ( MyPacket->m_pPacket ); int len = GetLength ( MyPacket->m_pPacket ); PrintDbg ( "Received original packet, len = %d", len ); DumpEthPacket(va, len); } #endif MyPacket->Init ( *m_pFrame ); // subject to change: we can pass here DRV_RECEIVE flag MyPacket->m_Status |= DRV_RECEIVE; /* if ( MyPacket -> m_Status & DRV_PACKET_ERROR ) { IndicateError ( MyPacket ); ReturnPacket ( MyPacket ); * Status = NDIS_STATUS_SOFT_ERRORS; return; } //*Status = NDIS_STATUS_SUCCESS; switch ( MyPacket->m_Protocol ) { case Proto_IP: case Proto_ARP: *Status = NDIS_STATUS_SUCCESS; break; default: //Indicate Error, ReturnPacket ( MyPacket ); *Status = NDIS_STATUS_HARD_ERRORS; } */ *Status = NDIS_STATUS_SUCCESS; //IndicateReceiveMyPacket(&m_Info, MyPacket); //return; /* aLock(); m_RecvQueue.AddAtBack(MyPacket); aUnLock(); return; */ #ifndef TCP_OPTIMIZE AddInterceptedPacket(MyPacket, true); #else aLock(); m_RecvQueue.AddAtBack(MyPacket); aUnLock(); #endif } //--------------------------------------------------------------------------- void CMaaService::OnRecvComplete() { PrintDbg("CMaaService::OnRecvComplete()"); //__asm int 1; /* Lock(); int xx = m_FreeList.GetCount(); UnLock(); PrintDbg("FreePackets: %d", xx); */ //NdisMEthIndicateReceiveComplete(m_Info.m_pAdapt->MiniportHandle); //return; /* while(1) { aLock(); CDrvPacket * MyPacket = m_RecvQueue.GetFromFront(); aUnLock(); if (!MyPacket) { break; } IndicateReceiveMyPacket(&m_Info, MyPacket); } PrintDbg("CMaaService::OnRecvComplete() - 2"); */ //__asm int 1; /* Lock(); xx = m_FreeList.GetCount(); UnLock(); PrintDbg("FreePackets: %d", xx); */ //return; #ifdef TCP_OPTIMIZE while(1) { aLock(); CDrvPacket * MyPacket = m_RecvQueue.GetFromFront(); aUnLock(); if (!MyPacket) { break; } //IndicateReceiveMyPacket(&m_Info, MyPacket); //continue; if (!TryToOptimize(MyPacket)) { AddInterceptedPacket(MyPacket, true); } } #endif } //--------------------------------------------------------------------------- void CMaaService::OnSendPacket(PNDIS_PACKET Packet, PNDIS_STATUS Status) { PrintDbg("CMaaService::OnSendPacket()"); //__asm int 1; /* Lock(); int xx = m_FreeList.GetCount(); UnLock(); PrintDbg("FreePackets: %d", xx); */ SetInterceptedPacketEventsIfNeed(false, true); CDrvPacket * MyPacket = DublicatePacket(Packet, DRV_SEND); if (!MyPacket) { *Status = NDIS_STATUS_FAILURE; return; } /* if (MyPacket->m_Status & DRV_PACKET_ERROR) { // too big frame ReturnPacket(MyPacket); } */ MyPacket->Init(*m_pFrame); // subject to change: we can pass here DRV_RECEIVE flag MyPacket->m_Status &= ~DRV_RECEIVE; if (MyPacket->m_Status & DRV_PACKET_ERROR) { // m_aLock.Lock(); ReturnPacket(MyPacket); // m_aLock.UnLock(); // *Status = NDIS_STATUS_SOFT_ERRORS; *Status = NDIS_STATUS_FAILURE; return; } #ifdef DUMP_PACKETS { _byte * va = GetPtr ( MyPacket->m_pPacket ); int len = GetLength ( MyPacket->m_pPacket ); PrintDbg ( "Original packet to be sent, len = %d", len ); DumpEthPacket(va, len); } #endif * Status = NDIS_STATUS_SUCCESS; //SendMyPacket(&m_Info, MyPacket); //return; #ifndef TCP_OPTIMIZE AddInterceptedPacket(MyPacket, true); #else if (!TryToOptimize(MyPacket)) { AddInterceptedPacket(MyPacket, true); } #endif } //--------------------------------------------------------------------------- #ifdef _WIN32 #pragma pack( push, temp_pack_id_1, 1 ) #endif struct CDrvPsevHdr { _IP m_SourceIp, m_DestinIp; _word m_Protocol, m_Length; }; struct CDrvIpRec { _IP m_SourceIp, m_DestinIp; }; // Intel is little endian, so look for bit fields ... /* struct iphdr { _byte ihl:4; _byte version:4; _byte tos; _word tot_len; _word id; _word frag_off; _byte ttl; _byte protocol; _word check; _dword saddr; _dword daddr; // options start here }; struct tcphdr { _word source; _word dest; _dword seq; _dword ack_seq; _word res1:4; _word doff:4; _word fin:1; _word syn:1; _word rst:1; _word psh:1; _word ack:1; _word urg:1; _word res2:2; _word window; _word check; _word urg_ptr; }; struct udphdr { _word source; _word dest; _word len; _word check; }; */ #ifdef _WIN32 #pragma pack( pop, temp_pack_id_1 ) #endif //--------------------------------------------------------------------------- int SubstractSumNotCompl(void * p, int len, int sm) { // (len & 1) == 0 len /= 2; unsigned char * p2 = (unsigned char *)p; while(len > 0) { int x = (((int) p2[0]) << 8) | (int) p2[1]; sm -= x; len--; p2 += 2; } while (sm < 0) { sm = (sm & 0xffff) + (sm >> 16); } /* __asm { mov ebx, p mov ecx, len mov eax, sm clc __Loop1: mov dx, [ebx] lea ebx, [ebx + 2] xchg dl,dh sbb ax, dx loop __Loop1 sbb ax, 0 mov sm, eax } */ return sm; } int AddSumNotCompl(void * p, int len, int sm) { unsigned char * p2 = (unsigned char *)p; while(len > 1) { int x = (((int) p2[0]) << 8) | (int) p2[1]; sm += x; len -= 2; p2 += 2; } if (len > 0) { int x = (((int) p2[0]) << 8); sm += x; } while(sm >= 0x10000) { sm = (sm & 0xffff) + (sm >> 16); } /* __asm { mov ebx, p mov ecx, len shr ecx, 1 mov eax, sm clc __Loop1: mov dx, [ebx] lea ebx, [ebx + 2] xchg dl, dh adc ax, dx loop __Loop1 adc ax, 0 mov ecx, len and ecx, 1 jz __Even mov dh, [ebx] mov dl, 0 add ax, dx adc ax, 0 __Even: mov sm, eax } */ return sm; } void SubstIpR(unsigned char * pIp, CTcpHashKey &k, CTcpHashKey &r, int NewTTL) { CDrvIpRec h; h.m_SourceIp = htonl(k.IPs); h.m_DestinIp = htonl(k.IPd); int sm = IP_CheckSum(pIp); sm = ntohs(sm); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(&h, sizeof(h), sm); if (NewTTL >= 0) { sm = SubstractSumNotCompl(pIp + 8, 2, sm); } h.m_SourceIp = htonl(r.IPd); h.m_DestinIp = htonl(r.IPs); IP_SourceAddress(pIp) = htonl(r.IPd); IP_DestinAddress(pIp) = htonl(r.IPs); sm = AddSumNotCompl(&h, sizeof(h), sm); if (NewTTL >= 0) { IP_TTL_(pIp) = (unsigned char)NewTTL; sm = AddSumNotCompl(pIp + 8, 2, sm); } IP_CheckSum(pIp) = htons(~sm); } //---------------------------------------------------------------------------- /* void SubstUdpR(unsigned char * pIp, unsigned char * pUdp, CTcpHashKey &k, CTcpHashKey &r, int NewTTL) { CDrvPsevHdr h; h.m_SourceIp = htonl(k.IPs); h.m_DestinIp = htonl(k.IPd); h.m_Protocol = htons(k.PortS); h.m_Length = htons(k.PortD); int sm = UDP_CheckSum(pUdp); sm = ntohs(sm); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(&h, sizeof(h), sm); h.m_SourceIp = htonl(r.IPd); h.m_DestinIp = htonl(r.IPs); h.m_Protocol = htons(r.PortD); h.m_Length = htons(r.PortS); UDP_SourcePort(pUdp) = htons(r.PortD); UDP_DestinPort(pUdp) = htons(r.PortS); sm = ~AddSumNotCompl(&h, sizeof(h), sm); UDP_CheckSum(pUdp) = htons(sm); SubstIpR(pIp, k, r, NewTTL); } //---------------------------------------------------------------------------- void SubstIcmpR(unsigned char * pIp, unsigned char * pIcmp, CTcpHashKey &k, CTcpHashKey &r, int NewTTL) { SubstIpR(pIp, k, r, NewTTL); } //---------------------------------------------------------------------------- void SubstPingR(unsigned char * pIp, unsigned char * pIcmp, CTcpHashKey &k, CTcpHashKey &r, int NewTTL) { switch(pIcmp[0]) { case ICMPType_EchoRequest: { int sm = ntohs(*(unsigned short *)(pIcmp + 2)); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(pIcmp + 4, 4, sm); PING_Identifier(pIcmp) = htons(r.PortS); PING_SequenceNumber(pIcmp) = htons(r.PortD); sm = ~AddSumNotCompl(pIcmp + 4, 4, sm); *(unsigned short *)(pIcmp + 2) = htons(sm); SubstIpR(pIp, k, r, NewTTL); } break; case ICMPType_EchoReply: { int sm = ntohs(*(unsigned short *)(pIcmp + 2)); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(pIcmp + 4, 4, sm); PING_Identifier(pIcmp) = htons(r.PortS); PING_SequenceNumber(pIcmp) = htons(r.PortD); sm = ~AddSumNotCompl(pIcmp + 4, 4, sm); *(unsigned short *)(pIcmp + 2) = htons(sm); SubstIpR(pIp, k, r, NewTTL); } break; case ICMPType_DestinationUnreachable: case ICMPType_TimeExceeded: case ICMPType_ParameterProblem: { unsigned char * IncIph = pIcmp + 8; int IncapsulatedIpHeaderLength = IP_HeaderLength(IncIph); //if ( a.m_End >= 8 + IncapsulatedIpHeaderLength + 8 ) { unsigned char * XHdr = IncIph + IncapsulatedIpHeaderLength; if (IP_Protocol(IncIph) == Proto_ICMP && XHdr[0] == ICMPType_EchoRequest) { CTcpHashKey r2 = r; r2.IPs = r.IPd; r2.IPd = r.IPs; SubstIpR(IncIph, k, r2, -1); int sm = ntohs(*(unsigned short *)(XHdr + 2)); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(XHdr + 4, 4, sm); PING_Identifier(XHdr) = htons(r.PortS); PING_SequenceNumber(XHdr) = htons(r.PortD); sm = ~AddSumNotCompl(XHdr + 4, 4, sm); *(unsigned short *)(XHdr + 2) = htons(sm); CTcpHashKey k2 = k; r2 = r; r2.IPd = ntohl(IP_SourceAddress(pIp)); k2.IPs = ntohl(IP_SourceAddress(pIp)); k2.IPd = ntohl(IP_DestinAddress(pIp)); SubstIpR(pIp, k2, r2, NewTTL); } } } break; } return; } */ //---------------------------------------------------------------------------- void SubstTcpR(unsigned char * pIp, unsigned char * pTcp, CTcpHashKey &k, CTcpHashKey &r, int NewTTL /*= -1*/) { CDrvPsevHdr h; h.m_SourceIp = htonl(k.IPs); h.m_DestinIp = htonl(k.IPd); h.m_Protocol = htons(k.PortS); h.m_Length = htons(k.PortD); int sm = TCP_CheckSum(pTcp); sm = ntohs(sm); sm = (~sm) & 0xffff; sm = SubstractSumNotCompl(&h, sizeof(h), sm); h.m_SourceIp = htonl(r.IPd); h.m_DestinIp = htonl(r.IPs); h.m_Protocol = htons(r.PortD); h.m_Length = htons(r.PortS); TCP_SourcePort(pTcp) = htons(r.PortD); TCP_DestinPort(pTcp) = htons(r.PortS); sm = ~AddSumNotCompl(&h, sizeof(h), sm); TCP_CheckSum(pTcp) = htons(sm); SubstIpR(pIp, k, r, NewTTL); } //---------------------------------------------------------------------------- int gOptimizationHits = 0, gOptimizationHitsFailures = 0; //---------------------------------------------------------------------------- bool CMaaService::TryToOptimize(CDrvPacket * MyPacket) { #ifndef TCP_OPTIMIZE return false; #endif //return false; /* if (!gbOptimizationIsEnabled) { return false; } */ if (MyPacket->m_Protocol != Proto_IP) { return false; } //CRusRoute_Packet *p = a.m_Fragments.LookAtFront(); unsigned char * pEth = (unsigned char *)MyPacket->m_pHeader; int Len = MyPacket->m_Length; unsigned char * pIp = pEth + 14;; if (Len < 14 + 20 || IP_IsFragmented(pIp) || IP_Protocol(pIp) != Proto_TCP) { //gOptimizationSkipped++; return false; } int IpHdrLen = IP_HeaderLength(pIp); int TotLen = (int)ntohs(*IP_pTotalLength(pIp)); if (TotLen + 14 > Len || IpHdrLen + 20 > TotLen) { return false; } // Process TCP packet CTcpHashKey k; k.IPs = ntohl(IP_SourceAddress(pIp)); k.IPd = ntohl(IP_DestinAddress(pIp)); unsigned char * pTcp = pIp + IpHdrLen; // pTcp = pIp + IP_HeaderLength(pIp); k.PortS = ntohs(TCP_SourcePort(pTcp)); k.PortD = ntohs(TCP_DestinPort(pTcp)); unsigned long Seq = ntohl(TCP_Seq(pTcp)); unsigned long Ack = ntohl(TCP_Ack(pTcp)); CTcpOptHashData d; Lock(); //gLock.Lock("TCP.opt - 1"); int Id = -1; int flg; if (MyPacket->m_Status & DRV_RECEIVE) { /* if (!m_hIp2If.Find(k.IPs)) { // received paket with source ip == my local ip // deny, no statistics flg = -1000; CProtocolListColor c(CProtocolListColor::eRed); printf("%s", (const char *)CTOOString::sFormat("Deny incoming tcp packet with source Ip=%I(our local Ip), source MAC=%:, DestIp=%I\n", k.IPs, p->m_Buffer + 6, k.IPd)); } else */ { flg = pdo->m_hTcpRRedirs2.Find(k, &d); } } else { flg = pdo->m_hTcpSRedirs2.Find(k, &d); } if (flg) { //gOptimizationSkipped++; //gLock.UnLock(); UnLock(); return false; } CTcpHashKey k2; bool bIR; bool bCount = false; bool bSendBytes = true; int NewTTL = -1; switch(d.b) { case 0: k2 = d.p->s.k1; bIR = d.p->s.bIR0; bCount = !d.p->m_bJournalSecondaryLevel; bSendBytes = d.p->m_b1stDirSend; //== CTcpConnInfo2::eSend; break; case 1: k2 = d.p->s.k0; bIR = d.p->s.bIR1; bCount = !d.p->m_bJournalSecondaryLevel; bSendBytes = !d.p->m_b1stDirSend;// != CTcpConnInfo2::eSend; break; case 2: k2 = d.p->d.k1; bIR = d.p->d.bIR0; bCount = d.p->m_bJournalSecondaryLevel; bSendBytes = d.p->m_bLevel2Send; NewTTL = d.p->m_NewTTL; break; case 3: k2 = d.p->d.k0; bIR = d.p->d.bIR1; bCount = d.p->m_bJournalSecondaryLevel; bSendBytes = !d.p->m_bLevel2Send; break; default: //gOptimizationSkipped++; //gLock.UnLock(); UnLock(); return false; } d.p->m_Seq[d.b] = ntohl(TCP_Seq(pTcp)) + TotLen - IpHdrLen - TCP_HeaderLength(pTcp); d.p->m_Ack[d.b] = ntohl(TCP_Ack(pTcp)); bool bJournal = d.p->m_bJournal; int MTU = d.p->m_MTU[d.b]; DWORD Adapt = d.p->m_Adapters[d.b]; _IP UserIp = d.p->m_UserIp; int JournalId = d.p->m_JournalId; Id = pdo->GetOptIdByIpActivity /*UserActivity*/(d.p->m_UserIp); if (Id != d.p->m_Id || MTU < TotLen) { //gOptimizationSkipped++; //gLock.UnLock(); UnLock(); return false; } memcpy(pEth, &d.p->m_Eth[12 * d.b], 12); //int Dir = bIR ? RUSROUTE_STATUS_PASS_TO_TCP : 0; int Dir = bIR ? DRV_RECEIVE : 0; //gLock.UnLock(); if (bJournal && bCount) { pdo->AddOptJournalDataLocked(JournalId, Id, UserIp, 0, TotLen, bSendBytes); //gJournals.Add(JournalId, Id, UserIp, 0, TotLen, bSendBytes); } UnLock(); AdjustLength(MyPacket->m_pPacket, TotLen + 14); SubstTcpR(pIp, pTcp, k, k2, NewTTL); //__asm int 1; // MaaPrint("TcpOpt.1.%d: %s %I:%d --> %I:%d", d.b, (MyPacket->m_Status & DRV_RECEIVE) ? "Recv" : "Send", k.IPs, k.PortS, k.IPd, k.PortD); // MaaPrint("TcpOpt.2.mod: %s %I:%d --> %I:%d, Seq = %d, Ack = %d", (Dir & DRV_RECEIVE) ? "Recv" : "Send", k2.IPd, k2.PortD, k2.IPs, k2.PortS, Seq, Ack); if (m_Info.m_Number == (int)Adapt) { // use the same adapter PutPacket(MyPacket, Dir, this); // MaaPrint("TcpOpt.%d - done", d.b); } else { int Num = (int)Adapt; Lock(); CMaaAdapterInfo * a = NULL; pdo->m_hAdapterNumber2AdapterInfo.Find(Num, &a); if (a) { a->Touch(); } UnLock(); if (a) { a->m_pBind->PutPacket(MyPacket, Dir, this); // MaaPrint("TcpOpt.%d - done, diff iface", d.b); Lock(); a->UnTouch(); UnLock(); } else { gOptimizationHitsFailures++; // No such adapter //m_aLock.Lock(); ReturnPacket(MyPacket); //m_aLock.UnLock(); return true; // returning true because we already have modified packet } } gOptimizationHits++; return true; } //--------------------------------------------------------------------------- void CMaaService::DefferPacket ( CDrvPacket * Packet ) { // We must NOT delay foreign packet PacketCtx ( Packet -> m_pPacket ) -> m_OriginalPacket = NULL; // set some flag } //--------------------------------------------------------------------------- int CMaaService::PutPacket(CDrvPacket * MyPacket, int Dir, CMaaService * pMyPacketService) { // TODO::: //pMyPacketService->ReturnPacket(MyPacket); //return 0; #ifdef _WINNT CDrvPacket * pMyPacket; PNDIS_PACKET pPacket = MyPacket->m_pPacket; UINT Flags = NdisGetPacketFlags(pPacket); if (pMyPacketService != this) { pMyPacket = GetFreePacket(Dir & DRV_RECEIVE); if ( !pMyPacket ) { //pMyPacketService->m_aLock.Lock(); pMyPacketService->ReturnPacket(MyPacket); //pMyPacketService->m_aLock.UnLock(); return 0; } PNDIS_BUFFER pBuffer; UINT Size, Offset = 0, SrcSize; void * pVA, *pSrcVA; NdisGetFirstBufferFromPacket(pPacket, &pBuffer, &pSrcVA, &SrcSize, &SrcSize); //pMyPacket -> m_Status = 0; pPacket = pMyPacket->m_pPacket; NdisGetFirstBufferFromPacket(pPacket, &pBuffer, &pVA, &Size, &Size); NdisMoveMemory(pVA, pSrcVA, SrcSize); NdisAdjustBufferLength(pBuffer, SrcSize); } else { pMyPacket = MyPacket; } CDrvPacketContext * pContext = PacketCtx(pPacket); PrintDbg("pContext->m_Index = %p, pMyPacket = %p", pContext->m_Index, pMyPacket); // Copy the Out of Band data, if any //PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET(pPacket); //Memzero(OurOOB, sizeof(NDIS_PACKET_OOB_DATA)); // this line fills PacketCtx by zeros !!!!!! NdisGetPacketFlags(pPacket) = 0; // = Flags; //NdisClearPacketFlags(pPacket, -1); //NdisSetPacketFlags(pPacket, 0); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS); pContext->m_OriginalPacket = NULL; if (pContext->m_Index != pMyPacket) { PrintDbg("pContext->m_Index = %p != pMyPacket = %p", pContext->m_Index, pMyPacket); //__asm int 1; //++//pContext->m_Index = pMyPacket; } if (pMyPacketService != this) { pMyPacketService->ReturnPacket(MyPacket); } //__asm int 1; if (Dir & DRV_RECEIVE) { gxx = "IndicateReceiveMyPacket(&m_Info, pMyPacket);"; IndicateReceiveMyPacket(&m_Info, pMyPacket); } else { gxx = "SendMyPacket(&m_Info, pMyPacket);"; SendMyPacket(&m_Info, pMyPacket); } return 1; #else // _WINNT return 0; #endif // _WINNT } //--------------------------------------------------------------------------- int CMaaService::PutPacket(CRusRoute_Packet0 &p) { //TODO::: PrintDbg("CMaaService::PutPacket(CRusRoute_Packet0 &p), p.m_Status = %d", p.m_Status); #ifdef _WINNT //aLock(); CDrvPacket * pMyPacket = GetFreePacket(p.m_Status & DRV_RECEIVE); //CDrvPacket * pMyPacket = GetFreePacket ( (p.m_Status & DRV_RECEIVE) ? DRV_RECEIVE : 0x10000000 ); // 7.01.2008 //aUnLock(); PNDIS_BUFFER pBuffer; UINT Size, Offset = 0; void * pVA; if ( !pMyPacket ) { return 0; } //pMyPacket -> m_Status = 0; PNDIS_PACKET pPacket = pMyPacket -> m_pPacket; CDrvPacketContext * pContext = PacketCtx ( pPacket ); PrintDbg("1. pContext->m_Index = %p, pMyPacket = %p", pContext->m_Index, pMyPacket); NdisGetFirstBufferFromPacket ( pPacket, &pBuffer, &pVA, &Size, &Size ); NdisMoveMemory ( pVA, p.m_Buffer, p.m_Length ); NdisAdjustBufferLength ( pBuffer, p.m_Length ); // Copy the Out of Band data, if any //PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET(pPacket); //Memzero(OurOOB, sizeof(NDIS_PACKET_OOB_DATA)); // this line fills PacketCtx by zeros !!!!!!!! NdisGetPacketFlags(pMyPacket->m_pPacket) = p.m_Flags; //NdisClearPacketFlags(pPacket, -1); //NdisSetPacketFlags ( pPacket, p.m_Flags ); NDIS_SET_PACKET_STATUS ( pPacket, NDIS_STATUS_SUCCESS ); pContext -> m_OriginalPacket = NULL; PrintDbg("2. pContext->m_Index = %p, pMyPacket = %p", pContext->m_Index, pMyPacket); if (p.m_Status & DRV_RECEIVE) { //__asm int 1; IndicateReceiveMyPacket(&m_Info, pMyPacket); } else { SendMyPacket(&m_Info, pMyPacket); } return 1; #else // _WINNT return 0; #endif // _WINNT } //--------------------------------------------------------------------------- /* void CMaaService::InitPacket ( CDrvPacket & p ) { int len = m_MaxFrameSize; p.m_Status = 0; _byte * ptr; #ifdef _WIN9x PNDIS_BUFFER pBuffer; NdisUnchainBufferAtFront ( p.m_pPacket, & pBuffer ); ptr = ( _byte * ) pBuffer -> VirtualAddress; pBuffer -> Length = len; NdisReinitializePacket ( p.m_pPacket ); NdisChainBufferAtFront ( p.m_pPacket, pBuffer ); //GetMyContext ( &p ) -> NdisBindingHandle = NdisBindingHandle; #endif // _WIN9x #ifdef _WINNT PNDIS_BUFFER pBuffer; void * pVA; UINT Size; PNDIS_PACKET pPacket = p.m_pPacket; //CDrvPacketContext * pContext = PacketCtx ( pPacket ); NdisGetFirstBufferFromPacket ( pPacket, &pBuffer, &pVA, &Size, &Size ); ptr = ( _byte * ) pVA; NdisAdjustBufferLength ( pBuffer, len ); // copy any packet flags over, see the DDK NdisClearPacketFlags(pPacket, -1); NdisSetPacketFlags ( pPacket, 0 ); //NdisSetPacketFlags ( pPacket, NdisGetPacketFlags ( pOldPacket ) ); // Copy the Out of Band data, if any PNDIS_PACKET_OOB_DATA OurOOB = NDIS_OOB_DATA_FROM_PACKET ( pPacket ); //NdisMoveMemory ( OurOOB, OOB, sizeof ( NDIS_PACKET_OOB_DATA ) ); Memzero ( OurOOB, sizeof ( NDIS_PACKET_OOB_DATA ) ); NDIS_SET_PACKET_STATUS ( pPacket, NDIS_STATUS_PENDING ); #endif // _WINNT //pContext -> m_Index = pMyPacket; DefferPacket ( &p ); p.Init ( * m_pFrame ); } */ //--------------------------------------------------------------------------- #ifdef _WINNT /* PNDIS_BUFFER CMaaService::AllocateBuffer ( void * Address, int Length ) { NDIS_STATUS Status; PNDIS_BUFFER Buffer; NdisAllocateBuffer ( & Status, & Buffer, m_BufferPoolHandle, Address, Length ); if ( Status != NDIS_STATUS_SUCCESS ) { Buffer = NULL; } return Buffer; } */ #endif //--------------------------------------------------------------------------- void CMaaService::SetInterceptedPacketEventsIfNeed(bool bContextIsLocked, bool bForce) { if (!bContextIsLocked) { Lock(); } // context is locked if (bForce || m_InterceptedPackets.LookAtFront()) { m_PacketInterceptedEvent.SetUserEvent(); //pdo->m_InterceptedPacketsList.AddAtBack(&p->m_CommonPacketListItem); pdo->m_PacketInterceptedEvent.SetUserEvent(); } if (!bContextIsLocked) { UnLock(); } } //--------------------------------------------------------------------------- void CMaaService::AddInterceptedPacket(CDrvPacket *p, bool bSetEvent) { Lock(); // context is locked m_InterceptedPackets.AddAtBack(p); pdo->m_InterceptedPacketsList.AddAtBack(&p->m_CommonPacketListItem); if (bSetEvent) { m_PacketInterceptedEvent.SetUserEvent(); pdo->m_PacketInterceptedEvent.SetUserEvent(); } UnLock(); } //--------------------------------------------------------------------------- CDrvPacket * CMaaService::GetInterceptedPacket() { Lock(); // context is locked CDrvPacket *p = m_InterceptedPackets.GetFromFront(); if (p) { pdo->m_InterceptedPacketsList.Release(&p->m_CommonPacketListItem); } UnLock(); return p; } //--------------------------------------------------------------------------- void CMaaService::ReturnInterceptedPacket(CDrvPacket * p) { ReturnPacket(p); } //--------------------------------------------------------------------------- void CMaaService::SetupPacketInterceptedEvent(HANDLE h) { m_PacketInterceptedEvent.SetupUserEvent(h); } //--------------------------------------------------------------------------- void CMaaService::SetupConnectedEvent(HANDLE h) { m_ConnectedEvent.SetupUserEvent(h); } //--------------------------------------------------------------------------- void CMaaService::SetConnectedEvent() { m_ConnectedEvent.SetUserEvent(); } //--------------------------------------------------------------------------- void CMaaAdapterInfo::SendRequests() { NDIS_STATUS Status2; #if 0 { NDIS_REQUEST &Req = pBind->m_Req1; Memzero ( &Req, sizeof ( Req ) ); Req.RequestType = NdisRequestQueryInformation; Req.DATA.QUERY_INFORMATION.Oid = OID_802_3_PERMANENT_ADDRESS; Req.DATA.QUERY_INFORMATION.InformationBuffer = pBind->m_PermanentMac.Addr; Req.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof ( pBind->m_PermanentMac.Addr ); // CallNdis //NdisRequest ( &Status2, pBind -> m_NdisBindingHandle, &Req ); Status2 = pBind->m_Block.NdisCommonOpenBlock.RequestHandler ( pBind->m_NdisBindingHandle, &Req ); if ( Status2 != NDIS_STATUS_PENDING ) { MSTCP_RequestCompleteHandler ( ProtocolBindingContext, &Req, Status2 ); } } { NDIS_REQUEST &Req = pBind->m_Req2; Memzero ( &Req, sizeof ( Req ) ); Req.RequestType = NdisRequestQueryInformation; Req.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS; Req.DATA.QUERY_INFORMATION.InformationBuffer = pBind->m_Mac.Addr; Req.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof ( pBind->m_Mac.Addr ); // CallNdis //NdisRequest ( &Status2, pBind -> m_NdisBindingHandle, &Req ); Status2 = pBind->m_Block.NdisCommonOpenBlock.RequestHandler ( pBind->m_NdisBindingHandle, &Req ); if ( Status2 != NDIS_STATUS_PENDING ) { MSTCP_RequestCompleteHandler ( ProtocolBindingContext, &Req, Status2 ); } } #endif { NDIS_REQUEST &Req = m_Req3; Memzero(&Req, sizeof(Req)); Req.RequestType = NdisRequestQueryInformation; Req.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE; Req.DATA.QUERY_INFORMATION.InformationBuffer = &m_DataGetMaxFrameSize; Req.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(m_DataGetMaxFrameSize); m_DataGetMaxFrameSize = 0; // CallNdis //NdisRequest ( &Status2, pBind -> m_NdisBindingHandle, &Req ); NdisRequest(&Status2, m_pAdapt->BindingHandle, &Req); /* if (Status2 != NDIS_STATUS_PENDING) { MSTCP_RequestCompleteHandler(ProtocolBindingContext, &Req, Status2 ); } */ if (Status2 == NDIS_STATUS_SUCCESS) { MSTCP_MyRequestComplete(&Req, m_pBind); } } } //--------------------------------------------------------------------------- void MSTCP_MyRequestComplete(PNDIS_REQUEST NdisReq, CMaaAdapter * pAdapter) { Lock(); // Context is locked switch ( NdisReq -> DATA.QUERY_INFORMATION.Oid ) { case OID_802_3_PERMANENT_ADDRESS: { int BytesWritten = NdisReq -> DATA.QUERY_INFORMATION.BytesWritten; pAdapter -> m_Info.m_PermanentMac.Set ( NdisReq -> DATA.QUERY_INFORMATION.InformationBuffer, BytesWritten ); PrintDbg ( "[%s]: Permanent Mac Address is %:", pAdapter -> m_Info.m_AdapterName.const_char_ptr (), pAdapter -> m_Info.m_PermanentMac.Addr ); pAdapter -> OnInfoObtained ( CMaaService::eInfoPermanentMac ); break; } case OID_802_3_CURRENT_ADDRESS: { //INT3 int BytesWritten = NdisReq -> DATA.QUERY_INFORMATION.BytesWritten; pAdapter -> m_Info.m_Mac.Set ( NdisReq -> DATA.QUERY_INFORMATION.InformationBuffer, BytesWritten ); PrintDbg ( "[%s]: Current Address is %:", pAdapter -> m_Info.m_AdapterName.const_char_ptr (), pAdapter -> m_Info.m_Mac.Addr ); pAdapter -> OnInfoObtained ( CMaaService::eInfoCurrentMac ); break; } case OID_GEN_MAXIMUM_FRAME_SIZE: { unsigned long * InformationBuffer = ( unsigned long * ) NdisReq -> DATA.QUERY_INFORMATION.InformationBuffer; int BytesWritten = NdisReq -> DATA.QUERY_INFORMATION.BytesWritten; { unsigned long HdrLen = pAdapter -> m_pFrame -> GetHeaderLength (); // or GetRecvHeaderLength () ? //unsigned long RealMaxMTU = * InformationBuffer; if ( * InformationBuffer + HdrLen < ( unsigned long ) pAdapter -> m_FrameLimit && * InformationBuffer + HdrLen > * InformationBuffer ) { pAdapter -> m_MaxFrameSize = * InformationBuffer + HdrLen; //* InformationBuffer -= 0;//pAdapter -> GetMaxAddInfoSize (); } else { pAdapter -> m_MaxFrameSize = pAdapter -> m_FrameLimit; * InformationBuffer = pAdapter -> m_MaxFrameSize - HdrLen; //* InformationBuffer = CDRV_MAX_FRAME_SIZE - HdrLen - 0;//pAdapter -> GetMaxAddInfoSize (); } } pAdapter -> OnInfoObtained ( CMaaService::eInfoMaxFrameSize ); break; } case OID_GEN_LINK_SPEED: { int BytesWritten = NdisReq -> DATA.QUERY_INFORMATION.BytesWritten; if ( BytesWritten >= sizeof ( int ) ) { unsigned long s = * ( unsigned long * )( NdisReq -> DATA.QUERY_INFORMATION.InformationBuffer ); //PrintDbg ( "[%s]: OID_GEN_LINK_SPEED: %d00 bps", pAdapter -> m_Info.m_AdapterName.const_char_ptr (), s ); pAdapter->m_Info.m_LinkSpeed = s; } } } UnLock(); } //--------------------------------------------------------------------------- void CMaaService::PreUnBind() { Lock(); pdo->m_hAdapterNumber2AdapterInfo.Remove(m_Info.m_Number); m_Info.m_bStatusClosing = true; UnLock(); while(1) { while(1) { CDrvPacket * DrvPkt = GetInterceptedPacket(); if (!DrvPkt) { break; } ReturnPacket(DrvPkt); } while(1) { aLock(); CDrvPacket * DrvPkt = m_RecvQueue.GetFromFront(); aUnLock(); if (!DrvPkt) { break; } ReturnPacket(DrvPkt); } Lock(); int x = m_Info.m_PacketsProcessing; UnLock(); if (x <= 0) { break; } NdisMSleep(2); } }