🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.socket
Article #159

Re: How can I Trace the Route to an IP Addres from within my program

#159
From: Bob Gonder
Date: Fri, 27 Jun 2008 22:09
216 lines
6118 bytes
DreamChaser wrote:

>I went back and recopied/rewrote the pseudo-code and the replies below 
>are from the code provided at the end.

I'm not sure what I changed, but this C console version works.
I don't seem to have icmpapi.h, so I added my own...
One thing I noticed is you delay calling GetLastError,
perhaps until too late. (Results after the code)

#include <winsock2.h>
#include <iphlpapi.h>
//#include <icmpapi.h>
#include <stdio.h>

//----#include <icmpapi.h>----//
#define	__in
#define	__inout

HANDLE WINAPI IcmpCreateFile(void);

BOOL WINAPI IcmpCloseHandle(
  __in  HANDLE IcmpHandle
);

DWORD WINAPI IcmpSendEcho(
  __in     HANDLE IcmpHandle,
  __in     IPAddr DestinationAddress,
  __in     LPVOID RequestData,
  __in     WORD RequestSize,
  __in     PIP_OPTION_INFORMATION RequestOptions,
  __inout  LPVOID ReplyBuffer,
  __in     DWORD ReplySize,
  __in     DWORD Timeout
);
//---end #include <icmpapi.h>----//

//---------------------------------------------------------------------------
// An array of error message strings.
char* ErrorStrings[] = {
	"Error Base",
	"Buffer too small.",
	"Destination net unreachable.",
	"Destination host unreachable.",
	"Destination protocol unreachable.",
	"Destination port unreachable.",
	"Out of resources.",
	"Bad option.",
	"Hardware error.",
	"Packet too large.",
	"Request timed out.",
	"Bad request.",
	"Bad route.",
	"TTL expired in transit.",
	"TTL expired REASSEM.",
	"Param problem.",
	"Source quench.",
	"Option too large.",
	"Bad destination.",
	"Address deleted.",
	"Spec MNU change.",
	"MTU change.",
	"Unload"
};
#pragma pack(1)
typedef struct {
    BYTE   cbType;
    BYTE   cbSize;
    BYTE   pointer;
    struct in_addr addresses[62];
} RecordRouteOption, *PRecordRouteOption;
#pragma pack()
void OutputHex( PIP_OPTION_INFORMATION info)
{
	PRecordRouteOption op = info->OptionsData;

	printf(	"InfoAddress:%X\r\n\n", info );

	printf( "TimeToLive:%i\r\n"
		"TypeOfService:%i\r\n"
		"Flags:%X\r\n"
		"OptionsSize:%i\r\n"
		"OptionsData:%X\r\n",
		info->Ttl,info->Tos,info->Flags,info->OptionsSize,info->OptionsData);
	if( op )
	{
		printf(	"Type:%i\r\n"
			"Size:%i\r\n"
			"Pointer:%i\r\n",
			op->cbType,op->cbSize,op->pointer);
		do{
			printf( "IP%i=%X\r\n",op->pointer/4,
			 op->addresses[(op->pointer/4)-1] );
		}while( op->pointer -= 4 );
	};
}
//---------------------------------------------------------------------------
int main(void)
{
	int	iPingTimeout = 2000;   //ms
	char*	SendData = "Hello";
	WSADATA	wsaData;
	int	iResult;
	HANDLE	icmp;
	DWORD	dwRetVal;

	RecordRouteOption option[2] = {0};
	IP_OPTION_INFORMATION info = {0};

	DWORD	ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(option) +
			    sizeof(SendData) + 8;
	ICMP_ECHO_REPLY* reply = (PICMP_ECHO_REPLY) malloc(ReplySize);

	info.Ttl = 255;
	info.OptionsSize = (UCHAR)sizeof(RecordRouteOption)+1;
	info.OptionsData = (PUCHAR)&option[0];

	option[0].cbType = IP_OPT_RR;
	option[0].cbSize = sizeof(RecordRouteOption);
	option[0].pointer = 4;
	option[0].cbType = IP_OPT_EOL;

	printf("\r\n");

	icmp = IcmpCreateFile();
	if( !icmp )
	{	printf("IcmpCreateFile Failed.\r\n");
	};

	dwRetVal = IcmpSendEcho(icmp, inet_addr("74.125.47.147"),
		 	SendData, strlen(SendData),
			&info, reply, ReplySize, iPingTimeout);

    if (dwRetVal > 0){
       struct in_addr ReplyAddr;
       ReplyAddr.S_un.S_addr = reply->Address;
	printf("Reply from %s: bytes=%d, time=%3dms TTL=%3d\r\n",
                   inet_ntoa(ReplyAddr),
                   reply->DataSize,
                   reply->RoundTripTime,
                   reply->Options.Ttl
		);
	if( reply->DataSize && reply->Data )
	{	printf("Data: %s\r\n", reply->Data );
	};
	OutputHex( &reply->Options);

    } else {
	DWORD	error = GetLastError();
	LPVOID	lpMsgBuf;
	printf(ErrorStrings[reply->Status - IP_STATUS_BASE]);
	printf("\r\n");
	FormatMessage(
	     FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
             NULL, error,
             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf, 0, NULL );
	printf(lpMsgBuf);
	printf("\r\n");
       // Free the buffer.
       LocalFree( lpMsgBuf );
     }
	printf("\r\n");

	IcmpCloseHandle(icmp);
	free(reply);

	return 0;
}

 - - - - - -

