Click to See Complete Forum and Search --> : casting/converting a dotted ip address from IPAddr


jlewicki
July 6th, 2007, 04:18 PM
In order to use IcmpSendEcho, you need to take a dotted ip address "127.0.0.1" and run it through inet_addr() so it is of the IPAddr format. I want to convert this IPAddr format back to the dotted form.

I've searched the forums and googled multiple times but to no avail. These are some of the things that i have tried:

PRELIMINARY: I ping a machine with IcmpSendEcho. I then casted the ReplyBuffer:

PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;

When I call pEchoReply->Address, it displays an 8 digit u_long. Why is it doing this? You can't just call a struct and display a value. Address is of the type IPAddr. The structure for IPAddr is:

typedef struct {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
}S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} IPAddr;

I tried this:

char szIP[20];
sprintf ( szIP, "%d.%d.%d.%d", addr.S_un_b.s_b4, addr.S_un_b.s_b3, addr.S_un_b.s_b2, addr.S_un_b.s_b1);

and this:

sprintf ( szIP, "%d.%d.%d.%d", addr.S_un.S_un_b.s_b4, addr.S_un.S_un_b.s_b3, addr.S_un.S_un_b.s_b2, addr.S_un.S_un_b.s_b1);

and received this error:

error C2228: left of '.S_un' must have class/struct/union
type is 'IPAddr'
error C2228: left of '.S_addr' must have class/struct/union

I also tried casting:

in_addr addr = pEchoReply->Address;

but received another error:

error C2440: 'initializing' : cannot convert from 'IPAddr' to 'in_addr'



Full source:

//#include <winsock.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#include <iostream>
//#include <winsock.h>
//#include <Ipexport.h>
#include <Icmpapi.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")

void ErrorMessage(char *str) //display detailed error info
{
LPVOID msg;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &msg,
0,
NULL
);
printf("%s: %s\n",str,msg);
LocalFree(msg);
}

void main()
{

HANDLE hIcmpFile;
//PICMP_ECHO_REPLY *reply;
DWORD dwRetVal;

LPVOID ReplyBuffer;
char SendData[] = "12345678";

ReplyBuffer = (VOID*) malloc(sizeof(ICMP_ECHO_REPLY) + sizeof(SendData));


if ((hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
{
ErrorMessage("CreateFile");
printf("Unable to open file.\n");
}
else
{
printf("File created.\n");
}

char *IPtable[1];
unsigned long ip;

IPtable[0] = ("192.168.3.1");
//IPtable[0] = ("216.109.112.135");
//inet_addr("123.456.789.0"
if(!(ip = inet_addr(IPtable[0])))
printf("conversion failed\n");
std::cout<<"\n" << "ip: "<<ip<<std::endl;

//if((dwRetVal = IcmpSendEcho(hIcmpFile, ip, SendData, sizeof(SendData) + sizeof(ICMP_ECHO_REPLY), NULL, ReplyBuffer, 8*sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY), 1000)) != 0)
if((dwRetVal = IcmpSendEcho(hIcmpFile,
ip,
SendData,
sizeof(SendData),
NULL,
ReplyBuffer,
8*sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY),
1000)) != 0)
{
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
printf("\tReceived %ld messages.\n", dwRetVal);
printf("\tMessage: %s\n\n", pEchoReply->Data);

//char *data = (char*)pEchoReply->Data;
char* data = static_cast<char *> (pEchoReply->Data);

std::cout<<"IPaddress: "<<pEchoReply->Address<<std::endl;
std::cout<<"Status: "<<pEchoReply->Status<<std::endl;
std::cout<<"RoundTripTime: "<<pEchoReply->RoundTripTime<<std::endl;
std::cout<<"DataSize: "<<pEchoReply->DataSize<<std::endl;
std::cout<<"Data: "<<data<<std::endl;


//in_addr addr = pEchoReply->Address;
//addr.S_un.S_addr = pEchoReply->Address;

//char szIP[20] = pEchoReply->Address.S_un.S_addr;
//char *szIP = reinterpret_cast<char*>(addr.S_un.S_addr);
//printf("ip: %s\n\n", pEchoReply->Address);

//sprintf ( szIP, "%d.%d.%d.%d", addr.S_un_b.s_b4, addr.S_un_b.s_b3, addr.S_un_b.s_b2, addr.S_un_b.s_b1);
//std::cout<<"\nmaybe?: "<<szIP<<std::endl;
}
else
{
ErrorMessage("IcmpSendEcho\n\n");
printf("\tCall to IcmpSendEcho() failed.\n");
printf("\tError: %ld\n", GetLastError());
}

CloseHandle(hIcmpFile); //clean stuff up

return;
}

wildfrog
July 6th, 2007, 05:03 PM
No quite sure if this is what you're asking for, but have you seen the inet_ntoa (http://msdn2.microsoft.com/en-us/library/ms738564.aspx) function?

-petter

jlewicki
July 6th, 2007, 05:12 PM
Thanks a lot:


in_addr add;
add.S_un.S_addr = pEchoReply->Address;
char *addr = inet_ntoa(add);
std::cout<<"IPaddress: "<<addr<<std::endl;

wildfrog
July 6th, 2007, 05:19 PM
You're welcome. :wave:

Just a note from MSDN:

The data is guaranteed to be valid until the next Windows Sockets function call within the same thread—but no longer. Therefore, the data should be copied before another Windows Sockets call is made.

- petter