TCP-Traceroute核心代码

    技术2022-05-11  54

    //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  

    最新回复(0)