Why CPU overhead reach abnormal 100%???Strange!!!!!!!!!!!!!!

Home Forums Discussions Support Why CPU overhead reach abnormal 100%???Strange!!!!!!!!!!!!!!

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #5164
    speedvoipok
    Participant

      I have designed and implemented a simple packet dispatch engine(PDE) which is based upon passthrough sample of Winpkfilter. Our PDE is also build as .dll and only a thin wrapper to passthru. But after running PDE for small while, CPU overhead abnormally reach 100%, Why to behavior so? I try my best to look through my program for several days, but pity to get no result, Help me! Ndis-Guru..
      Source code is list as follows:

      Pde.cpp
      ======
      #include “stdafx.h”
      #include “iphlp.h”
      #include “..VgLogVgLog.h”
      #include “Pde.h”

      //


      Global declaration


      VG_PDE_CONTEXT g_VgPdeContext; // Pde control context
      CNdisApi g_CNdisApi; // CNdisApi class interface instance

      //


      Macros


      //


      DLL Main Entry


      // BOOL APIENTRY DllMain( HANDLE hModule,
      // DWORD ul_reason_for_call,
      // LPVOID lpReserved
      // )
      // {
      // switch (ul_reason_for_call)
      // {
      // case DLL_PROCESS_ATTACH:
      // case DLL_THREAD_ATTACH:
      // case DLL_THREAD_DETACH:
      // case DLL_PROCESS_DETACH:
      // break;
      // }
      // return TRUE;
      // }

      //


      Function implementation


      static USHORT _ntohs(USHORT netshort)
      {
      PUCHAR pBuffer;
      USHORT nResult;

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

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

      return( nResult );
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeStartup
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      VGPDE_STATUS VGPDEAPI VgPdeStartup(unsigned char *pAdapterMac)
      {
      HANDLE currentHandle;

      VgPdeSetActiveAdapterHandle(pAdapterMac);
      currentHandle = VgPdeGetActiveAdapterHandle();

      if(!g_CNdisApi.IsDriverLoaded())
      {
      VGPDELOG(“Driver not installed on this system, failed to load.n”);
      return VGPDEERRDRVNOTFOUND;
      }

      if(!g_CNdisApi.GetTcpipBoundAdaptersInfo(&g_VgPdeContext.adList))
      {
      VGPDELOG(“Error in getting adapters on this system.n”);
      return VGPDEERRNOTGETADAPTERS;
      }

      // g_VgPdeContext.activeAdIndex = 0; /* default adapter index */

      g_VgPdeContext.mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL;
      g_VgPdeContext.mode.hAdapterHandle = currentHandle;
      // Create notification event
      g_VgPdeContext.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      if((!g_VgPdeContext.hEvent) || (!g_CNdisApi.SetPacketEvent(currentHandle, g_VgPdeContext.hEvent)))
      {
      VGPDELOG(“Failed to set notification event for driver.n”);
      return (0x1); // abnormal exit
      }

      // Initialize reception Request
      ZeroMemory(&g_VgPdeContext.rxReq, sizeof(ETH_REQUEST));
      ZeroMemory(&g_VgPdeContext.rxpktBuf, sizeof(INTERMEDIATE_BUFFER));
      g_VgPdeContext.rxReq.EthPacket.Buffer = &g_VgPdeContext.rxpktBuf;
      g_VgPdeContext.rxReq.hAdapterHandle = currentHandle;

      // // Initialize transmission Request
      // ZeroMemory(&g_VgPdeContext.txReq, sizeof(ETH_REQUEST));
      // ZeroMemory(&g_VgPdeContext.txpktBuf, sizeof(INTERMEDIATE_BUFFER));
      // g_VgPdeContext.txReq.EthPacket.Buffer = &g_VgPdeContext.txpktBuf;

      // Initialize event handler sets for callback
      ZeroMemory(&g_VgPdeContext.pktEvSets, sizeof(VG_PACKET_EVENT_HANDLER_SET));

      g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode);

      g_VgPdeContext.hThread = CreateThread(NULL, 0, PacketDispatchEngine, 0,
      0, NULL);

      return VGPDE_OK;
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeCleanup
      //
      // Purpose
      // This function releases packets in the adapter queue and stops listening
      // the interface
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      void VGPDEAPI VgPdeCleanup()
      {
      g_VgPdeContext.mode.dwFlags = 0;
      g_VgPdeContext.mode.hAdapterHandle = VgPdeGetActiveAdapterHandle();

      // Set NULL event to release previously set event object
      g_CNdisApi.SetPacketEvent(VgPdeGetActiveAdapterHandle(), NULL);

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

      // Set default adapter mode
      g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode);

      // Empty adapter packets queue
      g_CNdisApi.FlushAdapterPacketQueue (VgPdeGetActiveAdapterHandle());
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeRegister
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      BOOL VGPDEAPI VgPdeRegister(PVG_PACKET_EVENT_HANDLER_SET pPktEvSet)
      {
      if (NULL == pPktEvSet)
      return FALSE;

      g_VgPdeContext.pktEvSets.pfnEvArpHandler = pPktEvSet->pfnEvArpHandler;
      g_VgPdeContext.pktEvSets.pfnEvIpHandler = pPktEvSet->pfnEvIpHandler;

      return TRUE;
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeUnRegister
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      void VGPDEAPI VgPdeUnRegister()
      {
      g_VgPdeContext.pktEvSets.pfnEvArpHandler = NULL;
      g_VgPdeContext.pktEvSets.pfnEvIpHandler = NULL;
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeGetActiveAdapterHandle
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      HANDLE VGPDEAPI VgPdeGetActiveAdapterHandle()
      {
      return g_VgPdeContext.adList.m_nAdapterHandle[g_VgPdeContext.activeAdIndex];
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeGetAdapterHandleByIndex
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      HANDLE VGPDEAPI VgPdeGetAdapterHandleByIndex(DWORD adIdx)
      {
      return g_VgPdeContext.adList.m_nAdapterHandle[adIdx];
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeSetActiveAdapterHandle
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      VGPDE_STATUS VGPDEAPI VgPdeSetActiveAdapterHandle(unsigned char *pAdapterMac)
      {
      unsigned long i;
      int j;
      BOOL bFindAdapter = FALSE;

      if(NULL == pAdapterMac)
      return VGPDE_FAILURE;

      // search possible adapter mac address
      for(i = 0; i < g_VgPdeContext.adList.m_nAdapterCount; i++)
      {
      for(j = 0; j < ETHER_ADDR_LENGTH; j++)
      if(g_VgPdeContext.adList.m_czCurrentAddress[j] != pAdapterMac[j])
      break;
      if(j == ETHER_ADDR_LENGTH) // adapter found
      {
      bFindAdapter = TRUE;
      g_VgPdeContext.activeAdIndex = i;
      break;
      }
      }

      if(bFindAdapter)
      return VGPDE_OK;
      else
      {
      VGPDELOG(“Adapter not Found on this system!n”);
      return VGPDEERRADAPTERNOTFOUND;
      }
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeInvoke
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      VGPDE_STATUS VGPDEAPI VgPdeInvoke()
      {
      g_VgPdeContext.hThread = CreateThread(NULL, 0, PacketDispatchEngine, 0,
      0, NULL);
      if(!g_VgPdeContext.hThread)
      return VGPDE_FAILURE;
      return VGPDE_OK;
      }

      /////////////////////////////////////////////////////////////////////////////
      //// PacketDispatchEngine
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //

      DWORD WINAPI PacketDispatchEngine(LPVOID pParam)
      {
      DWORD currentAdIdx = g_VgPdeContext.activeAdIndex;
      HANDLE currentHandle = VgPdeGetAdapterHandleByIndex(currentAdIdx);
      HANDLE activeHandle;
      ether_header_ptr pEthHeader = NULL;
      arphdr_ptr pArpHeader = NULL;
      VG_PACKET_DESCRIPTOR pktDescriptor;

      while(TRUE)
      {
      activeHandle = VgPdeGetActiveAdapterHandle();
      if(currentHandle != activeHandle) // active adapter changed!!!
      {
      currentHandle = activeHandle; // point to current adapter

      g_VgPdeContext.mode.hAdapterHandle = currentHandle;
      g_VgPdeContext.rxReq.hAdapterHandle = currentHandle; // Hook rxReq with adapter
      g_CNdisApi.SetPacketEvent(currentHandle, g_VgPdeContext.hEvent); // hook event with adapter
      g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode); // set adapter mode
      }

      //
      // Wait before active interface is ready to indicate the packet
      //
      WaitForSingleObject (g_VgPdeContext.hEvent, INFINITE);
      ResetEvent(g_VgPdeContext.hEvent);

      //
      // Read packet from the interface until there are any
      //
      while(g_CNdisApi.ReadPacket(&g_VgPdeContext.rxReq))
      {
      //
      // Get Ethernet header
      //
      pEthHeader = (ether_header_ptr)g_VgPdeContext.rxpktBuf.m_IBuffer;

      // packet descriptor manipulation
      pktDescriptor.nPktLen = g_VgPdeContext.rxpktBuf.m_Length; // frame length
      pktDescriptor.pPktBuf = g_VgPdeContext.rxpktBuf.m_IBuffer; // full frame including ether header
      if (g_VgPdeContext.rxpktBuf.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
      pktDescriptor.ePktDirection = VG_PACKET_FROM_MSTCP;
      else
      pktDescriptor.ePktDirection = VG_PACKET_FROM_NIC;

      //
      // Check if Ethernet frame contains ARP packet
      //
      if(_ntohs(pEthHeader->h_proto) == ETH_P_ARP)
      {
      // packet type specified
      pktDescriptor.ePktType = VG_PACKET_ARP;
      //
      // ARP packet handler callback
      //
      if(g_VgPdeContext.pktEvSets.pfnEvArpHandler != NULL)
      g_VgPdeContext.pktEvSets.pfnEvArpHandler(&pktDescriptor);
      }
      else if(_ntohs(pEthHeader->h_proto) == ETH_P_IP)
      {
      // packet type specified
      pktDescriptor.ePktType = VG_PACKET_IP;
      //
      // IP packet handler callback
      //
      if(g_VgPdeContext.pktEvSets.pfnEvIpHandler != NULL)
      g_VgPdeContext.pktEvSets.pfnEvIpHandler(&pktDescriptor);
      }
      }
      }

      return 0;
      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeTransmit
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      BOOL VGPDEAPI VgPdeTransmit(char *pPktBuf, int pktLength, VG_PACKET_DIRECTION eDirection)
      {
      if(NULL == pPktBuf)
      return FALSE;

      // Copy packet contents including ether header
      memcpy(g_VgPdeContext.rxpktBuf.m_IBuffer, pPktBuf, pktLength);
      // set packet length
      g_VgPdeContext.rxpktBuf.m_Length = pktLength;

      if(eDirection == VG_PACKET_TO_NIC)
      return (g_CNdisApi.SendPacketToAdapter(&g_VgPdeContext.rxReq));
      else
      return (g_CNdisApi.SendPacketToMstcp(&g_VgPdeContext.rxReq));

      }

      /////////////////////////////////////////////////////////////////////////////
      //// VgPdeForward
      //
      // Purpose
      //
      // Parameters
      //
      // Return Value
      //
      // Remarks
      //
      BOOL VGPDEAPI VgPdeForward(char *pPktBuf, int pktLength, unsigned char *pDestMac)
      {
      ether_header_ptr pEtherHdr = NULL;

      return TRUE;
      }

      static void _PdeLog(PDE_LOG_LEVEL level,char *module,const char *fmt, …)
      {

      char buf[16];
      const char *s;
      int d;
      va_list ap;
      FILE * pLogFile = NULL;
      char filename[MAX_PATH];

      strcpy(filename,PDE_LOG_FILE);
      pLogFile = fopen(filename,”a+”);
      if(pLogFile == NULL)
      return;

      SYSTEMTIME sysTime;
      GetSystemTime(&sysTime);

      switch(level)
      {
      case PDE_LOG_LEVEL_INFO:
      fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Information: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
      sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
      break;

      case PDE_LOG_LEVEL_ERROR:
      fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Error: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
      sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
      break;
      case PDE_LOG_LEVEL_FATAL:
      fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Fatal: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
      sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
      break;
      default: break;
      }

      va_start(ap, fmt);
      while (*fmt)
      {
      if (*fmt != ‘%’)
      {
      fputc(*fmt++,pLogFile);
      continue;
      }
      switch (*++fmt)
      {
      case ‘s’:
      case ‘S’:
      s = va_arg(ap, const char *);
      for ( ; *s; s++)
      {
      fputc(*s,pLogFile);
      }
      break;
      case ‘d’:
      case ‘D’:
      d = va_arg(ap, int);
      itoa(d, buf, 10);
      for (s = buf; *s; s++)
      {
      fputc(*s,pLogFile);
      }
      break;
      /* Add other specifiers here… */
      case ‘x’:
      case ‘X’:
      d = va_arg(ap, int);
      itoa(d, buf, 16);
      for (s = buf; *s; s++)
      {
      fputc(*s,pLogFile);
      }
      break;

      default:
      fputc(*fmt,pLogFile);
      break;
      }
      fmt++;
      }
      va_end(ap);
      fprintf(pLogFile,”n”);
      fclose(pLogFile);
      }

      Pde.h
      ====
      #ifndef _PDE_H
      #define _PDE_H

      #include
      #include
      #include
      #include

      #define VG_PDE_NDIS_HOOKING // Upon NDIS-Hooking NdisRD driver
      #ifdef VG_PDE_NDIS_HOOKING
      #include “..NdisRdincludecommon.h”
      #include “..NdisRdincludendisapi.h”
      #endif

      // The following ifdef block is the standard way of creating macros which make exporting
      // from a DLL simpler. All files within this DLL are compiled with the PDE_EXPORTS
      // symbol defined on the command line. this symbol should not be defined on any project
      // that uses this DLL. This way any other project whose source files include this file see
      // PDE_API functions as being imported from a DLL, whereas this DLL sees symbols
      // defined with this macro as being exported.
      #ifdef PDE_EXPORTS
      #define PDE_API __declspec(dllexport)
      #else
      #define PDE_API __declspec(dllimport)
      #endif

      #define VGPDEAPI WINAPI

      #define VGPDE_DEBUG

      #ifdef VGPDE_DEBUG
      #define VGPDELOG(_x)
      _PdeLog(PDE_LOG_LEVEL_ERROR, “Pde”, (_x))
      #else
      #define VGPDELOG(_x)
      #endif

      //#define ReleaseInterface VgPdeCleanup
      #define _htons _ntohs

      /*
      * All PDE error constants are biased by VGPDEERRBASE from
      * the “normal”
      */
      #define VGPDEERRBASE 1000
      #define VGPDEERRDRVNOTFOUND (VGPDEERRBASE + 1)
      #define VGPDEERRNOTGETADAPTERS (VGPDEERRBASE + 2)
      #define VGPDEERRADAPTERNOTFOUND (VGPDEERRBASE + 3)
      #define VGPDEERRCREATEEVENT (VGPDEERRBASE + 4)

      #define VGPDE_OK 0
      #define VGPDE_FAILURE -1

      #define PDE_LOG_FILE “..\bin\PdeLog.txt”

      #pragma pack(1)

      typedef enum _PDE_LOG_LEVEL
      {
      PDE_LOG_LEVEL_INFO = 0,
      PDE_LOG_LEVEL_ERROR,
      PDE_LOG_LEVEL_FATAL
      }PDE_LOG_LEVEL;

      typedef int VGPDE_STATUS;

      typedef enum _VG_PACKET_TYPE // type of packet
      {
      VG_PACKET_ARP = 0,
      VG_PACKET_IP
      }VG_PACKET_TYPE;

      typedef enum _VG_PACKET_DIRECTION // flow direction of packet
      {
      VG_PACKET_FROM_MSTCP,
      VG_PACKET_FROM_NIC,
      VG_PACKET_TO_MSTCP,
      VG_PACKET_TO_NIC
      }VG_PACKET_DIRECTION;

      typedef UCHAR VG_PACKET_BUF, *PVG_PACKET_BUF;

      typedef struct _VG_PACKET_DESCRIPTOR
      {
      VG_PACKET_TYPE ePktType;
      VG_PACKET_DIRECTION ePktDirection;
      PVG_PACKET_BUF pPktBuf;
      UINT nPktLen;
      }VG_PACKET_DESCRIPTOR, *PVG_PACKET_DESCRIPTOR;

      typedef BOOL (*VG_PACKET_EVENT_HANDLER)(IN PVG_PACKET_DESCRIPTOR pPktDes);

      typedef struct _VG_PACKET_EVENT_HANDLER_SET
      {
      VG_PACKET_EVENT_HANDLER pfnEvArpHandler; // for ARP packet
      VG_PACKET_EVENT_HANDLER pfnEvIpHandler; // for IP packet
      }VG_PACKET_EVENT_HANDLER_SET, *PVG_PACKET_EVENT_HANDLER_SET;

      /* Core control data structure */
      typedef struct _VG_PDE_CONTEXT
      {
      HANDLE hThread; // worker thread for packet event indication
      TCP_AdapterList adList; // array of all adapters within system
      DWORD activeAdIndex; // current active adapter
      ADAPTER_MODE mode; // adapter working mode
      ETH_REQUEST rxReq; // for packet reception
      INTERMEDIATE_BUFFER rxpktBuf; // holding real packet contents for reception
      ETH_REQUEST txReq; // for packet transmission
      INTERMEDIATE_BUFFER txpktBuf; // holding real packet contents for transmission
      HANDLE hEvent; // for event notification between pde and ndisrd driver
      VG_PACKET_EVENT_HANDLER_SET pktEvSets;
      }VG_PDE_CONTEXT, *PVG_PDE_CONTEXT;

      // This class is exported from the Pde.dll
      class PDE_API CPde
      {
      public:
      CPde(void);
      // TODO: add your methods here.
      };

      static USHORT _ntohs(USHORT netshort);
      DWORD WINAPI PacketDispatchEngine(LPVOID pParam);
      static void _PdeLog(PDE_LOG_LEVEL level,char *module,const char *fmt, …);

      extern “C”
      {
      VGPDE_STATUS VGPDEAPI VgPdeStartup(unsigned char *pAdapterMac);
      void VGPDEAPI VgPdeCleanup();
      BOOL VGPDEAPI VgPdeRegister(PVG_PACKET_EVENT_HANDLER_SET pPktEvSet);
      void VGPDEAPI VgPdeUnRegister();
      HANDLE VGPDEAPI VgPdeGetActiveAdapterHandle();
      HANDLE VGPDEAPI VgPdeGetAdapterHandleByIndex(DWORD adIdx);
      VGPDE_STATUS VGPDEAPI VgPdeSetActiveAdapterHandle(unsigned char *pAdapterMac);
      BOOL VGPDEAPI VgPdeTransmit(char *pPktBuf, int pktLength, VG_PACKET_DIRECTION eDirection);
      BOOL VGPDEAPI VgPdeForward(char *pPktBuf, int pktLength, unsigned char *pDestMac);
      };

      #endif

      Also here is PdeDemo.cpp which calls Pde.dll export routine.
      =============================================
      #include “stdafx.h”
      #include “..Pde.h”
      #include “..iphlp.h”

      #define PdeDemoShow printf

      unsigned char srcMac[] = {0x00, 0xC0, 0x9F, 0xF3, 0x45, 0x7A};
      unsigned char dstMac[] = {0x00, 0x1C, 0xF0, 0x47, 0xBA, 0x38};

      BOOL ArpHandler(IN PVG_PACKET_DESCRIPTOR pPktDes)
      {
      return TRUE;
      }

      BOOL IpHandler(IN PVG_PACKET_DESCRIPTOR pPktDes)
      {
      ether_header *pEthHdr = NULL;
      iphdr *pIpHdr = NULL;

      if (NULL == pPktDes)
      return FALSE;

      pEthHdr =(ether_header *)(pPktDes->pPktBuf);
      pIpHdr = (iphdr *)(pPktDes->pPktBuf + sizeof(ether_header));

      if(pPktDes->ePktDirection == VG_PACKET_FROM_NIC)
      {
      memcpy(pEthHdr->h_dest, dstMac, ETH_ALEN);
      memcpy(pEthHdr->h_source, srcMac, ETH_ALEN);
      if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
      {
      PdeDemoShow(“IpHandler@VgPdeTransmit errorn”);
      return FALSE;
      }
      }
      else /* from MSTCP */
      {
      if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
      {
      PdeDemoShow(“IpHandler@VgPdeTransmit errorn”);
      return FALSE;
      }
      }

      return TRUE;
      }

      int main(int argc, char* argv[])
      {
      VG_PACKET_EVENT_HANDLER_SET evHandlerSet;

      PdeDemoShow(“nPde Demo Apploication v1.0.0(Build 20080107) is running ….n”);
      PdeDemoShow(“Copyright(c)by SpeedVoIP Communication Technology Co., Ltd.n”);

      memset(&evHandlerSet, 0, sizeof(evHandlerSet));
      evHandlerSet.pfnEvArpHandler = ArpHandler;
      evHandlerSet.pfnEvIpHandler = IpHandler;

      VgPdeStartup(srcMac);
      VgPdeRegister(&evHandlerSet);

      while(1);

      return 0;
      }

      #6522
      Vadim Smirnov
      Keymaster

        I suppose the problem is not in the engine but in what you do with packets:

        if(pPktDes->ePktDirection == VG_PACKET_FROM_NIC)
        {
        memcpy(pEthHdr->h_dest, dstMac, ETH_ALEN);
        memcpy(pEthHdr->h_source, srcMac, ETH_ALEN);
        if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
        {
        PdeDemoShow("IpHandler@VgPdeTransmit errorn");
        return FALSE;
        }
        }
        else /* from MSTCP */
        {
        if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
        {
        PdeDemoShow("IpHandler@VgPdeTransmit errorn");
        return FALSE;
        }
        }

        I don’t know what are the MAC addresses you have used are taken from. But if the address you set as source MAC does not match the NIC address you send the packet from then you may meet problems. In Windows all packets sent on the network are normally indicated back to protocol (so called hardware loopback). It is posssible to use NDIS_FLAGS_DONT_LOOPBACK or/and NDIS_FLAGS_SKIP_LOOPBACK flags (set for the packet in INTERMEDIATE_BUFFER.m_Flags) to prevent the loopback but these packets are system specific and not guarantee to work properly on every Windows, though I used them just fine for the Ethernet Bridge. WinpkFilter normally filters out the loopback packet by checking the source MAC address (packet is skipped if source MAC = NIC MAC), but in your case it may fail to do so (if source MAC does not match the NIC address) and even single packet starts going in the endless loop (from application to WinkFilter, then From WinpkFilter to NIC, from NIC to WinpkFilter, from WinpkFilter to application and so on) -> 100% CPU load.

        You can read this topic on forum regarding the loopback packets:

        http://www.ntkernel.com/forum/viewtopic.php?t=281

        #6523
        speedvoipok
        Participant

          Hi Vadim:
          I can make sure that in pdedemo.cpp src mac must match that of NIC over which packets send. I think loopback cause maybe be excluded from our consideration.
          Today I have taken another experiment on PDE, when adding extra code into pdedemo.cpp, all things are ok, CPU overhead revert to normal level, about 2~7%.
          ===============================================================================================
          /* yield control to windows to avoid high
          CPU overhead */
          while (GetMessage(&msg, NULL, 0, 0))
          {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
          }
          ===============================================================================================
          I feel that it has something to with Windows thread or process schedule.

        Viewing 3 posts - 1 through 3 (of 3 total)
        • You must be logged in to reply to this topic.