Exemplo n.º 1
0
// add by zhangyan 2008-08-25
//发送ICMP包进行路由跟踪
int TraceReader::TraceRouteICMP(const char * cHost, int ttl)
{
	//用在发送和接受的ICMP包头中
    int seq_no = 0;
    ICMPHeader* send_buf = 0;
    IPHeader* recv_buf = 0;
    int rtn;
    int iCount = 0;
    int packet_size = DEFAULT_PACKET_SIZE;
    
    //packet_size = max(sizeof(ICMPHeader), min(MAX_PING_DATA_SIZE, (unsigned int)packet_size));

    // 启动 Winsocket
    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        //winsocket版本错误
		//cout<<"winsocket版本错误\n");
        return SYSERROR;
    }

    SOCKET sd; // RAW Socket句柄
    sockaddr_in dest, source;

    // 三个任务(创建sd, 设置ttl, 初试dest的值)
    rtn = setup_for_ping( cHost, ttl, sd, dest, timeout);
    if ( rtn < 0)
    {
		//cout<<"创建 ping 错误\n");
        goto cleanup; //释放资源并退出
    }

	destMachine = dest;
	
    // 为send_buf和recv_buf分配内存
    rtn = allocate_buffers(send_buf, recv_buf, packet_size);
    if ( rtn < 0)
    {
		//cout<<"分配发送和接收缓冲错误\n");
        goto cleanup;
    }

    // 初始化IMCP数据包(type=8,code=0)
    init_ping_packet(send_buf, packet_size, seq_no);

    // 发送ICMP数据包
    rtn = send_ping(sd, dest, send_buf, packet_size);

	//cout<<"rtn: "<<rtn<<endl;	
    if ( rtn >= 0)
    {        		
        while(1)
        {
            // 接受回应包
            rtn = recv_ping(sd, source, recv_buf, MAX_PING_PACKET_SIZE);
            if ( rtn <= 0)
            {				
                if( ++iCount < retrys)
				{
					// (在重试次数内)发送ICMP数据包
					send_ping(sd, dest, send_buf, packet_size);					
					continue;
				}
				else
				{			
					//cout<<"超过重试次数\n");
					oneRoutePath.push_back("*");
					goto cleanup;
				}
                
            }
					
			char szSourceIP[16];				
                        strncpy(szSourceIP, inet_ntoa(source.sin_addr), 16);
			//cout<<szSourceIP<<endl;
			//{
			//	mutex::scoped_lock lock(m_tracert_mutex);
			//	oneRoutePath.push_back(szSourceIP);
			//}	
			oneRoutePath.push_back(szSourceIP);
			if (strcmp(szSourceIP, cHost) == 0)
			{
				//路由跟踪完成
				rtn = 11;
			}
		
            //if( GetTickCount() - send_buf->timestamp >= iTimeOut )
			//	rtn = OVERTIME;

			goto cleanup;
        }
   }

cleanup:
    delete[]send_buf;	//释放分配的内存
    delete[]recv_buf;
    WSACleanup();		// 清理winsock

    return rtn;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	SOCKET PingSocket;
	ICMP_HDR *SendBuf = NULL;
	IPV4_HDR *RecvBuf = NULL;		// ICMP + IP buffer

	// 입력 값 확인
	if (argc < 2)
	{
		printf("usage:\n");
		printf("%s <host> [data_size]", argv[0]);
		printf("\tdata_size can be up to %d bytes. Default is %d\n", 
			MAX_PING_DATA_SIZE, DEFAULT_PACKET_SIZE);

		return 1;
	}

	// Initialize Winsock 
	WSADATA wsaData;
	int result;

	result = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (result != 0)
	{
		printf("WSAStartup failed with error: %d\n", WSAGetLastError());
		return -1;
	}

	//
	SOCKADDR_IN srcAddr, destAddr;
	int packet_size = DEFAULT_PACKET_SIZE;
	setup_for_ping(argv[1], PingSocket, destAddr);

	packet_size = max(sizeof(ICMP_HDR), 
						min(MAX_PING_DATA_SIZE, (unsigned int)packet_size));
	// SendBuf / RecvBuf Memory allocation
 	allocate_buffers(SendBuf, RecvBuf, packet_size);

	// set up ping packet
	init_ping_packet(SendBuf, packet_size);

	// Send the ping request and Receive the reply
	send_ping(PingSocket, destAddr, SendBuf, packet_size);
	while (1)
	{
		if (recv_ping(PingSocket, srcAddr, RecvBuf, MAX_PING_PACKET_SIZE) < 0)
		{
			unsigned short header_len = RecvBuf->ip_header_length * 4;
			ICMP_HDR* icmphdr = (ICMP_HDR *)((char *)RecvBuf + header_len);

		}
		else
		{
			break;
		}
	}

	// Cleanup
	WSACleanup();
	free(SendBuf);
	free(RecvBuf);

	return 0;
}