Tracert 代码

以前写的Tracert源代码,
相关参考 : http://baike.baidu.com/view/493712.htm
--------------------------------------------------------------------------------------------------
General.h
#include <windows.h>
#ifdef __GENERAL_H__
#define __GENERAL_H__
// CRC Check Sum
extern USHORT ip_checksum(USHORT* buffer, int size);
// Read IP Address from Integer to String
void ReadIPAddress(unsigned long IPAddress);
#endif  // GENERAL_H
 
----------------------------------------------------------------------------------------------------
General.cpp

#include "General.h"
#include <stdio.h>

USHORT ip_checksum(USHORT* buffer, int size)
{
    unsigned long cksum = 0;
   
    // Sum all the words together, adding the final byte if size is odd
    while (size > 1) {
        cksum += *buffer++;
        size -= sizeof(USHORT);
    }
    if (size) {
        cksum += *(UCHAR*)buffer;
    }

    // Do a little shuffling
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >> 16);
   
    // Return the bitwise complement of the resulting mishmash
    return (USHORT)(~cksum);
}

void ReadIPAddress(unsigned long IPAddress)
{
    printf("%d.%d.%d.%d/n", UCHAR(IPAddress),
                                       UCHAR(IPAddress >> 8),
                                       UCHAR(IPAddress >> 16),
                                       UCHAR(IPAddress >> 24));
}

----------------------------------------------------------------------------------------------------------

ICMP.h

#include <windows.h>
#ifndef __ICMP_H__
#define __ICMP_H__

#define ICMP_ECHO 8               // Echo ICMP Packet
#define ICMP_REPLAY 0             // Replay ICMP Packet
#define MAX_DATA_SIZE 1024         
#define ICMP_MIN 8                
#define ICMP_TIMEOUT 11           // Time out ICMP Packet
#define DEFAULT_ICMP_SIZE 44      // The Default ICMP Packet Size

#pragma pack(1)
typedef struct tagICMPHeader
{
    UCHAR type;
    UCHAR code;
    USHORT checkSum;
    USHORT ID;
    USHORT SeqNumber;
}ICMPHeader, *PICMPHeader;
#pragma pack()

#pragma pack(1)
typedef struct tagIPHeader
{
    BYTE h_len:4;
    BYTE version:4;
    BYTE tos;
    USHORT total_len;
    USHORT ID;
    USHORT flags;
    BYTE ttl;
    BYTE proto;
    USHORT checksum;
    ULONG source_ip;
    ULONG dest_ip;
}IPHeader, *PIPHeader;
#pragma pack()

#endif  // ICMP_H

-------------------------------------------------------------------------------------------------------

Tracert.h

#include "ICMP.H"
#include "General.h"
#include <iostream>
using namespace std;

#ifndef __TRACERT_H__
#define __TRACERT_H__

#define TRACERT_DATA_PART_SIZE (DEFAULT_ICMP_SIZE - sizeof(ICMPHeader))
#pragma pack(1)
typedef struct tagTracertPacket
{
    ICMPHeader icmp_header;
    BYTE data_part[TRACERT_DATA_PART_SIZE];
}TracertPacket, *PTracertPacket;
#pragma pack()

class Tracert
{
public:
    Tracert();
    ~Tracert();
    BOOL StartClient();

private:
    void PackTracertPacket(TracertPacket& tracert_packet);
    int UnPackTracertPacketPacket();
    int Configuration();
    int ReceivePacket();
    int SendPacket();
    DWORD InitializeConnection();
    int UnitializeConnection();
    int DecodeTracertPacket(const IPHeader& ip_header, const int recvPacketLen);
    friend USHORT ip_checksum(USHORT* buffer, int size);
    friend void ReadIPAddress(unsigned long IPAddress);

private:
    SOCKET sock;
    sockaddr_in dest;
    sockaddr_in source;
};

#endif  // TRACERT_H

 
-------------------------------------------------------------------------------------------------------
Tracert.cpp

#define  WIN32_LEAN_AND_MEAN
#include <winsock2.h>                     //Need the support of WinSock2
#include <ws2tcpip.h>                     //When setting the level of IPPROTO_IP                                        
#include "Tracert.h"           
#define TRANSFER_OVER 0x05      
static const TCHAR* DEFAULT_ADDRESS = TEXT("220.181.18.155");   // BaiDu Address
static const int TIMEOUT = 1000;                               // 1 second
Tracert::Tracert()
{
    InitializeConnection();
}
 
Tracert::~Tracert()
{
    UnitializeConnection();
}
 
int Tracert::Configuration()
{
    int ttl = TIMEOUT;
 
    if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&ttl,
            sizeof(ttl)) == SOCKET_ERROR)
    {
        cout << "Error in Configuration, error code:" <<  GetLastError() << endl;
        return GetLastError();
    }
    memset(&dest, 0, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_addr.s_addr = inet_addr(DEFAULT_ADDRESS);
    return 0;
}
 