C:\RA7\RA7\EXE\TcpTest>icmp_rr
Reply from 74.125.47.147: bytes=5, time= 62ms TTL=242
Data: Hello
InfoAddress:902BB8

TimeToLive:242
TypeOfService:0
Flags:0
OptionsSize:0
OptionsData:902BC0
Type:72
Size:101
Pointer:108
IP27=0
IP26=0
IP25=0
IP24=0
IP23=0
IP22=0
IP21=0
IP20=0
IP19=0
IP18=0
IP17=0
IP16=0
IP15=0
IP14=0
IP13=0
IP12=0
IP11=0
IP10=0
IP9=0
IP8=0
IP7=0
IP6=0
IP5=0
IP4=0
IP3=0
IP2=0
IP1=6F6C
C:\RA7\RA7\EXE\TcpTest>

Since this is further than you've gotten,
I didn't try too hard to understand the returned OptionsData.
Technical Details
Message-ID: <reoa64t03o0hdpjmju08fv7iusknnru0jo@4ax.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!proxad.net!feeder1-2.proxad.net!feeder.erje.net!news.isoc.lu!newsgroups.borland.com!not-for-mail
References: <MPG.22c8301ab312798c989a97@newsgroups.borland.com> <485faf40$1@newsgroups.borland.com> <MPG.22cb3a3e698457ac989a9a@newsgroups.borland.com> <rrj264107nnff1gqarmhq4p0v1c23k6801@4ax.com> <4861dce2$1@newsgroups.borland.com> <4862a806$1@newsgroups.borland.com> <486484c8$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,7aa64e4617379849
X-Google-Attributes: gid11508e,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: Bob Gonder <none@nowhere.invalid>
Newsgroups: borland.public.cppbuilder.internet.socket
Subject: Re: How can I Trace the Route to an IP Addres from within my program
Date: Fri, 27 Jun 2008 15:09:20 -0700
Message-ID: <reoa64t03o0hdpjmju08fv7iusknnru0jo@4ax.com>
References: <MPG.22c8301ab312798c989a97@newsgroups.borland.com> <485faf40$1@newsgroups.borland.com> <MPG.22cb3a3e698457ac989a9a@newsgroups.borland.com> <rrj264107nnff1gqarmhq4p0v1c23k6801@4ax.com> <4861dce2$1@newsgroups.borland.com> <4862a806$1@newsgroups.borland.com> <486484c8$1@newsgroups.borland.com>
X-Newsreader: Forte Agent 1.93/32.576 English (American)
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 67.77.147.203
X-Trace: newsgroups.borland.com 1214604557 67.77.147.203 (27 Jun 2008 15:09:17 -0700)
Lines: 218
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!proxad.net!feeder1-2.proxad.net!feeder.erje.net!news.isoc.lu!newsgroups.borland.com!not-for-mail