Click to See Complete Forum and Search --> : Get IP address


Thanhvt
September 11th, 1999, 09:06 AM
Hi everybody.
I've tried to get the IP address of a computer when I know its name. I use gethostbyname() and then use the HOSTENT structure to get the address.
But it did not work. Can anyone tell me how to get an IP address with standard format "xxx.yyy.zzz.ttt" when I know the computer name (such as john or sally). Thanks

dmadden
September 12th, 1999, 12:24 AM
Here is an example PING.C & PING.H, I'm letting you see it as an example of how to do this...

There are calls to other classes/functions but you don't need them!

THIS IS THE PING.C

#include "Ping.h"

// Specifies packing alignment for structure and union members.
#pragma pack(4)

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0

#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)

/* The IP header */
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum

unsigned int sourceIP;
unsigned int destIP;

}IpHeader;

//
// ICMP header
//
typedef struct _ihdr {
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
}IcmpHeader;

#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree (GetProcessHeap(),0,(p))

void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
void decode_resp(char *buf, int bytes,struct sockaddr_in *from,
int* elapsedTime, int* dataSize, int* icmp_seq);

//-----------------------------------------------------------------------------
int Ping( const CString& hostToPing,
CString& HostToPingIP,
int* elapsedTime /*=NULL*/,
int* dataSize /*=NULL*/,
int* icmp_seq /*=NULL*/)
//-----------------------------------------------------------------------------
{

WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread, datasize=DEF_PACKET_SIZE;;
int fromlen = sizeof(from);
int timeout = 1000;
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;

if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
CErrorMgt::RaiseError("WSAStartup failed: %d\n",GetLastError());
return (STATUS_FAILED);
}

sockRaw = WSASocket (AF_INET,
SOCK_RAW,
IPPROTO_ICMP,
NULL, 0,0);

if (sockRaw == INVALID_SOCKET) {
CErrorMgt::RaiseError("WSASocket() failed: %d\n",WSAGetLastError());
return (STATUS_FAILED);
}
bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
CErrorMgt::RaiseError("failed to set recv timeout: %d\n",WSAGetLastError());
return (STATUS_FAILED);
}
timeout = 1000;
bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
CErrorMgt::RaiseError("failed to set send timeout: %d\n",WSAGetLastError());
return (STATUS_FAILED);
}
memset(&dest,0,sizeof(dest));

hp = gethostbyname(hostToPing);

if (!hp){
addr = inet_addr(hostToPing);
}
if ((!hp) && (addr == INADDR_NONE) ) {
CErrorMgt::RaiseError("Unable to resolve %s\n",hostToPing);
return (STATUS_FAILED);
}

if (hp != NULL)
memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
else
dest.sin_addr.s_addr = addr;

if (hp)
dest.sin_family = hp->h_addrtype;
else
dest.sin_family = AF_INET;

// NOTE:
//
// this is where you convert it from IN_ADDR
// to an ascii value e.g.: 255.255.255.255
//
dest_ip = inet_ntoa(dest.sin_addr);
&HostToPingIP(dest_ip);

//if (argc >2) {
// datasize = atoi(argv[2]);
//if (datasize == 0)
// datasize = DEF_PACKET_SIZE;
//}
if(dataSize!=NULL && *dataSize!=0)
datasize=*dataSize;


datasize += sizeof(IcmpHeader);

icmp_data = (char*)xmalloc(MAX_PACKET);
recvbuf = (char*)xmalloc(MAX_PACKET);

if (!icmp_data) {
CErrorMgt::RaiseError("HeapAlloc failed %d\n",GetLastError());
return (STATUS_FAILED);
}


memset(icmp_data,0,MAX_PACKET);
fill_icmp_data(icmp_data,datasize);

while(1) {
int bwrote;

((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);

bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,
sizeof(dest));
if (bwrote == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
CErrorMgt::RaiseError("timed out in sendding\n");
return (STATUS_FAILED);//continue;
}
CErrorMgt::RaiseError("sendto failed: %d\n",WSAGetLastError());
return (STATUS_FAILED);
}
if (bwrote < datasize ) {
//fprintf(stdout,"Wrote %d bytes\n",bwrote);
}else
break;
}
bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,
&fromlen);
if (bread == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
CErrorMgt::RaiseError("timed out in reception\n");
return (STATUS_FAILED);//continue;
}
CErrorMgt::RaiseError("recvfrom failed: %d\n",WSAGetLastError());
return (STATUS_FAILED);
}
decode_resp(recvbuf,bread,&from,elapsedTime, dataSize, icmp_seq);
Sleep(1000);