int Tracert::SendPacket()
{
    static int livetime = 1;
    int retValue=setsockopt(sock,IPPROTO_IP,IP_TTL,(char *)&livetime,sizeof(int));
    if (retValue < 0)
    {
        cout << "Error in Set Tracert Packet Time, error code" << GetLastError() << endl;
        return GetLastError();
    }
    else
    {
        livetime++;
    }
    TracertPacket tracert_packet;
    PackTracertPacket(tracert_packet);
    retValue = sendto(sock,                          // Socket
                      (const char*)&tracert_packet,  // Buffer
                      sizeof(tracert_packet)
                      0,                             // Flag
                      (const sockaddr*)&dest,        // The Pointer to Socket Address
                      sizeof(dest));                 // Size of Socket Address
    if (retValue < 0)
    {
        cout << "Error in send Packet, error code" << GetLastError() << endl;
        return GetLastError();
    }
    return 0;
}
 
int Tracert::ReceivePacket()
{
    // effetive will be worse?
    IPHeader* recv_buf = (IPHeader*)new TCHAR[MAX_DATA_SIZE];
    if (recv_buf == NULL)
    {
        return GetLastError();
    }
    int fromlen = sizeof(source);
    int retValue = recvfrom(sock,
                            (char*)recv_buf,
                            MAX_DATA_SIZE,
                            0,
                            (sockaddr*)&source,
                            &fromlen);
    if (retValue < 0)
    {
        cout << "Error in receive packet, error code" << GetLastError() << endl;
        return GetLastError();
    }
    else
    {
        // Decode ping packet
        retValue = DecodeTracertPacket(*recv_buf, retValue);
    }
    delete []recv_buf;
    recv_buf = NULL;
    return retValue;
}
 
void Tracert::PackTracertPacket(TracertPacket &tracert_packet)
{
    //static USHORT ID = 1;
    static USHORT SeqNumber = 1;
    tracert_packet.icmp_header.type = ICMP_ECHO;
    tracert_packet.icmp_header.code = 0;
    tracert_packet.icmp_header.checkSum = 0;
    tracert_packet.icmp_header.ID = (USHORT)GetCurrentProcessId();
    tracert_packet.icmp_header.SeqNumber = SeqNumber++;
    memset(tracert_packet.data_part, 'E', TRACERT_DATA_PART_SIZE);
    tracert_packet.icmp_header.checkSum = ip_checksum((USHORT*)&tracert_packet, sizeof(tracert_packet));
}
 
int Tracert::DecodeTracertPacket(const IPHeader &ip_header, const int recvPacketLen)
{
    USHORT ipheader_len = ip_header.h_len * 4;
    if (recvPacketLen < ipheader_len + ICMP_MIN)
    {
        // Packet is too small
        cout << "Receive packet is too small" << endl;
        return -1;
    }
   
    TracertPacket *tracertpacket = (TracertPacket*)((char*)&ip_header + ipheader_len);
    if (tracertpacket == NULL)
    {
        cout << "ICMP Header is NULL" << endl;
        return -1;
    }
 
    if (tracertpacket->icmp_header.type == ICMP_TIMEOUT && tracertpacket->icmp_header.code == 0)
    {
        //cout << "Reply Packet" << endl;
        //cout << "time:" << int (GetTickCount() - pingpacket->dwTime) << endl;
        cout << "Route Address:";
        ReadIPAddress(ip_header.source_ip);
    }
   
    if(tracertpacket->icmp_header.type==ICMP_REPLAY &&
       tracertpacket->icmp_header.ID==GetCurrentProcessId())
    {
        //printf("%2d:        %-15s       %4dms/n",icmpcount++,
        //       inet_ntoa(from->sin_addr),tick-cStartTickCount);
        cout << "Route Address:";
        ReadIPAddress(ip_header.source_ip);
        printf("Trace complete!/n");
        return TRANSFER_OVER;
    }
    return 0;
}
 
BOOL Tracert::StartClient()
{
    int flag = 0;
    while(true)
    {
        if (SendPacket())
        {
            return FALSE;
        }
        flag = ReceivePacket();
        if (flag == TRANSFER_OVER)
        {
            return TRUE;
        }
        else if (flag)
        {
            return FALSE;
        }
        Sleep(1000);
    }
    return TRUE;
}
 
DWORD Tracert::InitializeConnection()
{
    cout << "+Initialize Connection!" << endl;
    WSAData wsaData;
    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
    {
        cout << "Startup error!" << endl;
        return GetLastError();
    }
    sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sock < 0)
    {
        cout << "Create socket error!" << endl;
        return GetLastError();
    }
    if (Configuration())
    {
        return GetLastError();
    }
    cout << "-Initialize Connection!" << endl;
    return 0;
}
 
int Tracert::UnitializeConnection()
{
    WSACleanup();
    closesocket(sock);
    cout << "Unitialize Connection!" << endl;
    return 0;
}
 
int Tracert::UnPackTracertPacketPacket()
{
    return 0;
}
-------------------------------------------------------------------------------------------------------------
main.cpp
 
#include "Tracert.h"
int main()
{
    Tracert tracert_Program;
    tracert_Program.StartClient();
    return 0;
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值