实验手册 联系客服

发布时间 : 星期五 文章实验手册更新完毕开始阅读57d565dc6d175f0e7cd184254b35eefdc9d31577

sockaddr_in sockSend; int uAddr = 0; CICMP MyIcmp; //初始化Winsock MyIcmp.Initialize( ); //解析主机 hp = gethostbyname( argv[ 1 ] ); //是否输入主机名 if ( hp == NULL ) { uAddr = inet_addr( argv[ 1 ] ); //输入IP地址 sockSend.sin_addr.S_un.S_addr = uAddr; } if (( hp == NULL ) && ( uAddr == INADDR_NONE )) { cout << \ return 2; } if ( hp != NULL ) { memcpy( &( sockSend.sin_addr ), hp->h_addr, hp->h_length ); uAddr = sockSend.sin_addr.S_un.S_addr; } for ( int i = 0; i < nNumber; i++ ) { MyIcmp.SendICMP( ICMP_ECHO, uAddr ); MyIcmp.RecvICMP( ) ; cout<

文件: icmp.h

描述: CICMP class

struct IP_Header { unsigned int HeaderLength:4; //IP首部长度 unsigned int Version:4; //协议版本 unsigned char TOS; //服务类型 unsigned short TotalLength; //数据长度 unsigned short ID; //标识 unsigned short mflag; //其它标记 unsigned char TTL; //生命期 unsigned char Protocal; //协议 unsigned short CheckSum; //检验和 unsigned int SourceIPAddress; //源IP地址 unsigned int DestIPAddress; //目的IP地址 };

//ICMP数据结构

struct ICMP_Header { unsigned char type; //类型 unsigned char code; //编码 unsigned short cksum; //检查和 unsigned short ID; //标识 unsigned short number; //计数值 unsigned int time; //时间 };

//ICMP类 class CICMP {

public: CICMP( UINT uPacSize = DEF_PACKET_SIZE, int nTTL = DEF_TTL ); BOOL Initialize( void ); //初始化 USHORT CheckSum( USHORT *pBuffer, int nSize ); //检查和 BOOL SendICMP( int nMsg, char * pAddr) ; //发送报文 BOOL SendICMP( int nMsg, SOCKADDR_IN *pAddr ); //发送报文 BOOL RecvICMP( void ); //接收报文 //设置包大小和生存期 private: char *m_pSendBuffer; //发送内存数据区 char *m_pRecvBuffer; IP_Header *m_pIPHeader; //IP数据头(接收)

ICMP_Header *m_pIcmp; //ICMP数据头(发送或接收) SOCKET m_Sock; //套接字标识 SOCKADDR_IN m_SockAddr; UINT m_uPacketSize; //指定发送报文长度 };

//***************************************************************** //Icmp.cpp

//ping类的实现文件 //Winsock初始化

BOOL CICMP::Initialize( void ) { int nLen = m_uPacketSize + sizeof( ICMP_Header ); m_pSendBuffer = ( char* )xmalloc( nLen ); //申请发送内存空间 m_pRecvBuffer = ( char* )xmalloc( MAX_PACKET_SIZE ); //申请接收内存空间 //初始化Socket2.1 WORD wVersionRequested; WSADATA wsaData; int err; int nTimeOut = TIMEOUT; //设置超时时间 wVersionRequested = MAKEWORD( 2, 1 ); //初始化Winsock err = WSAStartup( wVersionRequested, &wsaData ); //建立原始套接字 m_Sock = WSASocket( AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0 ); //设置超时时间 setsockopt( m_Sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&nTimeOut, sizeof( nTimeOut )); setsockopt( m_Sock, SOL_SOCKET, SO_SNDTIMEO, ( char* )&nTimeOut, sizeof( nTimeOut )); }

//*********************************** //计算校验和

USHORT CICMP::CheckSum( USHORT *pBuffer, int nSize ) {

unsigned long cksum = 0; while ( nSize > 1) { cksum += *(pBuffer++); nSize -= sizeof( USHORT ); } if ( nSize >0 ) { cksum += *( UCHAR* )pBuffer; } cksum = ( cksum >> 16) + ( cksum & 0xffff ); cksum += ( cksum >> 16 ); return ( USHORT )( ~cksum ); }

//发送ICMP数据包

BOOL CICMP::SendICMP( int nMsg, sockaddr_in *pAddr ) { char *p_data; int state; //发送数据状态 pAddr->sin_family = AF_INET; pAddr->sin_port = 0; int nICMPLen = sizeof( ICMP_Header ); //ICMP头长度 memset( m_pSendBuffer, 0, m_uPacketSize + nICMPLen ); //用0填充 内存区 //填充ICMP数据各项 m_pIcmp = ( ICMP_Header* )m_pSendBuffer; m_pIcmp->type = nMsg; m_pIcmp->code = 0; m_pIcmp->ID = ( USHORT )GetCurrentProcessId( ); //获取进程ID m_pIcmp->number = AddNum( ); m_pIcmp->time = GetTickCount( ); m_pIcmp->cksum = 0; //填充数据区 p_data = (( char*)m_pIcmp + nICMPLen ); memset(( char* )p_data,'E',m_uPacketSize ); //可以添任意字符 //填充检查和项 m_pIcmp->cksum = CheckSum(( USHORT* )m_pIcmp, m_uPacketSize + nICMPLen );