ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
pcap.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file pcap.h
6 * @brief libpcap file framing - the classic global + per-record headers, link-type agnostic.
7 *
8 * One owner for the PCAP framing shared by every capture feature (Wi-Fi promiscuous capture,
9 * CAN / bus listen-only capture, ...): each writes its frames with the matching DLT link type so
10 * the forwarded stream is a valid `.pcap` a wired Wireshark / tcpdump opens directly. Header-only
11 * and pure (little-endian byte writes, no heap, no stdlib), host-identical.
12 *
13 * @author Douglas Quigg (dstroy0)
14 * @date 2026
15 */
16
17#ifndef PROTOCORE_PCAP_H
18#define PROTOCORE_PCAP_H
19
21#include <stddef.h>
22#include <stdint.h>
23
24/** @brief libpcap header sizes. */
25#define PC_PCAP_GLOBAL_HDR_LEN 24
26#define PC_PCAP_REC_HDR_LEN 16
27
28/** @brief Common libpcap DLT link-layer types. */
29#define PC_DLT_IEEE802_11 105 ///< raw 802.11 (Wi-Fi promiscuous capture)
30#define PC_DLT_CAN_SOCKETCAN 227 ///< Linux SocketCAN classic/FD frames
31#define PC_DLT_ETHERNET 1 ///< IEEE 802.3 Ethernet
32#define PC_DLT_IEEE802_15_4_NOFCS 230 ///< raw 802.15.4 MAC frame, no FCS
33#define PC_DLT_IEEE802_15_4_TAP 283 ///< 802.15.4 with a TAP pseudo-header (RSSI / channel TLVs)
34
35/**
36 * @brief Write the 24-byte libpcap global header (little-endian, microsecond timestamps).
37 * @param linktype the DLT_* link type of the frames that follow (e.g. ::PC_DLT_IEEE802_11).
38 * @return ::PC_PCAP_GLOBAL_HDR_LEN, or 0 if @p cap is too small.
39 */
40inline size_t pc_pcap_global_header(uint8_t *out, size_t cap, uint32_t linktype)
41{
42 if (!out || cap < PC_PCAP_GLOBAL_HDR_LEN)
43 {
44 return 0;
45 }
46 pc_wr32le(out + 0, 0xa1b2c3d4); // magic: usec timestamps, little-endian
47 pc_wr16le(out + 4, 2); // version major
48 pc_wr16le(out + 6, 4); // version minor
49 pc_wr32le(out + 8, 0); // thiszone (GMT)
50 pc_wr32le(out + 12, 0); // sigfigs
51 pc_wr32le(out + 16, 65535); // snaplen
52 pc_wr32le(out + 20, linktype); // network / DLT
54}
55
56/**
57 * @brief Write a 16-byte libpcap record header for one captured frame.
58 * @return ::PC_PCAP_REC_HDR_LEN, or 0 if @p cap is too small.
59 */
60inline size_t pc_pcap_record_header(uint8_t *out, size_t cap, uint32_t ts_sec, uint32_t ts_usec, uint32_t caplen,
61 uint32_t origlen)
62{
63 if (!out || cap < PC_PCAP_REC_HDR_LEN)
64 {
65 return 0;
66 }
67 pc_wr32le(out + 0, ts_sec);
68 pc_wr32le(out + 4, ts_usec);
69 pc_wr32le(out + 8, caplen);
70 pc_wr32le(out + 12, origlen);
72}
73
74#endif // PROTOCORE_PCAP_H
Fixed-width integer serializers into a raw uint8_t* buffer - one source of truth.
size_t pc_wr32le(uint8_t *p, uint32_t v)
Write v little-endian at p.
Definition endian.h:40
size_t pc_wr16le(uint8_t *p, uint16_t v)
Write v little-endian at p.
Definition endian.h:32
#define PC_PCAP_GLOBAL_HDR_LEN
libpcap header sizes.
Definition pcap.h:25
size_t pc_pcap_record_header(uint8_t *out, size_t cap, uint32_t ts_sec, uint32_t ts_usec, uint32_t caplen, uint32_t origlen)
Write a 16-byte libpcap record header for one captured frame.
Definition pcap.h:60
#define PC_PCAP_REC_HDR_LEN
Definition pcap.h:26
size_t pc_pcap_global_header(uint8_t *out, size_t cap, uint32_t linktype)
Write the 24-byte libpcap global header (little-endian, microsecond timestamps).
Definition pcap.h:40