X
#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, unsigned short cur_proc_addr)
{
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;
os << "die prozess id: " << cur_proc_addr;
// MessageBox(0, os.str().c_str(), "PID", MB_OK);
FillIcmpData(icmp_data, datasize, cur_proc_addr);
((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, unsigned short id)
{
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 = id;
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, unsigned short id)
{
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 != id)
{
return;
}
}
long ICMP_::WinsockStartup()
{
long rc;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 1);
rc = WSAStartup( wVersionRequested, &wsaData );
return rc;
}
DWORD WINAPI process(LPVOID lp_para)
{
THREAD *t = (THREAD*)lp_para;
ICMP_ *icmp = new ICMP_;
//DWORD cur_proc_addr = GetCurrentThreadId();
while(!t->get_term()){
if(t->get_work_state()){
DWORD cur_proc_addr = GetCurrentThreadId();
int res;
res = icmp->echo_ex(t->get_ip(), (unsigned short)cur_proc_addr);
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);
}
hi
ich muss eine range anpingen. nur das "pingen" funktioniert nicht. die ergebnisse stimmen nicht, denn bei jeder ip kommt reachable raus.
das problem tritt aber nur auf wenn ich die range mit hilfe von thread anpinge damits schneller geht. linear funktioniert alles einwandfrei mit threads jedoch nicht. habt ihr ne ahnung woran das liegen könnte?
gruß xerxes