Ping - Alles ohne Fehler, aber es geht keine Packet raus!



  • Hi zusammen,
    versuche einen Ping in C++ direkt mit Sockets zu implementieren. Hab schon einiges gefunden und auch selbst geschrieben. Hab nur ein riessen Problem, dass alles ohne Fehler ablaeuft, aber kein Ping abgesetzt wird.

    Kann mir jemand helfen? Komm einfach nicht mehr weiter hier!

    Hier mal der Code:

    #include "StdAfx.h"
    #include ".\hosttoping.h"
    #include "ipexport.h"
    #include "ICMPAPI.h"
    #include "DefaultSetting.h"
    #include <ws2tcpip.h>
    #include <winsock2.h>
    #include <iostream>
    #pragma comment(lib,"iphlpapi.lib")
    #pragma comment(lib,"WS2_32.lib")
    
    using namespace std;
    
    HostToPing::HostToPing(CString IpAdress)
    {
    	this->IpAdress = IpAdress;
    }
    
    HostToPing::~HostToPing(void)
    {
    }
    
    int HostToPing::check_access(void) 
    {	
    	return ping(this->IpAdress);
    
    }
    
    int HostToPing::ping(CString IpAddress) {
    	SOCKET sock;
    	IpOptionHeader ipopt;
    
    	int ret;							//Return value for different functions to check errors
    	int datasize = 0;
    	int timeout = Default_Timeout;
    	int resultStartupWSA;
    
    	USHORT seq_no = 0;
    	WORD Version = MAKEWORD(2,2);		//Create Verision for WSASTartup with Macro
    	WSADATA lpWSAData;					//Further details - not used
    	char	 *icmp_data = NULL,
    			 *recvbuf = NULL;
    	sockaddr_in dest;					//Destination to reach (IP etc)
    
    	resultStartupWSA = WSAStartup(Version, &lpWSAData);		//Startup Winsocket (with Version)
    
    	sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
    	if (sock == INVALID_SOCKET) {
    		return -10;
    	}
    
    	//Set IP Options - for getting the route information 
    	ZeroMemory(&ipopt, sizeof(ipopt));		//Fill the Header wit zeros
        ipopt.code = IP_RECORD_ROUTE; // Record route option
        ipopt.ptr  = 4;               // Point to the first addr offset
        ipopt.len  = 39;              // Length of option header
    
    	ret = setsockopt(sock, IPPROTO_IP, IP_OPTIONS, 
            (char *)&ipopt, sizeof(ipopt));
        if (ret == SOCKET_ERROR)
        {
    		cerr << "setsockopt(IP_OPTIONS) failed: %d\n", WSAGetLastError();
    		return -20;
        }
    
    	// Set the send/recv timeout values
        ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, 
                    (char*)&timeout, sizeof(timeout));
        if(ret == SOCKET_ERROR) 
        {
    		cerr << "setsockopt(SO_RCVTIMEO) failed: %d\n", WSAGetLastError();
    		return -30;        
        }
    
    	timeout = 1000;	//Sendoptions
        ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, 
                    (char*)&timeout, sizeof(timeout));
        if (ret == SOCKET_ERROR) 
        {
    		cerr << "setsockopt(SO_SNDTIMEO) failed: %d\n", 
                WSAGetLastError();
        }
    
    	memset(&dest, 0, sizeof(dest));
    	dest.sin_family = AF_INET;
    	dest.sin_addr.s_addr=inet_addr("192.168.0.39");
    
        // Create the ICMP packet
        datasize += sizeof(IcmpHeader);  
        icmp_data = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                    Max_PacketSize);
        recvbuf = (char *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
    				Max_PacketSize);
        if (!icmp_data) 
        {
    		cerr << "HeapAlloc() failed: %d\n", GetLastError();
    		return -40;
        }
    
    	memset(icmp_data,0,Max_PacketSize);
        FillICMP(icmp_data,datasize);
    
    	//Send
    	((IcmpHeader*)icmp_data)->i_cksum = 0;
        ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
        ((IcmpHeader*)icmp_data)->i_seq = seq_no++;
        ((IcmpHeader*)icmp_data)->i_cksum = 
    		checksum((USHORT*)icmp_data, datasize);
    
    	ret = sendto(sock, icmp_data, datasize, 0,					
                         (struct sockaddr*)&dest, sizeof(dest));
    	if (ret < 1) {		//Return is the number of sent bytes
    		cerr << "Sento() failed: %d\n", WSAGetLastError();
    		return -50;			
    	}
    
    	//unload library for sockets -> important for Winsock dll Counter
    	resultStartupWSA = WSACleanup();
    	if (resultStartupWSA != 0) {
    		cerr << "Unload library for sockets not successfull";
    		return -60;
    	}
    }
    
    void HostToPing::FillICMP(char *icmp_data, int datasize)
    {
        IcmpHeader *icmp_hdr = NULL;
        char       *datapart = NULL;
    
        icmp_hdr = (IcmpHeader*)icmp_data;
        icmp_hdr->i_type = 8;        // Request an ICMP echo
        icmp_hdr->i_code = 0;
        icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
        icmp_hdr->i_cksum = 0;
        icmp_hdr->i_seq = 0;
    
        datapart = icmp_data + sizeof(IcmpHeader);
        //Fill the Echo with nonsense
        memset(datapart,'E', datasize - sizeof(IcmpHeader));
    }
    
    // Function: checksum
    //
    // Description:
    //    This function calculates the 16-bit one's complement sum
    //    of the supplied buffer (ICMP) header
    //
    USHORT HostToPing::checksum(USHORT *buffer, int size) 
    {
        unsigned long cksum=0;
    
        while (size > 1) 
        {
            cksum += *buffer++;
            size -= sizeof(USHORT);
        }
        if (size) 
        {
            cksum += *(UCHAR*)buffer;
        }
        cksum = (cksum >> 16) + (cksum & 0xffff);
        cksum += (cksum >>16);
        return (USHORT)(~cksum);
    }
    

    Hab nur versucht eine fixe IP zu pingen, aber nichts funktioniert.
    Hoffe, ihr habt einen Tip fuer mich!

    Danke schon mal!!

    Mark


Anmelden zum Antworten