Ejemplo n.º 1
0
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 */
}
Ejemplo n.º 2
0
/**
 * 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;
}
Ejemplo n.º 3
0
/**
 * 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;
}