Use alignof in gcc

alignof is defined in stdalign.h for gcc:

$ cat /usr/lib/gcc/x86_64-unknown-linux-gnu/9.1.0/include/stdalign.h
......
#ifndef _STDALIGN_H
#define _STDALIGN_H

#ifndef __cplusplus

#define alignas _Alignas
#define alignof _Alignof

#define __alignas_is_defined 1
#define __alignof_is_defined 1

#endif

#endif  /* stdalign.h */

To use alignofstdalign.h must be included, otherwise following errors will be reported:

......
warning: implicit declaration of function 'alignof' [-Wimplicit-function-declaration]
    3 |  return alignof(int);
      |         ^~~~~~~
 error: expected expression before

It is no need to include any header files to use _Alignof and __alignof__.

The ISN for retransmitting SYN

RFC 793 illustrates a scenario in which TCP client and server pick different ISN (Initial Sequence Number) when processing duplicate SYN packets. Form 13.2.3 Initial Sequence Number (ISN)TCP/IP Illustrated, Volume 1, I find following evidence:

Before each end sends its SYN to establish the connection, it chooses an ISN for that connection. The ISN should change over time, so that each connection has a different one. [RFC0793] specifies that the ISN should be viewed as a 32-bit counter that increments by 1 every 4μs. The purpose of doing this is to arrange for the sequence numbers for segments on one connection to not overlap with sequence numbers on a another (new) identical connection. In particular, new sequence numbers must not be allowed to overlap between different instantiations (or incarnations) of the same connection.

Reference:
What will happen at server side if it received 2 SYN packet from the same client application?.

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.