VC based implementation of network monitoring function program example

  • 2020-04-02 02:35:31
  • OfStack

The VC++ network listener code described in this paper, can realize the function of monitoring the network connection used by the protocol, source IP address, target IP address and other information, and can bind the data content to the grid control display. The specific functional code is shown as follows:


//The thread function
UINT ThreadFun( LPVOID pParam )
{
 CSniffAppDlg* pDlg = static_cast<CSniffAppDlg*>(pParam);
 MSG msg;
 char buffer[1000],sourceip[32] ,*tempbuf;
 char *ptemp;
 BYTE* pData = NULL; //Data in the actual datagram
 UINT sourceport ;
 CString str;
 HEADIP*  pHeadIP;
 HEADICMP* pHeadICMP;
 HEADUDP*  pHeadUDP;
 HEADTCP*  pHeadTCP;
 in_addr addr;
 int ret;
 while (TRUE)
 {
 pData = NULL;
 if (PeekMessage(&msg,pDlg->m_hWnd,WM_CLOSE,WM_CLOSE,PM_NOREMOVE ))
 {
  closesocket(pDlg->m_Sock);
  break; 
 }
 memset(buffer,0,1000);
 ret = recv(pDlg->m_Sock,buffer,1000,0);
 
 if (ret == SOCKET_ERROR)
 {
  continue;
 }
 else //Received data
 {
  tempbuf = buffer;
  pHeadIP = (HEADIP*)tempbuf;
  //Gets the total length of the datagram
  WORD len = ntohs(pHeadIP->totallen);
  
  //Get the source IP
  pDlg->m_List.InsertItem(pDlg->m_List.GetItemCount(),"");
  addr.S_un.S_addr = pHeadIP->sourceIP;
  ptemp = inet_ntoa(addr);
  
  pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,1,ptemp);
 
  //Get destination IP
  addr.S_un.S_addr = pHeadIP->destIP;
  ptemp = inet_ntoa(addr);
  pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,2,ptemp);
  
  //Get protocol name
  ptemp = get_protoname(pHeadIP->proto);
  strcpy(sourceip,ptemp);
  pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,0,sourceip);
  
  //Gets the total length of the IP datagram
  WORD ipSumLen = ntohs(pHeadIP->totallen);
  
  //Total IP data header length
  int ipHeadLen = 20;
  //Gets the length of the IP layer data removed
  WORD netlen = ipSumLen - ipHeadLen;
  
  //Obtain data of different protocols according to different large protocols
  switch (pHeadIP->proto)
  {
  case IPPROTO_ICMP:
  {
   pHeadICMP = (HEADICMP*)(tempbuf+20); 
   
   pData = (BYTE*)(pHeadICMP)+4; //The ICMP data header consists of four bytes
   //Gets the length of the data
   netlen -= 4;
   break;
  }
  case IPPROTO_UDP:
  {
   pHeadUDP = (HEADUDP*)(tempbuf+20); 
   pData = (BYTE*)pHeadUDP+8; //UDP data header has 8 bytes
   sourceport = ntohs(pHeadUDP->SourcePort);
   str.Format("%d",sourceport);
   //Set the source port
   pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str); 
   str.Empty();
   netlen -= 8;  
   break;
  }
  case IPPROTO_TCP:
  {
   pHeadTCP = (HEADTCP*)(tempbuf+20);
   sourceport = ntohs(pHeadTCP->SourcePort);   
   pData = (BYTE*)pHeadTCP+20; //TCP data headers have a total of 20 bytes
   str.Format("%d",sourceport);
   //Set the source port
   pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str); 
   str.Empty();
   netlen-= 20;  
   break;
  }     
  }
  //Set the data size
  str.Format("%d",netlen);
  pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,4,str);
  str.Empty();
  //Set up the data
  if (pData != NULL)
  {
  str.Format(" %s",pData);
  pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,5,str);
  }
  str.Empty();
 }
 }
 return 0;
}
void CSniffAppDlg::OnBeginlisten() 
{
 //Create a socket
 m_Sock = socket(AF_INET,SOCK_RAW, IPPROTO_IP );
 char name[128];
 memset(name,0,128);
 hostent* phostent;
 phostent = gethostbyname(name);
 DWORD ip;
 ip = inet_addr(inet_ntoa(*(in_addr*)phostent->h_addr_list[0]));
 int timeout = 4000; //Timeout 4 seconds
 //Sets the timeout for the received data
 setsockopt(m_Sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(timeout));
 sockaddr_in skaddr;
 skaddr.sin_family = AF_INET;
 skaddr.sin_port = htons(700);
 skaddr.sin_addr.S_un.S_addr = ip;
 //Binding address
 if ( bind(m_Sock,(sockaddr*)&skaddr,sizeof(skaddr))==SOCKET_ERROR)
 {
 MessageBox(" Address binding error ");
 return;
 }
 DWORD inBuffer=1;
 DWORD outBuffer[10];
 DWORD reValue = 0;
 if (WSAIoctl(m_Sock,SIO_RCVALL,&inBuffer,sizeof(inBuffer),&outBuffer,sizeof(outBuffer),&reValue,NULL,NULL)==SOCKET_ERROR)
 {
 MessageBox(" Buffer setting error .");
 closesocket(m_Sock);
 return;
 }
 else
 m_pThread = AfxBeginThread(ThreadFun,(void*)this);
}
void CSniffAppDlg::OnCancel()
{
 if (m_pThread)
 {
 //m_pThread->ExitInstance();
 delete m_pThread;
 }
 closesocket( m_Sock) ;
 CDialog::OnCancel();
}

This example is only the main part of the functional code, readers can according to their own project requirements to test, improve and perfect after integration into their own project.


Related articles: