Hi,
我们知道,发送个ICMP Echo Request报文,如果得到Destination Unreachable回复ICMP报文, 这个报文会包含IP报文头的前8个字节,以便我们APP识别。
我现在用
winSock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
建立发送ICMP Echo Request报文。
问题是,我如何能取得保留此IP报文的前8个字节,以备得到类似Destination Unreachable ICMP响应报文时比对识别?
谢谢指点!
我们知道,发送个ICMP Echo Request报文,如果得到Destination Unreachable回复ICMP报文, 这个报文会包含IP报文头的前8个字节,以便我们APP识别。
我现在用
winSock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
建立发送ICMP Echo Request报文。
问题是,我如何能取得保留此IP报文的前8个字节,以备得到类似Destination Unreachable ICMP响应报文时比对识别?
谢谢指点!
解决方案 »
- GdiplusStartup未定义的标示符
- 有没有人有GDI+的MSDN?谢谢!
- 急: 如何调用已知 函数名 的函数??
- vc非托管能调用webserverice吗
- 我是新手,请教老鸟如何学习VC++6.0!(新手们来讨论一下啦!)
- 不压缩的24位位图如何进行反操作色
- 为什么会服务器会内部错误???
- 如何在一个应用程序(A.exe)中运行另一个应用程序(b.exe)在98 nt 2000下
- 为什么我的Access数据库只能查询一行?
- 急急急!!滚动条滚动之后出现白条问题-绘图软件(CSrollView)在线等!!
- 在Tree Control控件中如何人为改变选中状态?
- 使用Winsock2.0编程是不是需要安装SDK啊?
#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;
}
你的Ping程式很精炼;但是你的程式中并没有判断返回的ICMP报文是否是你的程式的响应报文,也没有判断返回ICMP报文是Echo Reply, 还是Destination Unreachable.
所以,你没有回答我的问题呵!