Skip to content

Layer 2 Header Inspection API

Shane Alcock edited this page Apr 30, 2019 · 3 revisions

This API was added in libtrace 4.0.7

The layer 2 header inspection API is aimed at making it easier for users to explore the variety of headers that can appear between a convention layer 2 header (like Ethernet) and the IP header, without having to write code to explicitly walk through each header individually.

The core of this API is built around two structures and two function calls:

typedef struct libtrace_layer2_header {
        uint16_t ethertype;                     /**< Ethertype of the header */
        void *data;                             /**< Pointer to the header */
} libtrace_layer2_header_t;

typedef struct libtrace_layer2_headers {
        uint64_t bitmask;                       /**< Bitmask of found headers */
        int num;                                /**< The number of headers */
        libtrace_layer2_header_t *header;       /**< Array of all found layer2 headers */
} libtrace_layer2_headers_t;

libtrace_layer2_headers_t *trace_get_layer2_headers(libtrace_packet_t *packet);
int trace_destroy_layer2_headers(libtrace_layer2_headers_t *headers);

If you call trace_get_layer2_headers() on a libtrace packet, it will return you a pointer to a populated libtrace_layer2_headers_t structure, which is essentially an array of layer 2 headers that it found in the packet after the first one (i.e. the initial Ethernet or 802.11 header). Within that structure, there are three fields: num which is the size of the array, header which is the array itself, and bitmask which can be used to quickly check which types of headers appear within the array (e.g. if all you care about is counting the number of packets with at least one VLAN tag, then you can just check the bitmask directly rather than walking the array). Note that if there are no additional layer 2 headers after the initial header in the packet, trace_get_layer2_headers() will return NULL.

Each entry in the header array is a structure of type libtrace_layer2_header_t, which contains two fields: 'data' which is a pointer to the start of the header within the packet and 'ethertype' which tells you what type of header it actually is. You'll need to refer to the ethertype to cast the data to the appropriate header type if you want to inspect the header contents.

Once you are finished with the returned header array, you'll need to call trace_destroy_layer2_headers() to ensure that any memory associated with the header array is freed correctly.

There are also two new helper functions that have been included as part of this API:

uint16_t trace_get_outermost_vlan(libtrace_packet_t *packet, uint8_t **vlanptr, uint32_t *remaining);
uint32_t trace_get_outermost_mpls(libtrace_packet_t *packet, uint8_t **mplsptr, uint32_t *remaining);

These functions return the outermost VLAN ID or MPLS label in the given packet, respectively. They also provide a pointer to the VLAN or MPLS header itself (via the second argument) and the number of captured bytes remaining in the packet starting from the found header (via the remaining argument). If no appropriate header is found in the packet, the two functions return either VLAN_NOT_FOUND or MPLS_NOT_FOUND, depending on what header you asked for.

Clone this wiki locally