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;
}
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;
}