icmp



  • hi
    main.cpp

    #include <windows.h>
    #include <iostream>
    #include <sstream>
    #include <string>
    
    #include "thread.h"
    #include "solv.h"
    #include "icmp.h"
    
    #define MAX 1
    
    using namespace std;
    
    #pragma comment(lib, "ws2_32.lib")
    #pragma comment(lib, "kernel32.lib")
    
    DWORD WINAPI process(LPVOID lp_para);
    string convert_int(int i);
    int start_wsa(void);
    void enter(void);
    void leave(void);
    
    LONG crit_sec = false; 
    
    FILE *file;
    
    int main()
    {
    	if(start_wsa()){
    		cout << " WSA Error: " << WSAGetLastError() << endl << endl;
    		system("Pause");
    		return 1;
    	}
    
    	file = fopen("C:\\icmp2.log", "w");
    	THREAD thread[MAX];
    	for(int i = 0; i < MAX; i++){
    		if(thread[i].create_thread(process, (LPVOID)&thread[i])){
    			cout << ">  Thread: " << i + 1 << " konnte nicht erstellt werden\n"
    				"Das Programm wird beendet!\n\n";
    
    			system("Pause");
    			return 1;			
    		}
    		cout << ">  Thread: " << i + 1 << " wurde erstellt\n";
    	}
    
    	for(i = 0; i < 256; i++){
    		for(int j = 0; true; j++){
    			if(!thread[j % MAX].get_work_state()){	
    				string cu_ip = "213.147.0." + convert_int(i);
    				thread[j % MAX].set_ip(cu_ip);
    				thread[j % MAX].set_work_state(true);
    				break;
    			}
    			Sleep(1);
    		}
    	}
    
    	Sleep(3000);
    	for(i = 0; i < MAX; i++)
    		thread[i].set_term(true);		
    
    	system("Pause");
    	return 0;
    }
    
    DWORD WINAPI process(LPVOID lp_para)
    {
    	THREAD *t = (THREAD*)lp_para;	
    
    	DWORD cur_proc_addr = GetCurrentThreadId();
    	ICMP_ *icmp = new ICMP_((unsigned short)cur_proc_addr);
    
    	while(!t->get_term()){
    		if(t->get_work_state()){	
    			int res;
    			res = icmp->echo_ex(t->get_ip());
    			string tmp;
    
    			if(!res){
    				enter();				
    				 tmp = "   " + t->get_ip() + " ->     reachable\n"; 
    				 fputs(tmp.c_str(), file);
    				 cout << cur_proc_addr << "     ";
    				 cout << tmp;				 
    				leave();
    			} else{
    				enter();				
    				 tmp = "   " + t->get_ip() + " ->     -\n"; 
    				 fputs(tmp.c_str(), file);
    				 cout << tmp;
    				leave();
    			}
    
    			t->set_work_state(false);
    		}
    
    		Sleep(1);
    	}
    	return ((DWORD) lp_para);
    }
    
    string convert_int(int i)
    {
    	stringstream str;
    	string foo;
    
    	str << i;
    	str >> foo;
    
    	return foo;
    }
    
    void enter(void)
    {
       while(InterlockedExchange(&crit_sec, true) != false)
          Sleep(0); 
    }
    
    void leave(void)
    {
       InterlockedExchange(&crit_sec, false); 
    }
    
    int start_wsa(void)
    {
    	WORD wVersionRequested;
    	WSADATA wsaData;
    	wVersionRequested = MAKEWORD( 2, 2);
    
    	return WSAStartup( wVersionRequested, &wsaData );
    }
    

    icmp.cpp

    #include <windows.h>
    #include <stdlib.h>
    #include <string>
    #include <sstream>
    #include <iostream>
    #include <stdio.h>
    #include <iostream.h>
    
    #include "icmp.h"
    
    using namespace std;
    
    #define ICMP_ECHOREPLY                 0
    #define ICMP_UNREACHABLE               3
    #define ICMP_ECHO                      8
    
    // 0 = Netz nicht erreichbar
    #define ICMP_CODE_NETWORK_UNREACHABLE  0
    // 1 = Rechner nicht erreichbar
    #define ICMP_CODE_HOST_UNREACHABLE     1
    
    // Minimalgrösse 8 Byte
    #define ICMP_MIN            8
    
    #define STATUS_FAILED       0xFFFF
    #define DEF_PACKET_SIZE     32
    #define MAX_PACKET          65000
    
    int ICMP_::echo_ex(string ip)
    {
      SOCKET sockRaw;
      SOCKADDR_IN addrDest;
      SOCKADDR_IN addrFrom;
      int addrFromLen = sizeof(addrFrom);
      HOSTENT* ptrHostent;
      unsigned long datasize;
      int RecvTimeout = 1000;
      char *dest_ip;
      char *icmp_data;
      char *recvbuf;
      unsigned int addr=0;
      unsigned short seq_no = 0;
      int BytesReceived;
      int BytesSent;
      long rc;
      unsigned ping_anzahl=0;
    
      sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
      if (sockRaw == INVALID_SOCKET)
      {
        return 1;
      }
      rc = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&RecvTimeout, sizeof(RecvTimeout));
      if(rc == SOCKET_ERROR)
      {
        return 1;
      }
    
      // Ip Adresse in ptrHostent geben
      ptrHostent = gethostbyname(ip.c_str());
    
      if ((!ptrHostent)  && (addr == INADDR_NONE) )
      {
        return 1;
      }
      if (ptrHostent != NULL)
      {
        memcpy(&(addrDest.sin_addr),ptrHostent->h_addr, ptrHostent->h_length);
      }
      else
      {
        addrDest.sin_addr.s_addr = addr;
      }
      if (ptrHostent)
      {
        addrDest.sin_family = ptrHostent->h_addrtype;
      }
      else
      {
        addrDest.sin_family = AF_INET;
      }
    
      // Konvertiert eine Netzwerk Adresse (SOCKADDR_IN) in einen String im Punkt Format (x.x.x.x)
      dest_ip = inet_ntoa(addrDest.sin_addr);
    
      // Gröss des Datenpaketes
      datasize = 32;
    
      if (datasize == 0)
      {
         datasize = DEF_PACKET_SIZE;
      }
    
      if (datasize > MAX_PACKET)
      {
         datasize = DEF_PACKET_SIZE;
      }
    
      datasize += sizeof(ICMP_HEADER);
    
      icmp_data = (char*)malloc(MAX_PACKET);
      recvbuf = (char*)malloc(MAX_PACKET+sizeof(IP_HEADER)+sizeof(ICMP_HEADER));
    
      if (!icmp_data || !recvbuf)
      {
        return 1;
      }
      ostringstream os;
    
     // MessageBox(0, os.str().c_str(), "PID", MB_OK);
      FillIcmpData(icmp_data, datasize);
    
        ((ICMP_HEADER*)icmp_data)->i_cksum = 0;
        ((ICMP_HEADER*)icmp_data)->timestamp = GetTickCount();
    
        ((ICMP_HEADER*)icmp_data)->i_seq = seq_no++;
        ((ICMP_HEADER*)icmp_data)->i_cksum = checksum((unsigned short*)icmp_data, datasize);
    
        BytesSent = sendto(sockRaw,icmp_data,datasize,0,(SOCKADDR*)&addrDest, sizeof(addrDest));
    
        if (BytesSent == SOCKET_ERROR)
        {
          if (WSAGetLastError() == WSAETIMEDOUT)
          {
          }
          return 1;
        }
        if (BytesSent < datasize )
        {
       }
        BytesReceived = recvfrom(sockRaw,recvbuf,MAX_PACKET+sizeof(IP_HEADER)+sizeof(ICMP_HEADER),0,(SOCKADDR*)&addrFrom, &addrFromLen);
    
       if (BytesReceived == SOCKET_ERROR)
        {
          if (WSAGetLastError() == WSAETIMEDOUT)
          {
          }
    
          return 1;
        }    
      closesocket(sockRaw);
      return 0;
    }
    
    void ICMP_::FillIcmpData(char *icmp_data, int datasize)
    {
      ICMP_HEADER *icmp_hdr;
      char *datapart;
    
      icmp_hdr = (ICMP_HEADER*)icmp_data;
    
      icmp_hdr->i_type = ICMP_ECHO;
      icmp_hdr->i_code = 0;
      icmp_hdr->i_id = cur_proc_addr;
      icmp_hdr->i_cksum = 0;
      icmp_hdr->i_seq = 0;
    
      datapart = icmp_data + sizeof(ICMP_HEADER);
      // Den Buffer mit etwas füllen
      memset(datapart,'C', datasize - sizeof(ICMP_HEADER));
    }
    
    unsigned short ICMP_::checksum(unsigned short *buffer, int size)
    {
      unsigned long cksum=0;
      while(size >1)
      {
        cksum+=*buffer++;
        size -=sizeof(unsigned short);
      }
    
      if(size)
      {
        cksum += *(unsigned char*)buffer;
      }
    
      cksum = (cksum >> 16) + (cksum & 0xffff);
      cksum += (cksum >>16);
      return (unsigned short)(~cksum);
    }
    
    void ICMP_::DecodeResponse(char *buf,int bytes, SOCKADDR_IN *from)
    {
      IP_HEADER   *IpHeader;
      ICMP_HEADER *IcmpHeader;
      unsigned short IpHeaderLen;
    
      IpHeader = (IP_HEADER*)buf;
      IpHeaderLen = IpHeader->h_len * 4 ; // number of 32-bit words *4 = bytes
    
      if (bytes  < IpHeaderLen + ICMP_MIN)
      {
    	return;
      }
      IcmpHeader = (ICMP_HEADER*)(buf + IpHeaderLen);
    
      if (IcmpHeader->i_type != ICMP_ECHOREPLY)
      {
        if (IcmpHeader->i_type == ICMP_UNREACHABLE)
        {
          if(IcmpHeader->i_code == ICMP_CODE_HOST_UNREACHABLE)
          {
            return;
          }
          if(IcmpHeader->i_code == ICMP_CODE_NETWORK_UNREACHABLE)
          {
            return;
          }
        }
        else
        {
          return;
        }
      }
    
      if (IcmpHeader->i_id != cur_proc_addr)
      {
        return;
      }
    }
    
    long ICMP_::WinsockStartup()
    {
      long rc;
    
      WORD wVersionRequested;
      WSADATA wsaData;
      wVersionRequested = MAKEWORD(2, 1);
    
      rc = WSAStartup( wVersionRequested, &wsaData );
      return rc;
    }
    

    folgendes problem:
    wenn ich MAX auf 10 setzte sprich wenn 10 threads erstellt werden, sind die ping echos immer gleich, dh alle server sind nach dem programm erreichbar...
    jedoch kann das nicht stimmen. also ist das programm falsch, nur hab ich schon nach langen überlegungen keinen blassen schimmer woran es liegen könnte.
    also: mit einem bzw 2 thread bekomm ich die richtigen ergebnisse bei mehr als 2
    wird es verfälscht... hat jemand eine idee?

    gruß _xerxes_


Anmelden zum Antworten