⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 analyzer.cpp

📁 ipv6 隧道探测工具。是linux下使用的。 用于探测两点间是否存在隧道
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <iostream>#include <stdlib.h>#include <string>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <netdb.h>#include <netinet/in_systm.h>#include <net/route.h>#include <sys/time.h>#include <unistd.h>#include <signal.h>#include <sys/socket.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <netinet/ip6.h>#include <netinet/icmp6.h>#include <sys/ioctl.h>#include <net/if.h>#include "Segment.h"#include "SegmentAna.h"#include "Analyzer.h"#include "IfAna.h"#include "NameIpAna.h"#include "RawSender.h"using namespace std;const size_t BUFFER_LENGTH = 65536;const size_t ADO_BUF_SIZE = 1024;int sequence = 0;int relsequence = 0; //to apply when using fragmented traceroute6int relsequenceapp = 0; //for backing up fragmented tr..int pid = getpid() & 0xffff;unsigned int mtu = 0;unsigned int appmtu = 0;string vp4source = "";string vp4dest = "";string vp4sourceapp = "";string vp4destapp = "";Analyzer::Analyzer() {  ipRef = "";  ipRefPath = "";  option = "";}//this function generaters checksum ipv6unsigned short Analyzer::in_cksum(unsigned short *ptr, int nbytes){        register long   sum;        u_short         oddbyte;        register        u_short answer;        sum = 0;        while (nbytes > 1) {                sum += *ptr++;                nbytes -= 2;        }        if (nbytes == 1) {                oddbyte = 0;                *((u_char *) & oddbyte) = *(u_char *) ptr;                sum += oddbyte;        }        sum = (sum >> 16) + (sum & 0xffff);        sum += (sum >> 16);        answer = ~sum;        return (answer);}unsigned short		/* this function generates header checksums ipv4*/Analyzer::csum (unsigned short *buf, int nwords){  unsigned long sum;  for (sum = 0; nwords > 0; nwords--)    sum += *buf++;  sum = (sum >> 16) + (sum & 0xffff);  sum += (sum >> 16);  return ~sum;}u_short Analyzer::pseudo_check(struct in6_addr from, struct in6_addr to, void *pkt, int length, int nh){    struct pseudo6 {        struct in6_addr src;        struct in6_addr dst;        unsigned short plen;        u_char zero;        u_char nh;    } *psd;    char *tosum;    u_short resultz;    tosum = (char *)(malloc(length + sizeof(struct pseudo6)));    memset(tosum, 0, length + sizeof(struct pseudo6));    psd = (struct pseudo6 *)(tosum);    memcpy(tosum + sizeof(struct pseudo6), pkt, length);    psd->src = from;    psd->dst = to;    psd->plen = htons(length);    psd->nh = nh;    resultz = in_cksum((u_short *)tosum, length + sizeof(struct pseudo6));    free(tosum);    return(resultz);}string Analyzer::getOwnIp(string ipRef) {  int s = socket (AF_INET6, SOCK_DGRAM, 0);	/* open raw socket */  struct sockaddr_in6 sin;  struct sockaddr_in6 sin2;  socklen_t len;  bzero(&sin,sizeof(sin));  int res = inet_pton(AF_INET6,ipRef.c_str(),&sin.sin6_addr);  if (res==0) {    printf("error with ip given as ipv6 of reference, either inserted bad with the -h, or in the tunneltrace.ip file\n");    exit(1);  }  sin.sin6_port=htons(1025);  sin.sin6_family=AF_INET6;  len = sizeof(sin2);  socklen_t optlen = sizeof(unsigned int);  int discover = 0;  if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER,   (char*) &discover, sizeof(discover)) == -1) perror("setsockopt IPV6_MTU_DISCOVER");  if (connect(s,(struct sockaddr*)&sin,sizeof(sin))==0) {    //let's set the mtu of our connection for future mtu path discovery//    getsockopt(s, IPPROTO_IPV6, IPV6_MTU, &mtuinfo, &infolen);   // cout<<"mtu: "<<mtu<<endl;   if (mtu == 0) { //I look for the MTU only the first time OwnIp is called     if (getsockopt(s, IPPROTO_IPV6, IPV6_MTU, (void *) &mtu, &optlen) < 0) {         printf("error determinig MTU\n");         close(s);         exit(2);     }  //   cout<<mtu<<endl;   }    //now we can look for our own ipv6 address    getsockname(s,(struct sockaddr*)&sin2,&len);    char abuf[INET6_ADDRSTRLEN];    (void) inet_ntop(AF_INET6, &sin2.sin6_addr , abuf , sizeof(abuf));    string apps = abuf;    close(s);    return apps;  }  else {    printf("error on connect, when determinig ownIP!!!\n");    close(s);    exit(2);  }}string Analyzer::Receiver(int recvfd) {  int ret=0;  uint8_t *ado_buffer;  char *my_buffer;  struct icmp6_filter filter;  //int recvfd;  struct msghdr msg;  struct iovec iov;  int found = 0;  struct in6_pktinfo info;  struct cmsghdr *cm;  struct in6_addr destination_address;  struct sockaddr_storage ss;  struct sockaddr_in6 *sender_address;  ado_buffer = (uint8_t *)malloc(ADO_BUF_SIZE);  if (ado_buffer == NULL) return "";  my_buffer = (char *)malloc(BUFFER_LENGTH);  if (my_buffer == NULL) return "";  //qui setti correttamente il buffer di destinazione  iov.iov_base = my_buffer;  iov.iov_len = BUFFER_LENGTH;  memset(&msg, 0, sizeof(msg));  msg.msg_name= &ss;  msg.msg_namelen=sizeof(ss);  msg.msg_iov = &iov;  msg.msg_iovlen = 1;  msg.msg_control = ado_buffer;  msg.msg_controllen = ADO_BUF_SIZE;  if(recvfd < 0) {    perror("socket");    close(recvfd);    return "";  }  int on=1;  setsockopt(recvfd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on));  fd_set fds;  struct timeval time1, time2, tv = {6,0};  FD_ZERO(&fds);  FD_SET(recvfd, &fds);  gettimeofday(&time1, NULL);  while(select(recvfd+1, &fds, NULL, NULL, &tv) != 0) {    /* Update timeout */    gettimeofday(&time2, NULL);    /* Check for carry, or we'll be sleeping forever... */    if(time2.tv_usec < time1.tv_usec) {        time2.tv_sec = time2.tv_sec - 1;        time2.tv_usec = time2.tv_usec + 1000000L;    }    tv.tv_sec = time2.tv_sec - time1.tv_sec;    tv.tv_usec = time2.tv_usec - time1.tv_usec;    time1 = time2;    /* Paranoia helps sometimes. If 0s timeout, select will wait forever. */    if(tv.tv_sec == 0 && tv.tv_usec == 0) {        tv.tv_sec = 0;        tv.tv_usec = 100000L;    }   ret=recvmsg(recvfd,&msg,0);   //controllo che non ci siano stati errori..   if (ret < 0) {     close(recvfd);     return "";   }  if (ret!=0) {    for (cm = CMSG_FIRSTHDR(&msg); cm!= NULL; cm= CMSG_NXTHDR(&msg, cm)) {      if (cm->cmsg_level == IPPROTO_IPV6 &&          cm->cmsg_type == IPV6_PKTINFO &&          cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {               info = *(struct in6_pktinfo*) CMSG_DATA(cm);               found = 1;               break;      }     }    destination_address = info.ipi6_addr;    struct icmp6_hdr *icmp6;    icmp6= (struct icmp6_hdr* ) my_buffer;    switch(icmp6->icmp6_type) {      case (129) : {        if ((icmp6->icmp6_id==pid) && (icmp6->icmp6_seq==sequence)) {          close(recvfd);          return "ok"; //echo reply, traceroute6 stops        }      }      break;      case (3) : {        struct icmp6_hdr *icmp6_2;        icmp6_2= (struct icmp6_hdr* ) (my_buffer + sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr));        if ((icmp6_2->icmp6_id==pid) && (icmp6_2->icmp6_seq==sequence)) {          char abuf[INET6_ADDRSTRLEN];          sender_address = (struct sockaddr_in6 *)&ss;          (void) inet_ntop(AF_INET6, &sender_address->sin6_addr , abuf , sizeof(abuf));          close(recvfd);          string sapp = abuf;          return sapp; //let's return the source address        }      }      break;      case (ICMP6_PACKET_TOO_BIG) : { //path mtu discovery        struct icmp6_hdr *icmp6_2;        icmp6_2= (struct icmp6_hdr* ) (my_buffer + sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr));        if ((icmp6_2->icmp6_id==pid) && (icmp6_2->icmp6_seq==sequence)) {          mtu = ntohl(icmp6->icmp6_mtu); //let's determine the future mtu          char abuf[INET6_ADDRSTRLEN];          sender_address = (struct sockaddr_in6 *)&ss;          (void) inet_ntop(AF_INET6, &sender_address->sin6_addr , abuf , sizeof(abuf));          close(recvfd);          string sapp = abuf;          return sapp; //let's return the source address        }      }      break;    }  }  }  close(recvfd);  return "";}int Analyzer::Sender(string sourceAddress, string destAddress, int hoplimit) {  int s = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);	/* open raw socket */  if(s < 0) {    perror("socket");    close(s);    return -1;  }  char icmp6PL[8];  char datagram[1500];  memset (datagram, 0, sizeof(datagram));  struct icmp6_hdr *icmp;  icmp = (struct icmp6_hdr *) (datagram);  icmp->icmp6_type = 128;  icmp->icmp6_code = 0;  icmp->icmp6_cksum = 0;  icmp->icmp6_id =pid;  icmp->icmp6_seq=sequence;  memset(&icmp6PL, 0, sizeof(icmp6PL));  in6_addr in;  in6_addr *p_in=&in;  int res1=inet_pton(AF_INET6, sourceAddress.c_str() , p_in);  in6_addr in2;  in6_addr *p_in2=&in2;  int res2=inet_pton(AF_INET6, destAddress.c_str() , p_in2); //destination IP  struct sockaddr_in6 sin;  bzero(&sin,sizeof(sin));  int res = inet_pton(AF_INET6, destAddress.c_str() , &sin.sin6_addr);  if (res==0) {    printf("error with ip \n");    exit(1);  }//    sin.sin6_port=htons(1025);  sin.sin6_family=AF_INET6;  int recvfd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);  if(recvfd < 0) {    perror("socket");    close(recvfd);    return -1;  } // int on = 1;//  if (setsockopt(s, IPPROTO_IPV6, 62, &on, sizeof(on))== -1) printf("problems frag")  ;  // 62 = IPV6_DONTFRAG  if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hoplimit,      sizeof(hoplimit)) == -1)      perror("setsockopt IPV6_UNICAST_HOPS");  if (sendto (s,		/* our socket */        datagram,	/* the buffer containing header and data */   //     sizeof(datagram),	/* total length of our datagram */        mtu-40, //8 bytes of ICMPv6 header + 40 bytes of IPv6 header        0,		/* routing flags, normally always 0 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -