TCP-Traceroute核心代码[通俗易懂]

TCP-Traceroute核心代码[通俗易懂]//tracer.c//Copyright(c)1999-2004//S8S8.netNetworkTech.Forum//writtenby13thFloor//Allrightsreserved.#include#include#include#includeusingnamespacestd;#include”pcap.h”#include”hea

大家好,又见面了,我是你们的朋友全栈君。

//tracer.c

//Copyright (c) 1999 – 2004

//S8S8.net Network Tech. Forum

//written by ’13th Floor’

//All rights reserved.

#include <winsock2.h>

#include <ws2tcpip.h>

#include <cstring>

#include <queue>

using namespace std;

#include “pcap.h”

#include “headers.h”

#include “tracer.h”

char* FLT_EXPR = “ip and icmp[icmptype]=icmp-timxceed or tcp[tcpflags]=tcp-rst”;

unsigned short checksum(unsigned short *buffer, int size)

{

    unsigned long cksum = 0;

    while(size > 1) {

          cksum += *buffer++;

          size -= sizeof(unsigned short);

    }

    if(size)

          cksum += *(unsigned char*)buffer;

    cksum = (cksum >> 16) + (cksum & 0xffff);

    cksum += (cksum >> 16);

    return (unsigned short)(~cksum);

}

int build_packets(

    unsigned long local_addr,

    unsigned long dst_addr,

    char* buf,

    unsigned char TTL)

{

    static unsigned long SEQ = 0x2344512;

    int datasize =0;

    IP_HDR ip_header;

    TCP_HDR tcp_header;

    PSD_HDR psd_header;

    ip_header.h_verlen =

              (4 << 4 | sizeof(ip_header) / sizeof(unsigned long));

    ip_header.total_len = htons(sizeof(IP_HDR) + sizeof(TCP_HDR));

    ip_header.ident = 1;

    ip_header.frag_and_flags = 0;

    ip_header.ttl = TTL;

    ip_header.proto = IPPROTO_TCP;

    ip_header.checksum = 0;

    ip_header.saddr = local_addr;

    ip_header.daddr = dst_addr;

    tcp_header.th_sport = htons(7000);    

    tcp_header.th_dport = htons(5000);

    tcp_header.th_seq = SEQ++;

    tcp_header.th_ack = 0;

    tcp_header.th_lenres = (sizeof(TCP_HDR) / 4 << 4 | 0);

    tcp_header.th_flag = 16;

    tcp_header.th_win = htons(16384);

    tcp_header.th_urp = 0;

    tcp_header.th_sum = 0;

    psd_header.saddr = ip_header.saddr;

    psd_header.daddr = ip_header.daddr;

    psd_header.mbz = 0;

    psd_header.proto = IPPROTO_TCP;

    psd_header.tcpl = htons(sizeof(tcp_header));

    memcpy(buf, &psd_header, sizeof(psd_header));

    memcpy(buf + sizeof(psd_header), &tcp_header, sizeof(tcp_header));

    tcp_header.th_sum = checksum((unsigned short *)buf,

                    sizeof(psd_header) + sizeof(tcp_header));

    memcpy(buf, &ip_header, sizeof(ip_header));

    memcpy(buf + sizeof(ip_header), &tcp_header, sizeof(tcp_header));

    memset(buf + sizeof(ip_header) + sizeof(tcp_header), 0, 4);

    datasize = sizeof(ip_header) + sizeof(tcp_header);

    ip_header.checksum = checksum((unsigned short*)buf,datasize);

    memcpy(buf, &ip_header, sizeof(ip_header));

    return 0;

}

int start_trace(

    queue<unsigned long>& dst_addr_queue,

    unsigned long local_addr,

    SOCKET& socket)

