int setup_sched(struct tcp_sched* sched) { in_addr sip, dip; /* Source & Destination IP */ in_addr local_ip, remote_ip; /* ip address of client and server*/ /*temporary packet buffers*/ struct pcap_pkthdr header; // The header that pcap gives us const u_char *packet; // The actual packet pcap_t *local_handle; unsigned int pkt_counter=0; ether_hdr *etherhdr = NULL; tcp_hdr *tcphdr = NULL; ipv4_hdr *iphdr = NULL; local_ip.byte1=0; local_ip.byte2=0; local_ip.byte3=0; local_ip.byte4=0; remote_ip.byte1=0; remote_ip.byte2=0; remote_ip.byte3=0; remote_ip.byte4=0; unsigned int size_ip, i = 0; unsigned int size_tcp; unsigned int size_payload; char errbuf[PCAP_ERRBUF_SIZE]; unsigned int flags=0; bool remote = false; /* flags to test if data is from 'cleint'=local or 'server'=remote */ bool local = false; local_handle = pcap_open_offline("newfile.pcap", errbuf); /*call pcap library function*/ if (local_handle == NULL) { fprintf(stderr,"Couldn't open pcap file %s: %s\n", "newfile.pcap", errbuf); return(2); } /*Before sending any packet, setup the schedule with the proper parameters*/ while((packet = pcap_next(local_handle,&header))) { pkt_counter++; /*increment number of packets seen*/ memcpy(&sched[i].pkthdr, &header, sizeof(struct pcap_pkthdr)); //sched[i].len = header.len; //sched[i].caplen = header.caplen; sched[i].packet_ptr = safe_malloc(sched[i].pkthdr.len); memcpy(sched[i].packet_ptr, packet, sched[i].pkthdr.len); /* extract necessary data */ etherhdr = (ether_hdr*)(sched[i].packet_ptr); iphdr = (ipv4_hdr *)(sched[i].packet_ptr + SIZE_ETHERNET); size_ip = iphdr->ip_hl << 2; if (size_ip < 20) { printf("ERROR: Invalid IP header length: %u bytes\n", size_ip); return 0; } tcphdr = (tcp_hdr *)(sched[i].packet_ptr + SIZE_ETHERNET + size_ip); size_tcp = tcphdr->th_off*4; if (size_tcp < 20) { printf("ERROR: Invalid TCP header length: %u bytes\n", size_tcp); return 0; } /* payload = (u_char *)(sched[i].packet_ptr + SIZE_ETHERNET + size_ip + size_tcp); */ size_payload = ntohs(iphdr->ip_len) - (size_ip + (size_tcp)); /* Source IP and Destination IP */ sip = iphdr->ip_src; dip = iphdr->ip_dst; flags = tcphdr->th_flags; if (flags == TH_SYN) { /* set IPs who's local and who's remote based on the SYN flag */ local_ip = sip; remote_ip = dip; } /*Compare IPs to see which packet is this comming from*/ if(compip(&local_ip, &remote_ip, &sip)==LOCAL_IP_MATCH) { local = true; remote = false; } if(compip(&local_ip, &remote_ip, &sip)==REMOTE_IP_MATCH) { local = false; remote = true; } /* Setup rest of Schedule, parameter by parameter */ /* Refer to header file for details on each of the parameters */ sched[i].etherhdr = etherhdr; sched[i].iphdr = iphdr; sched[i].tcphdr = tcphdr; sched[i].size_ip = size_ip; sched[i].size_tcp = size_tcp; sched[i].size_payload = size_payload; sched[i].sent_counter = 0; /* Do the following only for the first packet (SYN)*/ if(i==0) { sched[i].length_last_ldata = 0; sched[i].length_curr_ldata = 0; sched[i].length_last_rdata = 0; sched[i].length_curr_rdata = 0; sched[i].local = true; sched[i].remote = false; sched[i].curr_lseq = ntohl(sched[i].tcphdr->th_seq); sched[i].curr_lack = 0; sched[i].exp_rseq = 0; /* Keep track of previous remote seq & ack #s*/ sched[i].exp_rack = 0; } /* Local Packet operations */ else if(local) { sched[i].length_last_ldata = sched[i-1].length_curr_ldata; sched[i].length_curr_ldata = size_payload; sched[i].length_last_rdata = sched[i-1].length_curr_rdata; sched[i].length_curr_rdata = 0; sched[i].local = true; sched[i].remote = false; sched[i].curr_lseq = ntohl(sched[i].tcphdr->th_seq); sched[i].curr_lack = ntohl(sched[i].tcphdr->th_ack); sched[i].exp_rseq = sched[i-1].exp_rseq; /* Keep track of previous remote seq & ack #s*/ sched[i].exp_rack = sched[i-1].exp_rack; } /* Remote Packet operations */ else if(remote) { sched[i].length_last_ldata = sched[i-1].length_curr_ldata; sched[i].length_curr_ldata = 0; sched[i].length_last_rdata = sched[i-1].length_curr_rdata; sched[i].length_curr_rdata = size_payload; sched[i].local = false; sched[i].remote = true; sched[i].curr_lseq = sched[i-1].curr_lseq; sched[i].curr_lack = sched[i-1].curr_lack; sched[i].exp_rseq = ntohl(sched[i].tcphdr->th_seq); /* Keep track of previous remote seq & ack #s*/ sched[i].exp_rack = ntohl(sched[i].tcphdr->th_ack); /* Setup global variable where remote FIN-ACK exists*/ if(flags == (TH_FIN|TH_ACK)) finack_rindex = i; //printf("REMOTE --------%d\n",i+1); } i++; /* increment schedule index */ } /*end internal loop for reading packets (all in one file)*/ pcap_close(local_handle); /*close the pcap file*/ return pkt_counter; /* Return number of packets scheduled */ }
/** * This function rewrites the IPs and MACs of a given packet, * creates a newfile.pcap. It returns the number of packets of the newfile. * This function only starts rewriting the newfile once it sees the first * SYN packet. This is so that the first packet in the newfile is always * the first packet to be sent. */ int rewrite(in_addr* new_remoteip, struct mac_addr* new_remotemac, in_addr* myip, struct mac_addr* mymac, char* file, unsigned int new_src_port) { ether_hdr* etherhdr; ipv4_hdr *iphdr; tcp_hdr *tcphdr; in_addr local_ip; in_addr remote_ip; unsigned int size_ip; unsigned int size_tcp; char* newfile = "newfile.pcap"; char ErrBuff [1024]; int pkt_counter, len; const u_char *packet; struct pcap_pkthdr *header; in_addr sip; /* Source IP */ unsigned int flags; int local_packets = 0; bool initstep1 = false; /* keep track of successful handshake step */ local_ip.byte1=0; local_ip.byte2=0; local_ip.byte3=0; local_ip.byte4=0; remote_ip.byte1=0; remote_ip.byte2=0; remote_ip.byte3=0; remote_ip.byte4=0; /*Read the header of the PCAP*/ int fp_for_header = open(file,O_RDONLY); if(fp_for_header < 0) { fprintf(stderr, "Cannot open PCAP file to get file header.\n"); return PCAP_OPEN_ERROR; } u_int8_t data[sizeof(struct pcap_file_header)]; len = read(fp_for_header, data, sizeof(struct pcap_file_header)); if(len == 0) { fprintf(stderr, "Could not read from file.\n"); } close(fp_for_header); /*Open file for reading each packet*/ int fp = open(newfile,O_CREAT|O_WRONLY,S_IRWXU); if(fp < 0) { fprintf(stderr, "Cannot open file: %s for writing.\n",newfile); return PCAP_OPEN_ERROR; } /* Write the header to new file */ len = write(fp, data,sizeof(struct pcap_file_header)); pcap_t *pcap = set_offline_filter(file); if (!pcap) { fprintf (stderr, "Cannot open PCAP file '%s'\n", file); fprintf(stderr, "%s\n",ErrBuff); return PCAP_OPEN_ERROR; } /*Modify each packet's IP & MAC based on the passed args then do a checksum of each packet*/ for (pkt_counter = 0; pcap_next_ex(pcap, &header, &packet) > 0; pkt_counter++) { etherhdr = (ether_hdr*)(packet); iphdr = (ipv4_hdr *)(packet + SIZE_ETHERNET); size_ip = iphdr->ip_hl << 2; if (size_ip < 20) { printf("ERROR: Invalid IP header length: %u bytes\n", size_ip); return ERROR; } tcphdr = (tcp_hdr *)(packet + SIZE_ETHERNET + size_ip); size_tcp = tcphdr->th_off*4; if (size_tcp < 20) { printf("ERROR: Invalid TCP header length: %u bytes\n", size_tcp); return ERROR; } /* payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); */ sip = iphdr->ip_src; flags = tcphdr->th_flags; /* set IPs who's local and who's remote based on the SYN flag */ if(flags == TH_SYN) { local_ip = iphdr->ip_src; remote_ip = iphdr->ip_dst; initstep1 = true; /* This flag is set to signify the first encounter of the SYN within the pacp*/ } if(compip(&local_ip, &remote_ip, &sip)==LOCAL_IP_MATCH) { /* Set the source MAC */ etherhdr->ether_shost[0] = mymac->byte1; etherhdr->ether_shost[1] = mymac->byte2; etherhdr->ether_shost[2] = mymac->byte3; etherhdr->ether_shost[3] = mymac->byte4; etherhdr->ether_shost[4] = mymac->byte5; etherhdr->ether_shost[5] = mymac->byte6; /* Set the source IP */ iphdr->ip_src = *myip; /* Set the destination IP */ iphdr->ip_dst = *new_remoteip; /* Set the destination MAC */ etherhdr->ether_dhost[0] = new_remotemac->byte1; etherhdr->ether_dhost[1] = new_remotemac->byte2; etherhdr->ether_dhost[2] = new_remotemac->byte3; etherhdr->ether_dhost[3] = new_remotemac->byte4; etherhdr->ether_dhost[4] = new_remotemac->byte5; etherhdr->ether_dhost[5] = new_remotemac->byte6; /* This is to change the source port, whether it is specified as random or as a port # by the user */ tcphdr->th_sport = htons(new_src_port); } else if(compip(&local_ip, &remote_ip, &sip)==REMOTE_IP_MATCH) { /* Set the destination MAC */ etherhdr->ether_dhost[0] = mymac->byte1; etherhdr->ether_dhost[1] = mymac->byte2; etherhdr->ether_dhost[2] = mymac->byte3; etherhdr->ether_dhost[3] = mymac->byte4; etherhdr->ether_dhost[4] = mymac->byte5; etherhdr->ether_dhost[5] = mymac->byte6; /* Set the destination IP */ iphdr->ip_dst = *myip; /* Set the source IP */ iphdr->ip_src = *new_remoteip; /* Set the source MAC */ etherhdr->ether_shost[0] = new_remotemac->byte1; etherhdr->ether_shost[1] = new_remotemac->byte2; etherhdr->ether_shost[2] = new_remotemac->byte3; etherhdr->ether_shost[3] = new_remotemac->byte4; etherhdr->ether_shost[4] = new_remotemac->byte5; etherhdr->ether_shost[5] = new_remotemac->byte6; /* This is to change the source port, whether it is specified as random or as a port # by the user */ tcphdr->th_dport = htons(new_src_port); } /*Calculate & fix checksum for newly edited-packet*/ fix_all_checksum_liveplay(iphdr); if(initstep1) { /*only start rewriting new pcap with SYN packets on wards*/ local_packets ++; len = write(fp,header,16); if(len == 0) { fprintf(stderr, "Error occurred writing pcap_header.\n"); pcap_close(pcap); close(fp); return REWRITE_ERROR; } len = write(fp,packet,header->caplen); if(len == 0) { fprintf(stderr, "Error occurred writing pcap data.\n"); pcap_close(pcap); close(fp); return REWRITE_ERROR; } } } /* end of while loop */ pcap_close (pcap); close(fp); return local_packets; }
/** * This function rewrites the IPs and MACs of a given packet, * creates a newfile.pcap. It returns the number of packets of the newfile. * This function only starts rewriting the newfile once it sees the first * SYN packet. This is so that the first packet in the newfile is always * the first packet to be sent. */ int rewrite(input_addr* new_remoteip, struct mac_addr* new_remotemac, input_addr* myip, struct mac_addr* mymac, char* file, unsigned int new_src_port) { ether_hdr* etherhdr; ipv4_hdr *iphdr; tcp_hdr *tcphdr; input_addr local_ip; input_addr remote_ip; unsigned int size_ip; unsigned int size_tcp; char* newfile = "newfile.pcap"; char ErrBuff [1024]; int pkt_counter; const u_char *packet; struct pcap_pkthdr *header; pcap_dumper_t *dumpfile; input_addr sip; /* Source IP */ unsigned int flags; int local_packets = 0; bool initstep1 = false; /* keep track of successful handshake step */ bool warned = false; local_ip.byte1=0; local_ip.byte2=0; local_ip.byte3=0; local_ip.byte4=0; remote_ip.byte1=0; remote_ip.byte2=0; remote_ip.byte3=0; remote_ip.byte4=0; pcap_t *pcap = set_offline_filter(file); if (!pcap){ fprintf (stderr, "Cannot open PCAP file '%s' for reading\n", file); fprintf(stderr, "%s\n",ErrBuff); return PCAP_OPEN_ERROR; } dumpfile = pcap_dump_open(pcap, newfile); if (!dumpfile) { fprintf (stderr, "Cannot open PCAP file '%s' for writing\n", newfile); return PCAP_OPEN_ERROR; } /*Modify each packet's IP & MAC based on the passed args then do a checksum of each packet*/ for (pkt_counter = 0; pcap_next_ex(pcap, &header, &packet) > 0; pkt_counter++){ if (!warned && header->len > header->caplen) { fprintf(stderr, "warning: packet capture truncated to %d byte packets\n", header->caplen); warned = true; } etherhdr = (ether_hdr*)(packet); iphdr = (ipv4_hdr *)(packet + SIZE_ETHERNET); size_ip = iphdr->ip_hl << 2; if (size_ip < 20) { printf("ERROR: Invalid IP header length: %u bytes\n", size_ip); return ERROR; } tcphdr = (tcp_hdr *)(packet + SIZE_ETHERNET + size_ip); size_tcp = tcphdr->th_off*4; if (size_tcp < 20) { printf("ERROR: Invalid TCP header length: %u bytes\n", size_tcp); return ERROR; } /* payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); */ sip = iphdr->ip_src; flags = tcphdr->th_flags; /* set IPs who's local and who's remote based on the SYN flag */ if(flags == TH_SYN){ local_ip = iphdr->ip_src; remote_ip = iphdr->ip_dst; initstep1 = true; /* This flag is set to signify the first encounter of the SYN within the pacp*/ } if(compip(&local_ip, &remote_ip, &sip)==LOCAL_IP_MATCH){ /* Set the source MAC */ etherhdr->ether_shost[0] = mymac->byte1; etherhdr->ether_shost[1] = mymac->byte2; etherhdr->ether_shost[2] = mymac->byte3; etherhdr->ether_shost[3] = mymac->byte4; etherhdr->ether_shost[4] = mymac->byte5; etherhdr->ether_shost[5] = mymac->byte6; /* Set the source IP */ iphdr->ip_src = *myip; /* Set the destination IP */ iphdr->ip_dst = *new_remoteip; /* Set the destination MAC */ etherhdr->ether_dhost[0] = new_remotemac->byte1; etherhdr->ether_dhost[1] = new_remotemac->byte2; etherhdr->ether_dhost[2] = new_remotemac->byte3; etherhdr->ether_dhost[3] = new_remotemac->byte4; etherhdr->ether_dhost[4] = new_remotemac->byte5; etherhdr->ether_dhost[5] = new_remotemac->byte6; /* This is to change the source port, whether it is specified as random or as a port # by the user */ tcphdr->th_sport = htons(new_src_port); } else if(compip(&local_ip, &remote_ip, &sip)==REMOTE_IP_MATCH){ /* Set the destination MAC */ etherhdr->ether_dhost[0] = mymac->byte1; etherhdr->ether_dhost[1] = mymac->byte2; etherhdr->ether_dhost[2] = mymac->byte3; etherhdr->ether_dhost[3] = mymac->byte4; etherhdr->ether_dhost[4] = mymac->byte5; etherhdr->ether_dhost[5] = mymac->byte6; /* Set the destination IP */ iphdr->ip_dst = *myip; /* Set the source IP */ iphdr->ip_src = *new_remoteip; /* Set the source MAC */ etherhdr->ether_shost[0] = new_remotemac->byte1; etherhdr->ether_shost[1] = new_remotemac->byte2; etherhdr->ether_shost[2] = new_remotemac->byte3; etherhdr->ether_shost[3] = new_remotemac->byte4; etherhdr->ether_shost[4] = new_remotemac->byte5; etherhdr->ether_shost[5] = new_remotemac->byte6; /* This is to change the source port, whether it is specified as random or as a port # by the user */ tcphdr->th_dport = htons(new_src_port); } /*Calculate & fix checksum for newly edited-packet*/ fix_all_checksum_liveplay(iphdr); if(initstep1){ /*only start rewriting new pcap with SYN packets on wards*/ local_packets ++; pcap_dump((u_char *)dumpfile, header, packet); } } /* end of while loop */ pcap_close (pcap); pcap_dump_close(dumpfile); return local_packets; }