Reassemble packets for pcap file

In TCP protocol, because MSS limitation, sometimes one endpoint needs to split one TCP packet into multiple packets and send them. Today, I met a case which requires to reassemble them into one.

Firstly, I used Wireshark to “Hex Dump” first need-reassemble packet:

0000   18 cf 24 4c 71 4b 54 89 98 76 b8 30 08 00 45 00
......

Modify the length in IP header, append remaining TCP payload, then used colrm to remove offset:

# colrm 1 4 < data > data.txt

Used awk to prepend 0x and append , for every value:

awk '{ for(i = 1; i <= NF; i++) {$i="0x"$i","} print}' data.txt

Added the variable definition for array:

const u_char new_packet_4[] = {
    0x18, 0xcf, ......
    .......
}

Lastly, write a small program to insert new packet 4 and remove original packet 4 and 5, and code is here (Don’t forget to modify the header of packet 4).

Manipulate pcap file

Yesterday, to debug a tricky issue, I need to implement 2 utilities to manipulate pcap files through pcap library. The framework is simple: open source and destination files:

    ......
    char err[PCAP_ERRBUF_SIZE];
    src_handle = pcap_open_offline(src_file, err);
    if (src_handle == NULL) {
        printf("Open %s failed: %s\n", src_file, err);
        return EXIT_FAILURE;
    }

    dst_handle = pcap_open_dead(DLT_EN10MB, 262144);
    pcap_dumper_t *dst_dump = pcap_dump_open(dst_handle, dst_file);
    if (dst_dump == NULL) {
        printf("pcap_dump_open error: %s\n", pcap_geterr(dst_handle));
        return EXIT_FAILURE;
    }
    ......
    pcap_dump_close(dst_dump);
    pcap_close(dst_handle);
    pcap_close(src_handle);

    return EXIT_SUCCESS;

The first tool was creating out-of-order packets which I cached the previous packet and inserted it after other one:

......
    while (1)
    {
        struct pcap_pkthdr *hdr = NULL;
        static struct pcap_pkthdr src_index_hdr;

        const u_char *data = NULL;
        static u_char *src_index_data = NULL;

        static int count = 0;

        int ret = pcap_next_ex(src_handle, &hdr, &data);
        if (ret == 1) {
            if (++count == src_index) {
                memcpy(&src_index_hdr, hdr, sizeof(struct pcap_pkthdr));
                src_index_data = malloc(hdr->caplen);
                if (src_index_data == NULL) {
                    printf("malloc failed\n");
                    return EXIT_FAILURE;
                }
                memcpy(src_index_data, data, hdr->caplen);
            } else {
                pcap_dump((u_char *)dst_dump, hdr, data);
                if (count == dst_index) {
                    pcap_dump((u_char *)dst_dump, &src_index_hdr, src_index_data);
                }
            }
        } else if (ret == PCAP_ERROR_BREAK) {
            break;
        } else {
            printf("pcap_next_ex error: %s\n", pcap_geterr(src_handle));
            return EXIT_FAILURE;
        }
    }
......

The second was simple, just dumped the first 1200 packets into another file.

P.S., the full code is here.

Pcap develop package is needed in compiling tcpdump

On a fresh VoidLinux, I compiled tcpdump source code and met following errors during configuration:

# ../configure CFLAGS='-g -O0'
......
checking for local pcap library... not found
checking for pkg-config... no
checking for pcap-config... no
checking for main in -lpcap... no
configure: error: see the INSTALL doc for more info

I was sure libpcap was already installed. After some investigating, I found the root cause was libpcap-devel was needed:

# xbps-install -Suv libpcap-devel
......

Then the issue was fixed.