PCAP Format for Logs

While developing dietsniff I had to find a way to write pcap logs. However the docs I found were rather fragmented. I try to do a short roundup here. In fact, the format is pretty plain and it’s a pity that there seems not to be a quick’n’easy doc for it.

Every log-file starts with a header:

1
2
3
4
5
6
7
8
9
struct pcap_hdr {
    unsigned long  magic;         /* always 0xa1b2c3d4 */
    unsigned short version_major; /* 2 for now */
    unsigned short version_minor; /* 4 for now */
    unsigned long  thiszone;      /* GMT to local correction */
    unsigned long  sigfigs;       /* accuracy of timestamps, 0 is fine */
    unsigned long  snaplen;       /* max length of captured packets */
    unsigned long  network;       /* data link type */
};

The only really significant field here is network, which defines the format of the packets. I’m using 113 in dietsniff which means DLT_LINUX_SLL (“Linux cooked sockets”), i.e. those from PF_SOCKET sockets. man pcap contains a list and explanation of more possible formats.

While the header mentioned above appears only once at the beginning of a log file, the following applies to every single packet that is written to the log. First of all, every packet is preceded with a generic header:

1
2
3
4
5
struct pcap_rec_hdr {
    struct timeval  ts;         /* timestamp */
    unsigned long   incl_len;   /* number of octets of packet saved in file */
    unsigned long   orig_len;   /* actual length of packet */
};

Not too exciting. Simply the timestamp of the packet, the length that is contained in the log and the real length. So it’s possible to save only a certain amount of bytes of every packet.

The following data of each packet depends heavily of the specified format. I’m going to show how I did it for DLT_LINUX_SLL: first, we need just another header (again, for each packet):

1
2
3
4
5
6
7
struct pcap_sll_hdr {
    unsigned short pkttype;
    unsigned short hatype;
    unsigned short halen;
    char addr[8];
    unsigned short protocol;
};

These fields resemble those from struct sockaddr_ll which is returned with each packet so it’s just about 4 assignments and one memcpy(). The definition of this struct can be deducted from the pcap man page in the explanation of DLT_LINUX_SLL. I guess the other types should similarly straightforward.

After this, the packet can be finally dumped to the file.

← See all posts