📄 analyzer.cpp
字号:
#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=∈ 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 + -