#include "stdafx.h" #include "windows.h" #include "Winsock2.h" #pragma comment(lib,"ws2_32.lib") #pragma pack(1) // // ICMP timestamp request and reply // 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 originate_timestamp; ULONG receive_timestamp; ULONG transmit_timestamp; }IcmpHeader; void printIcmpHeader(IcmpHeader& timestampreply) { printf("IcmpHeader type: %d i_code %d i_cksum %d i_id %d i_seq %d \n",timestampreply.i_type, timestampreply.i_code, timestampreply.i_cksum, timestampreply.i_id, timestampreply.i_seq); printf(" originate_timestamp :%d receive_timestamp %d transmit_timestamp %d \n", timestampreply.originate_timestamp, timestampreply.receive_timestamp, timestampreply.transmit_timestamp); printf(" pid: %d \n",GetCurrentProcessId());} USHORT g_Seq = 0; 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); } int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; if ( WSAStartup ( MAKEWORD ( 2 , 0 ) , &wsaData ) != 0 ) return FALSE; int iResult , iTimeOut; SOCKET m_socketPing = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0); if (m_socketPing == INVALID_SOCKET) return FALSE; iTimeOut = 10000; //Set timeout value for data receive iResult = setsockopt( m_socketPing, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut)); if( iResult == SOCKET_ERROR ) return FALSE; iTimeOut = 10000; //Set timeout value for data send iResult = setsockopt( m_socketPing, SOL_SOCKET, SO_SNDTIMEO, (char*)&iTimeOut, sizeof(iTimeOut)); if(iResult == SOCKET_ERROR) return FALSE; struct sockaddr_in m_adr_Dest,m_adr_From; m_adr_Dest.sin_family = AF_INET; m_adr_Dest.sin_addr.s_addr = inet_addr( LPCTSTR ( "127.0.0.3" ) );//216.239.33.99 IcmpHeader icmph; int try_count=0; while(try_count<10) { try_count++; int iDataSize = sizeof(IcmpHeader); IcmpHeader *icmp_hdr=&icmph; ZeroMemory(icmp_hdr,iDataSize); icmp_hdr->i_type = 13;//timestamp request icmp_hdr->i_code = 0; icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); icmp_hdr->i_cksum = 0; icmp_hdr->i_seq = g_Seq++; icmp_hdr->originate_timestamp = (GetTickCount()); icmp_hdr->i_cksum = checksum( ( USHORT* )icmp_hdr, iDataSize ); printf("sequence %d , originate time %d\n", icmp_hdr->i_seq, icmp_hdr->originate_timestamp); int iDataWrite = sendto( m_socketPing, (char*)icmp_hdr, iDataSize, 0, (struct sockaddr*)&m_adr_Dest, sizeof(struct sockaddr)); if (iDataWrite == SOCKET_ERROR) { if (WSAGetLastError() == WSAETIMEDOUT) { continue; } //terminate the ping if unable to send request. return 1; } //receive the reply //(note it.: we sent only the ICMP header and data buffer) //IP-Header will be added in before the ICMP header. //We could receive more bytes(sizeof IP-Header) than the bytes sent. IcmpHeader timestampreply; int iFromLen; iFromLen = sizeof ( struct sockaddr ); memset( &m_adr_From ,0 , sizeof( m_adr_From ) ); //IcmpHeader* pReceiveBuffer = ×tampreply; int nReceiveBufferSize = sizeof(IcmpHeader)+1576; char* pReceiveBuffer=new char[nReceiveBufferSize]; int iDataGet = recvfrom( m_socketPing, (char*)pReceiveBuffer, nReceiveBufferSize, 0, (struct sockaddr*)&m_adr_From, &iFromLen);
if (iDataGet == SOCKET_ERROR) { DWORD iError = WSAGetLastError(); //if timeout occured. if (iError == WSAETIMEDOUT) { continue; } //terminate the ping if unable to receive reply. return 1; } printf("\niDataGet = %d \n",iDataGet); memcpy(×tampreply,pReceiveBuffer+20,sizeof(IcmpHeader));//skip ip header(20 bytes) printIcmpHeader(timestampreply); int ts=GetTickCount()-timestampreply.originate_timestamp; printf(" sequence id %d use time %d\n", timestampreply.i_seq, ts); } return 0; }
////////////////////////////////////////////////////////////////////////// // // // SOCKET SUPPORT SECTION // // // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // Send a PING Message // // // // Sends a PING message to the currently // // selected host. // // // // If icmpTracing is TRUE, // // increment and set icmpPingTTL to // // reach the next node in the Internet // // tree. Note: must timeout for a small// // period of time to allow TTL to // // complete. // // // // Start the timer and issue the Icmp Ping // // // ////////////////////////////////////////////////////发送PING消息包到目的主机 void CEWDPingDlg::SendPing(void) { PingSent = TRUE; PingSocket.icmpCurSeq++; PingSocket.icmpCurId = (USHORT)GetCurrentProcessId(); PingSocket.icmpHostAddress = HostIPAddress();
//如果目标地址为空,则返回 if (PingSocket.icmpHostAddress == NULL) return; //如果icmpTracing为真,则必须将 if (icmpTracing) { icmpPingTTL++;
http://www.pconline.com.cn/pcedu/empolder/gj/vc/10207/78851.html
#include "windows.h"
#include "Winsock2.h"
#pragma comment(lib,"ws2_32.lib")
#pragma pack(1)
//
// ICMP timestamp request and reply
//
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 originate_timestamp;
ULONG receive_timestamp;
ULONG transmit_timestamp;
}IcmpHeader;
void printIcmpHeader(IcmpHeader& timestampreply)
{
printf("IcmpHeader type: %d i_code %d i_cksum %d i_id %d i_seq %d \n",timestampreply.i_type, timestampreply.i_code,
timestampreply.i_cksum, timestampreply.i_id, timestampreply.i_seq);
printf(" originate_timestamp :%d receive_timestamp %d transmit_timestamp %d \n", timestampreply.originate_timestamp,
timestampreply.receive_timestamp, timestampreply.transmit_timestamp);
printf(" pid: %d \n",GetCurrentProcessId());}
USHORT g_Seq = 0;
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);
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if ( WSAStartup ( MAKEWORD ( 2 , 0 ) , &wsaData ) != 0 )
return FALSE;
int iResult , iTimeOut;
SOCKET m_socketPing = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0);
if (m_socketPing == INVALID_SOCKET)
return FALSE;
iTimeOut = 10000;
//Set timeout value for data receive
iResult = setsockopt(
m_socketPing,
SOL_SOCKET,
SO_RCVTIMEO,
(char*)&iTimeOut,
sizeof(iTimeOut));
if( iResult == SOCKET_ERROR )
return FALSE;
iTimeOut = 10000;
//Set timeout value for data send
iResult = setsockopt(
m_socketPing,
SOL_SOCKET,
SO_SNDTIMEO,
(char*)&iTimeOut,
sizeof(iTimeOut));
if(iResult == SOCKET_ERROR)
return FALSE;
struct sockaddr_in m_adr_Dest,m_adr_From;
m_adr_Dest.sin_family = AF_INET;
m_adr_Dest.sin_addr.s_addr = inet_addr( LPCTSTR ( "127.0.0.3" ) );//216.239.33.99
IcmpHeader icmph;
int try_count=0;
while(try_count<10)
{
try_count++;
int iDataSize = sizeof(IcmpHeader);
IcmpHeader *icmp_hdr=&icmph;
ZeroMemory(icmp_hdr,iDataSize);
icmp_hdr->i_type = 13;//timestamp request
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
icmp_hdr->i_cksum = 0;
icmp_hdr->i_seq = g_Seq++;
icmp_hdr->originate_timestamp = (GetTickCount());
icmp_hdr->i_cksum = checksum( ( USHORT* )icmp_hdr, iDataSize );
printf("sequence %d , originate time %d\n", icmp_hdr->i_seq, icmp_hdr->originate_timestamp);
int iDataWrite = sendto(
m_socketPing,
(char*)icmp_hdr,
iDataSize,
0,
(struct sockaddr*)&m_adr_Dest,
sizeof(struct sockaddr));
if (iDataWrite == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
continue;
}
//terminate the ping if unable to send request.
return 1;
}
//receive the reply
//(note it.: we sent only the ICMP header and data buffer)
//IP-Header will be added in before the ICMP header.
//We could receive more bytes(sizeof IP-Header) than the bytes sent.
IcmpHeader timestampreply;
int iFromLen;
iFromLen = sizeof ( struct sockaddr );
memset( &m_adr_From ,0 , sizeof( m_adr_From ) );
//IcmpHeader* pReceiveBuffer = ×tampreply;
int nReceiveBufferSize = sizeof(IcmpHeader)+1576;
char* pReceiveBuffer=new char[nReceiveBufferSize];
int iDataGet = recvfrom(
m_socketPing,
(char*)pReceiveBuffer,
nReceiveBufferSize,
0,
(struct sockaddr*)&m_adr_From,
&iFromLen);
if (iDataGet == SOCKET_ERROR)
{
DWORD iError = WSAGetLastError();
//if timeout occured.
if (iError == WSAETIMEDOUT)
{
continue;
}
//terminate the ping if unable to receive reply.
return 1;
}
printf("\niDataGet = %d \n",iDataGet);
memcpy(×tampreply,pReceiveBuffer+20,sizeof(IcmpHeader));//skip ip header(20 bytes)
printIcmpHeader(timestampreply);
int ts=GetTickCount()-timestampreply.originate_timestamp;
printf(" sequence id %d use time %d\n", timestampreply.i_seq, ts);
}
return 0;
}
// //
// SOCKET SUPPORT SECTION //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Send a PING Message //
// //
// Sends a PING message to the currently //
// selected host. //
// //
// If icmpTracing is TRUE, //
// increment and set icmpPingTTL to //
// reach the next node in the Internet //
// tree. Note: must timeout for a small//
// period of time to allow TTL to //
// complete. //
// //
// Start the timer and issue the Icmp Ping //
// //
////////////////////////////////////////////////////发送PING消息包到目的主机
void CEWDPingDlg::SendPing(void)
{ PingSent = TRUE;
PingSocket.icmpCurSeq++;
PingSocket.icmpCurId = (USHORT)GetCurrentProcessId(); PingSocket.icmpHostAddress = HostIPAddress();
//如果目标地址为空,则返回
if (PingSocket.icmpHostAddress == NULL)
return;
//如果icmpTracing为真,则必须将
if (icmpTracing)
{
icmpPingTTL++;
}
//设定TTL
if (PingSocket.SetTTL (icmpPingTTL) == SOCKET_ERROR)
{
PingSocket.DisplayError ("setsocket(TTL)",
"CEWDPingDlg::SendPing");
return;
}
//要设定一定的时间让TTL设定完成
Sleep (100);
//显示序列号,同时用蓝色尖头表示出来
SetTraceSequence (PingSocket.icmpCurSeq,
m_TraceList.GetItemCount(),
Icon_BlueArrow); //设定地址
PingSocket.icmpSockAddr.sin_family = PF_INET;
PingSocket.icmpSockAddr.sin_addr.s_addr = PingSocket.icmpHostAddress;
PingSocket.icmpSockAddr.sin_port = 0;
//开始计时
StartTimer();
//调用PING函数发出PING命令
if (PingSocket.Ping (pIcmpBuffer, icmpDataLen) == SOCKET_ERROR)
PingSocket.DisplayError("Ping", "CEWDPingDlg::SendPing");}//////////////////////////////////////////////////////
// //
// HostIPAddress //
// //
// Return the IP Address for the curently //
// selected host in Internet byte order. //
// //
// GetIPAddress leaves a copy of the address //
// in icmpSockAddr and sets HostName to its //
// DNS official name. //
// //
//////////////////////////////////////////////////////
unsigned long CEWDPingDlg::HostIPAddress()
{ unsigned long iHostAddress; GetDlgItemText (IDC_DEST, HostName, MAXHOSTNAME); iHostAddress = PingSocket.GetIPAddress ((LPSTR)&HostName); if ((iHostAddress == INADDR_ANY) || (iHostAddress == NULL))
{
PingSocket.DisplayError ("gethostbyname",
"CEWDPingDlg::HostIPAddress");
iHostAddress = NULL;
}
else
SetDlgItemText (IDC_DEST, HostName); return iHostAddress;
}