// TestRouteInstance. cpp: defines the entry point of the console application. <Br/> // </p> <p> # include "stdafx. h "<br/> # include <WinSock2.h> <br/> # include <assert. h> <br/> # include <ws2ipdef. h> <br/> # include <AtlConv. h> </p> <p> # pragma comment (lib, "Ws2_32.lib ") <br/> # define LOCAL_IP "192.168.100.94" <br/> # define ICMP_PORT 0 <br/> # define DEST_HOST_IP "119.75.213.61" <br/> # define DEST_HOST_PORT 22 <br/> # define RECV_BUF 1024 <br/> # define MAX_HOPS 30 <br/> # define MAX_RECVTIMEOUT 50 0 </p> <p> BOOL InitWinSock () // initialize the WinSock database <br/> {<br/> WSADATA wsaData = {0 }; <br/> int iRet (0); <br/> iRet = WSAStartup (MAKEWORD (2, 2), & wsaData); <br/> if (iRet! = 0) <br/>{< br/> return FALSE; <br/>}< br/> if (LOBYTE (wsaData. wVersion )! = 2 | LOBYTE (wsaData. wVersion )! = 2) <br/>{< br/> return FALSE; <br/>}< br/> return TRUE; <br/>}</p> <p> // uninstall the socket library <br/> void CleanWinSock () <br/>{< br/> WSACleanup (); <br/>}< br/> # pragma pack (1) <br/> typedef struct icmp_hdr <br/>{< br/> UCHAR icmp_type; // Message Type <br/> UCHAR icmp_code; // message code <br/> USHORT icmp_checksum; // check and </p> <p> // echo header <br/> USHORT icmp_id; // Request ID <br/> USHORT icmp_sequence; // serial number <br/> // send each time to this // 8 byte </p> <p> // custom data part <br/> UL ONG icmp_timestamp; // timestamp <br/>} ICMP_HDR; <br/> # pragma pack () </p> <p> // test and <br/> USHORT CheckSum (USHORT * uBuffer, int iSize) <br/>{< br/> ULONG uCheckSum (0 ); <br/> // accumulate data into uCheckSum with words <br/> while (iSize> 1) <br/> {<br/> // uCheckSum = uCheckSum + * uBuffer; <br/> // uBuffer ++; <br/> uCheckSum + = * uBuffer ++; <br/> iSize-= sizeof (iSize ); <br/>}< br/> // if it is an odd number, the last byte is extended to the double word in the uCheckSum. <br/> if (iSize) <br/> {<br /> UCheckSum + = * (UCHAR *) uBuffer; <br/>}< br/> uCheckSum = (uCheckSum> 16) + (uCheckSum & 0 xffff ); <br/> uCheckSum + = (uCheckSum> 16); <br/> return (USHORT )(~ UCheckSum); <br/>}</p> <p> BOOL DecodeICMPPacket (char * szBuffer, int iSize, SOCKADDR_IN * pRecvAddr, int iTTL) <br/> {<br/> ICMP_HDR * pICMPHdr = NULL, * pICMPOther = NULL; <br/> assert (szBuffer! = NULL); <br/> assert (iSize> 0); <br/> pICMPHdr = (ICMP_HDR *) & (szBuffer [20]); </p> <p> pICMPOther = (ICMP_HDR *) & (szBuffer [48]); <br/> // static int iFirstRouter = iTTL; <br/> static int iFirst = 1; </p> <p> if (pICMPHdr-> icmp_type! = 11 & pICMPHdr-> icmp_code! = 0 & pICMPHdr-> icmp_type! = 0) <br/>{< br/> printf_s ("unknown ICMP packet: type: % d, code: % d! /R/n ", pICMPHdr-> icmp_type, pICMPHdr-> icmp_code); <br/> return FALSE; <br/>}</p> <p> if (pICMPOther-> icmp_id = GetCurrentThreadId () <br/>{< br/> printf_s ("No: % d Routers: % s/r/n ", iFirst, inet_ntoa (pRecvAddr-> sin_addr )); <br/>}</p> <p> if (pICMPHdr-> icmp_code = 0 & pICMPHdr-> icmp_type = 0) <br/>{< br/> printf_s ("Destination: % s", inet_ntoa (pRecvAddr-> sin_addr )); <br/> printf_s ("% d routers in total", iFirst-1); <br/> Printf_s ("Timeout: % d MS/r/n", (GetTickCount ()-pICMPHdr-> icmp_timestamp); <br/> return TRUE; <br/>}< br/> iFirst ++; <br/> return FALSE; <br/>}</p> <p> TCHAR * ParseDestIp (TCHAR ** szString) <br/>{< br/> if (_ tcscmp (szString [1], _ T ("-ip") = 0) <br/>{< br/> return szString [2]; <br/>}< br/> return NULL; <br/>}</p> <p> int _ tmain (int argc, _ TCHAR * argv []) <br/>{< br/> char * pszDestIp; <br/> USES_CONVERSION; </p> <p> I F (argc> 1) <br/>{< br/> pszDestIp = W2A (ParseDestIp (argv); <br/>}< br/> InitWinSock (); <br/> // create an icmp socket <br/> socket RawICMPSock (INVALID_SOCKET); <br/> int iRet (0); <br/> RawICMPSock = SOCKET (AF_INET, SOCK_RAW, IPPROTO_ICMP); <br/> if (RawICMPSock = INVALID_SOCKET) <br/>{< br/> printf_s ("create icmp socket failed! "); <Br/> return 1; <br/>}< br/> SOCKADDR_IN addrIn; <br/> addrIn. sin_family = AF_INET; <br/> addrIn. sin_addr.S_un.S_addr = INADDR_ANY; // inet_addr (LOCAL_IP); <br/> addrIn. sin_port = htons (ICMP_PORT); <br/> iRet = bind (RawICMPSock, (SOCKADDR *) & addrIn, sizeof (SOCKADDR )); <br/> if (iRet = SOCKET_ERROR) <br/> {<br/> printf_s ("bind ICMP socket failed! "); <Br/> return 1; <br/>}< br/> // set the timeout value <br/> int iTimeOut = MAX_RECVTIMEOUT; </p> <p> // set TTL <br/> int iTTL = 1; <br/> iRet = setsockopt (RawICMPSock, IPPROTO_IP, IP_TTL, (char *) & iTTL, sizeof (int); <br/> if (iRet = SOCKET_ERROR) <br/>{< br/> printf_s ("set TTL failed! /R/n "); <br/> return 1; <br/>}< br/> // set timeout <br/> iRet = setsockopt (RawICMPSock, SOL_SOCKET, SO_RCVTIMEO, (char *) & iTimeOut, sizeof (int); <br/> if (iRet = SOCKET_ERROR) <br/>{< br/> printf_s ("setsockopt failed! "); <Br/> return 1; <br/>}< br/> iRet = setsockopt (RawICMPSock, SOL_SOCKET, SO_SNDTIMEO, (char *) & iTimeOut, sizeof (int); <br/> if (iRet = SOCKET_ERROR) <br/> {<br/> printf_s ("setsockopt failed! "); <Br/> return 1; <br/>}</p> <p> SOCKADDR_IN DestAddr; <br/> SOCKADDR_IN addrFrom = {0 }; <br/> DestAddr. sin_family = AF_INET; <br/> if (pszDestIp! = NULL) <br/>{< br/> # define DEST_HOST_IP pszDestIp <br/>}< br/> DestAddr. sin_addr.S_un.S_addr = inet_addr (DEST_HOST_IP); <br/> DestAddr. sin_port = htons (DEST_HOST_PORT); <br/> int iAddrFromLen = sizeof (addrFrom); <br/> BOOL bRet (FALSE ); <br/> char szRecvBuffer [RECV_BUF] = {0}; <br/> char szSendBuffer [sizeof (ICMP_HDR) + 32] = {0 }; <br/> ICMP_HDR * pIcmpHdr = NULL; <br/> // int iBeforeSendTime (0), iRecvTime (0); <Br/> while (iTTL <= MAX_HOPS) <br/> {</p> <p> ZeroMemory (& szSendBuffer, sizeof (szSendBuffer )); <br/> pIcmpHdr = (ICMP_HDR *) szSendBuffer; <br/> pIcmpHdr-> icmp_code = 0; <br/> pIcmpHdr-> icmp_type = 8; <br/> pIcmpHdr-> icmp_sequence = iTTL; <br/> pIcmpHdr-> icmp_id = GetCurrentThreadId (); <br/> pIcmpHdr-> icmp_timestamp = GetTickCount (); // custom data </p> <p> pIcmpHdr-> icmp_checksum = CheckSum (USHORT *) szSendBuffer, si Zeof (szSendBuffer); <br/> // memset (& szSendBuffer [sizeof (ICMP_HDR)], 'E', 32 ); </p> <p> iRet = sendto (RawICMPSock, szSendBuffer, sizeof (szSendBuffer), 0, (SOCKADDR *) & DestAddr, sizeof (SOCKADDR )); <br/> // iBeforeSendTime = GetTickCount (); <br/> if (iRet = SOCKET_ERROR) <br/>{< br/> printf_s ("sendto failed! "); <Br/> break; <br/>}< br/> // receives ICMP packets <br/> iRet = recvfrom (RawICMPSock, szRecvBuffer, RECV_BUF, 0, (SOCKADDR *) & addrFrom, & iAddrFromLen); <br/> // iRecvTime = GetTickCount (); </p> <p> if (iRet = SOCKET_ERROR) <br/>{< br/> if (WSAGetLastError () = WSAETIMEDOUT) <br/>{< br/> printf_s ("time out! /R/n "); <br/> // continue; <br/>}< br/> else <br/>{< br/> printf_s (" recvfrom failed! "); <Br/> break; <br/>}< br/> if (iRet> 0) <br/>{< br/> // printf_s ("Timeout: % d MS/r/n", iRecvTime-iBeforeSendTime); <br/> bRet = DecodeICMPPacket (szRecvBuffer, iRet, & addrFrom, iTTL); <br/>}< br/> if (bRet) <br/>{< br/> break; <br/>}</p> <p> // Add TTL <br/> iTTL ++; <br/> iRet = setsockopt (RawICMPSock, IPPROTO_IP, IP_TTL, (char *) & iTTL, sizeof (int); <br/> if (iRet = SOCKET_ERROR) <br/>{< br/> printf_s ("sets Ockopt failed! "); <Br/> return 1; <br/>}< br/> if (iTTL> 30) <br/> {<br/> printf_s ("Maximum hop! % D/r/n ", iTTL-1); <br/>}< br/> closesocket (RawICMPSock); <br/> CleanWinSock (); <br/> return 0; <br/>}</p> <p>