{

    char snd_buf[128];

    int ret;

    sockaddr_in dst_addr;

    pcap_t* adhandle;

    struct pcap_pkthdr *header;

    const u_char *pkt_data;

    //Setup for winpcap

    pcap_if_t     *alldevs, *d;

    char           errbuf[PCAP_ERRBUF_SIZE];

    unsigned int     netmask;

    bpf_program     fcode;

    if (pcap_findalldevs(&alldevs, errbuf) == -1)

          throw (“Error in pcap_findalldevs”);    

    try {

      d = alldevs->next;

          if ((adhandle= pcap_open_live(

                          d->name, //adapter

                          65536,

                          1,

                          1000, //time out

                          errbuf))

              == NULL)

              throw (“Failed to open adapter!”);

          if(d->addresses != NULL)

              netmask=((struct sockaddr_in *)

                    (d->addresses->netmask))

                    ->sin_addr.S_un.S_addr;

          else

              netmask=0xffffff;

          if(pcap_compile(adhandle,

                    &fcode,

                    FLT_EXPR,

                    1,

                    netmask) <0

                    )

              throw (“Failed to compile the filter”);

          if(pcap_setfilter(adhandle, &fcode)<0) {

              throw (“Error setting the filter”);

          }

    }

    catch (const char * error) {

          pcap_freealldevs(alldevs);

          throw (error);

    }

    pcap_freealldevs(alldevs);

   

    //Setup for Winsock

    WSADATA     wsaData;

    BOOL flag = TRUE;

    int time_out = 2000;

    socket = INVALID_SOCKET;

    if (WSAStartup(MAKEWORD(2, 1), &wsaData) !=0)

          throw (“WSAStartup() failed”);

    try {

          socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW,

              NULL,0, WSA_FLAG_OVERLAPPED);

          if (socket == INVALID_SOCKET)

              throw (“WSASocket() failed”);

          if (setsockopt(socket, IPPROTO_IP, IP_HDRINCL,

              (char*)&flag, sizeof(int)) == SOCKET_ERROR)

              throw (“Failed to set IP_HDRINCL”);

          if (setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO,

              (char*)&time_out, sizeof(time_out)) == SOCKET_ERROR)

              throw (“Failed to set SO_SNDTIMEO”);

    }

    catch(const char* error) {

          if (socket != INVALID_SOCKET)

              closesocket(socket);

          WSACleanup();

          throw error;

    }

    //Get local address

    char name[255];

    PHOSTENT hostinfo;

    if (gethostname(name, sizeof(name))==0)

          if ((hostinfo = gethostbyname(name)) !=NULL)

              local_addr = (*(struct in_addr*)

                          *hostinfo->h_addr_list).s_addr;

    //Start Trace

    while (dst_addr_queue.empty() == false) {

          unsigned long crt_addr = dst_addr_queue.front();

          memset(&dst_addr, 0, sizeof(dst_addr));

          dst_addr.sin_family = AF_INET;

          dst_addr.sin_addr.s_addr = crt_addr;

         

          printf(“/n/nTracing: “);

          printf(“%s/n”, inet_ntoa(*(in_addr*)&crt_addr));

          for (unsigned char ttl = 1; ttl <= 30; ttl++) {

              build_packets(local_addr, crt_addr, snd_buf, ttl);

              ret = sendto(socket, snd_buf, sizeof(IP_HDR)+sizeof(TCP_HDR),

                    0, (sockaddr*)&dst_addr, sizeof(dst_addr));

              ret = pcap_next_ex(adhandle, &header, &pkt_data);

              if (ret == 0) {

                    printf(“%s/n”, “time out”);

                    continue;

              }

              IP_HDR* iphdr = (IP_HDR*)(pkt_data + 14);

              printf(“%s/n”, inet_ntoa(*(in_addr*)&(iphdr->saddr)));

              if (iphdr->proto == IPPROTO_TCP) break;

          }

          dst_addr_queue.pop();

    }

    return 0;

}

[Copy to clipboard]
CODE:
//headers.h

//Copyright (c) 1999 – 2004

//S8S8.net Network Tech. Forum

//written by ’13th Floor’

//All rights reserved.

#ifndef _HEADERS_H

#define _HEADERS_H

//IP Header

typedef struct _iphdr {

    unsigned char h_verlen;     //IP Version

    unsigned char tos;           //Type of Service; 8 bits

    unsigned short total_len;     //total length; 16 bits

    unsigned short ident;           //Identification; 16 bits

    unsigned short frag_and_flags;     //Flags

    unsigned char ttl;           //Time to live; 8 bits

    unsigned char proto;           //Protocol; 8 bits

    unsigned short checksum;     //Checksum; 16 bits

    unsigned long saddr;           //Source IP address; 32 bits

    unsigned long daddr;           //Destination IP address; 32 bits

} IP_HDR;

//PSD Header

typedef struct _psdhdr {

    unsigned long saddr;           //Source IP address; 32 bits

    unsigned long daddr;           //Destination IP address; 32 bits

    unsigned char mbz;           //padding

    unsigned char proto;           //Protocol; 8 bits

    unsigned short tcpl;           //TCP length; 16 bits

} PSD_HDR;

//TCP Header

typedef struct _tcphdr {

    unsigned short th_sport;     //Source port; 16 bits

    unsigned short th_dport;     //Destination port; 16 bits

    unsigned long th_seq;           //Sequence Number; 32 bits

    unsigned long th_ack;           //Acknowledgment Number; 32 bits

    unsigned char th_lenres;     //Data Offset / reserved

    unsigned char th_flag;           //ECN / Control Bits; 6 bits

    unsigned short th_win;           //Window; 16 bits

    unsigned short th_sum;           //Checksum; 16 bits

    unsigned short th_urp;           //Urgent Pointer; 16 bits

} TCP_HDR;

//ICMP Header

typedef struct _icmphdr {

    unsigned char i_type;           //ICMP Type; 8 bits

    unsigned char i_code;           //ICMP Code; 8 bits

    unsigned short i_cksum;           //ICMP header checksum; 16 bits

    unsigned short i_id;           //Identification; 16 bits

    unsigned short i_seq;           //Sequence Number; 16 bits

    unsigned long timestamp;     //Timestamp; 32 bits

} ICMP_HDR;

#endif

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151510.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号