R
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