コード例 #1
0
ファイル: tcpliveplay.c プロジェクト: rkophs/tcpreplay
/**
 * 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;
}
コード例 #2
0
ファイル: tcpliveplay.c プロジェクト: KevinFei/tcpreplay
/**
 * 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;
}