return 0;

} // Ping

//
// The response is an IP packet. We must decode the IP header to locate
// the ICMP data
//
//-----------------------------------------------------------------------------
void decode_resp(char *buf, int bytes,struct sockaddr_in *from,
int* elapsedTime, int* dataSize, int* icmp_seq)
//-----------------------------------------------------------------------------
{
IpHeader *iphdr;
IcmpHeader *icmphdr;
unsigned short iphdrlen;

iphdr = (IpHeader *)buf;

iphdrlen = iphdr->h_len * 4 ; // number of 32-bit words *4 = bytes

if (bytes < iphdrlen + ICMP_MIN) {
printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));
}

icmphdr = (IcmpHeader*)(buf + iphdrlen);

if (icmphdr->i_type != ICMP_ECHOREPLY) {
CErrorMgt::RaiseError("non-echo type %d recvd\n",icmphdr->i_type);
return;
}
if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) {
CErrorMgt::RaiseError("someone else's packet!\n");
return ;
}
//printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr));
//printf(" icmp_seq = %d. ",icmphdr->i_seq);
//printf(" time: %d ms ",GetTickCount()-icmphdr->timestamp);
//printf("\n");
if(elapsedTime!=NULL)
*elapsedTime = GetTickCount()-icmphdr->timestamp; // in msec
if(icmp_seq!=NULL)
*icmp_seq = icmphdr->i_seq;
if(dataSize!=NULL)
*dataSize = bytes;
}


//-----------------------------------------------------------------------------
USHORT 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);
}

//
// Helper function to fill in various stuff in our ICMP request.
//
//-----------------------------------------------------------------------------
void fill_icmp_data(char * icmp_data, int datasize)
//-----------------------------------------------------------------------------
{
IcmpHeader *icmp_hdr;
char *datapart;

icmp_hdr = (IcmpHeader*)icmp_data;

icmp_hdr->i_type = 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);
//
// Place some junk in the buffer.
//
memset(datapart,'E', datasize - sizeof(IcmpHeader));

}




/*

//-----------------------------------------------------------------------------
int Ping( const CString & NodeName,
CString & ElTime, CString & ErrorMessage )
//-----------------------------------------------------------------------------
{
ElTime = "0";

// Build the command line string
char CommandLine[256];
sprintf( CommandLine, "PING %s -n 1 -w 3000 > %s\\RASProbe.tmp", NodeName, Dir );

// Run the command
int Res = system( CommandLine );

// Open output file
FILE * stream = NULL;
stream = fopen( Dir+"\\RASProbe.tmp", "r" );
if ( stream == NULL )
return -1;

char s[100];
char * fRes = NULL;
CString Str;

// Seek to last line
while( (fRes = fgets(s, 100, stream)) != NULL )
Str = s;
fclose( stream );

if ( ! FileReportFlag ) printf( "%s\n", Str );

// According last line value set success or failure
int Index0 = Str.Find( "Reply" );
int Index = Str.Find( "time" );
if ( (Index0 != -1) && (Index != -1) ) {
Str = Str.Right( Str.GetLength() - Index );
Index = Str.Find( "ms" );
Str = Str.Left( Index );
// Get the time spent by ping
ElTime = Str.Right( Str.GetLength() - 5 ); // "time=%dms"
ErrorMessage = "";
return 0;
}
else {
ErrorMessage = Str;
return -1;
}

} // Ping
*/



THIS IS THE PING.H

//LIBS = kernel32.lib oldnames.lib libcmt.lib
// Don't forget to link with: ws2_32.lib


#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE 32
#define MAX_PACKET 1024

int Ping( const CString& hostToPing, int* elapsedTime = NULL, int* dataSize = NULL, int* icmp_seq = NULL);



Hope this helps!

Thanks in advance,

Dan