WinPkFilter from a class

Home Forums Discussions Support Portal WinPkFilter from a class

This topic contains 1 reply, has 2 voices, and was last updated by  Vadim Smirnov 11 years, 4 months ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #5039

    dipple
    Participant

    OK, I am writting a windows service. This windows service has a class CFilter that I would like to impliment the filtering in.

    To start with I am simply attempting to create a windows service that will perform the same process as the PassThru example except the output is written to a text file.

    So I have the service working fine and the code for the PassThru example is in my class but I am getting a compiler error that I can not seem to get past.

    Here is the header file for my class. Note: The StartFilter method is the method that will be called from the windows service to perform the WinPkFilter related functionality.

    Filter.h:


    #pragma once
    #include ".kernelincludecommon.h"
    #include ".kernelincludendisapi.h"
    #include "iphlp.h"

    class CFilter
    {
    private:
    TCP_AdapterList AdList;
    DWORD iIndex;
    CNdisApi api;
    ETH_REQUEST Request;
    INTERMEDIATE_BUFFER PacketBuffer;
    HANDLE hEvent;
    CXEventLog pEventLog;

    USHORT ntohs(USHORT);
    void ReleaseInterface();

    public:
    CFilter(void);
    ~CFilter(void);
    void StartFilter();
    };

    Here is the Filter.cpp file


    #include "StdAfx.h"
    #include ".filter.h"

    CFilter::CFilter(void)
    {
    pEventLog.Init("wdtdi");
    pEventLog.Write(EVENTLOG_INFORMATION_TYPE, _T("TDI Hook Enabled."));
    }

    CFilter::~CFilter(void)
    {
    }

    USHORT CFilter::ntohs( USHORT netshort )
    {
    PUCHAR pBuffer;
    USHORT nResult;

    nResult = 0;
    pBuffer = (PUCHAR )&netshort;

    nResult = ( (pBuffer[ 0 ] < < 8) & 0xFF00 )
    | ( pBuffer[ 1 ] & 0x00FF );

    return( nResult );
    }

    void CFilter::ReleaseInterface()
    {
    // This function releases packets in the adapter queue and stops listening the interface
    ADAPTER_MODE Mode;

    Mode.dwFlags = 0;
    Mode.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];

    // Set NULL event to release previously set event object
    api.SetPacketEvent(AdList.m_nAdapterHandle[iIndex], NULL);

    // Close Event
    if (hEvent)
    CloseHandle ( hEvent );

    // Set default adapter mode
    api.SetAdapterMode(&Mode);

    // Empty adapter packets queue
    api.FlushAdapterPacketQueue (AdList.m_nAdapterHandle[iIndex]);
    }

    void CFilter::StartFilter()
    {
    UINT counter = 0;
    ether_header* pEthHeader = NULL;

    iIndex = 1; // For testing this is the adapter to attach to. Eventually need to
    // handle all adapters on machine.

    counter = 100; // For testing this is the number of packets to process.

    if(!api.IsDriverLoaded())
    {
    pEventLog.Write(EVENTLOG_INFORMATION_TYPE, _T("Driver not installed on this system of failed to load"));
    return;
    }

    api.GetTcpipBoundAdaptersInfo ( &AdList );

    if ( iIndex + 1 > AdList.m_nAdapterCount )
    {
    pEventLog.Write(EVENTLOG_INFORMATION_TYPE, _T("There is no network interface with such index on this system"));
    return;
    }

    ADAPTER_MODE Mode;

    Mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL;
    Mode.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];

    // Create notification event
    hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    // Set event for helper driver
    if ((!hEvent)||(!api.SetPacketEvent((HANDLE)AdList.m_nAdapterHandle[iIndex], hEvent)))
    {
    pEventLog.Write(EVENTLOG_INFORMATION_TYPE, _T("Failed to create notification event or set it for driver"));
    return;
    }

    atexit (ReleaseInterface);

    // Initialize Request
    ZeroMemory ( &Request, sizeof(ETH_REQUEST) );
    ZeroMemory ( &PacketBuffer, sizeof(INTERMEDIATE_BUFFER) );
    Request.EthPacket.Buffer = &PacketBuffer;
    Request.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];

    api.SetAdapterMode(&Mode);

    while (counter != 0)
    {
    WaitForSingleObject ( hEvent, INFINITE );
    ResetEvent(hEvent);

    while(api.ReadPacket(&Request))
    {
    counter--;

    #ifndef _SILENT_PASSTHRU

    if (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
    {
    //printf("n%d - MSTCP --> Interfacen", counter);
    }
    else
    {
    //printf("n%d - Interface --> MSTCPn", counter);
    }

    //printf ("tPacket size = %dn", PacketBuffer.m_Length);
    pEthHeader = (ether_header*)PacketBuffer.m_IBuffer;

    /* printf (
    "tSource MAC:tt %.2X%.2X%.2X%.2X%.2X%.2Xn",
    pEthHeader->h_source[0],
    pEthHeader->h_source[1],
    pEthHeader->h_source[2],
    pEthHeader->h_source[3],
    pEthHeader->h_source[4],
    pEthHeader->h_source[5]
    );

    printf (
    "tDestination MAC:t %.2X%.2X%.2X%.2X%.2X%.2Xn",
    pEthHeader->h_dest[0],
    pEthHeader->h_dest[1],
    pEthHeader->h_dest[2],
    pEthHeader->h_dest[3],
    pEthHeader->h_dest[4],
    pEthHeader->h_dest[5]
    );

    if(ntohs(pEthHeader->h_proto) == ETH_P_IP)
    printf("tInternet Protocol packetn");

    if(ntohs(pEthHeader->h_proto) == ETH_P_RARP)
    printf("tReverse Addr Res packetn");

    if(ntohs(pEthHeader->h_proto) == ETH_P_ARP)
    printf("tAddress Resolution packetn");
    */
    #endif // _SILENT_PASSTHRU

    if (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
    {
    // Place packet on the network interface
    api.SendPacketToAdapter(&Request);
    }
    else
    {
    // Indicate packet to MSTCP
    api.SendPacketToMstcp(&Request);
    }

    if (counter == 0)
    {
    pEventLog.Write(EVENTLOG_INFORMATION_TYPE, _T("Filtering complete"));
    break;
    }

    }

    }
    }

    Sorry my C++ skills are a little more rusty then I thought. I can not seem to figure out the correct way to define the ReleaseInterface method. I did try changing the properties of the Visual Studio 2003 C++ project to use __cdecl as the calling convention instead of __stdcall that did not help.

    Here is the compiler error I am getting.


    error C2664: 'atexit' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)'

    Let me know if you need more information and thanks for your help.[/code]

    #6090

    Vadim Smirnov
    Moderator

    Basically using atexit() the way you did is not correct, you should pass a static function to atexit() instead of C++ class method. Also, since you are making the windows service you can release interfaces when your service process is stopped instead of using atexit().

    From the design point of view I would create a C++ classe to wrap each interface and manipulated adapter thru this class ( ReleaseInterface functionality could be placed into the class destructor). Some more advanced WinpkFilter code can be downloaded from this page http://www.ntkernel.com/w&p.php?id=31 once you are a registered customer.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.