WinPkFilter from a class

Home Forums Discussions Support WinPkFilter from a class

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
      Keymaster

        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.