Line data Source code
1 : #ifndef HEADER_fd_src_util_net_fd_pcapng_h 2 : #define HEADER_fd_src_util_net_fd_pcapng_h 3 : 4 : /* pcapng is a file format for packet captures. Incompatible with 5 : classic "tcpdump" pcap as in fd_pcap.h but supports additional 6 : features such as embedded encryption secrets. 7 : 8 : Spec: https://datatracker.ietf.org/doc/draft-ietf-opsawg-pcapng/ 9 : 10 : fd_pcapng only supports little-endian files. All strings in this API 11 : are formatted as UTF-8 (superset of ASCII) and max not exceed 200 12 : char length. All values in "opt" structs are optional, absence 13 : implied by zero unless otherwise stated. 14 : 15 : This library is not optimized for high performance and is thus not 16 : suitable for packet capture at line rate. Parsing API is hardened 17 : against malicious inputs. */ 18 : 19 : #include "../fd_util_base.h" 20 : 21 : /* Opaque handle of a pcapng iterator */ 22 : 23 : struct fd_pcapng_iter; 24 : typedef struct fd_pcapng_iter fd_pcapng_iter_t; 25 : 26 : #define FD_PCAPNG_ITER_ALIGN (32UL) 27 : 28 : /* Section Header Block options */ 29 : 30 : struct fd_pcapng_shb_opts { 31 : char const * hardware; /* Generic name of machine performing capture 32 : e.g. "x86_64 Server" */ 33 : char const * os; /* Operating system or distro name */ 34 : char const * userappl; /* Name of this program (e.g. "Firedancer") */ 35 : }; 36 : typedef struct fd_pcapng_shb_opts fd_pcapng_shb_opts_t; 37 : 38 : /* Interface Description Block options */ 39 : 40 : struct fd_pcapng_idb_opts { 41 : char name[16]; /* Name of network interface in OS */ 42 : uchar ip4_addr[4]; /* IPv4 address in big endian order -- todo support multiple */ 43 : uchar mac_addr[6]; /* MAC address */ 44 : uchar tsresol; /* See FD_PCAPNG_TSRESOL_* */ 45 : char hardware[64]; /* Name of network interface hardware */ 46 : }; 47 : typedef struct fd_pcapng_idb_opts fd_pcapng_idb_opts_t; 48 : 49 : /* Generalized frame read from a pcapng. 50 : Usually a packet but can also be metadata */ 51 : 52 : struct fd_pcapng_idb_desc { 53 : uint link_type; 54 : fd_pcapng_idb_opts_t opts; 55 : }; 56 : typedef struct fd_pcapng_idb_desc fd_pcapng_idb_desc_t; 57 : 58 : struct fd_pcapng_frame { 59 : long ts; /* Time in ns (matches fd_log_wallclock) */ 60 : uint type; /* Packet type */ 61 : uint data_sz; /* Size of data array */ 62 : uint orig_sz; /* Original packet size (>=data_sz) */ 63 : uint if_idx; /* Index of interface */ 64 : fd_pcapng_idb_desc_t const * idb; /* Associated interface (nullable) */ 65 : uchar * data; 66 : }; 67 : typedef struct fd_pcapng_frame fd_pcapng_frame_t; 68 : 69 : /* FD_PCAPNG_TSRESOL_* sets the resolution of a timestamp. */ 70 : 71 15 : #define FD_PCAPNG_TSRESOL_NS ((uchar)0x09) 72 : 73 : /* fd_pcapng_iter iter frame types */ 74 : 75 12 : #define FD_PCAPNG_FRAME_SIMPLE (1U) /* Simple packet type (data only) */ 76 21 : #define FD_PCAPNG_FRAME_ENHANCED (3U) /* Packet with metadata */ 77 3 : #define FD_PCAPNG_FRAME_TLSKEYS (4U) /* TLS keys */ 78 : 79 : FD_PROTOTYPES_BEGIN 80 : 81 : /* Read API ***********************************************************/ 82 : 83 : /* fd_pcap_iter_{align,footprint} return alignment and footprint 84 : requirements of an fd_pcap_iter_t memory region. */ 85 : 86 : FD_FN_CONST ulong 87 : fd_pcapng_iter_align( void ); 88 : 89 : FD_FN_CONST ulong 90 : fd_pcapng_iter_footprint( void ); 91 : 92 : /* fd_pcapng_iter_new creates an iterator suitable for reading a pcapng 93 : file. mem is a non-NULL pointer to a memory region matching align 94 : and footprint requirements. file should be non-NULL handle of a 95 : stream seeked to the first byte of a pcapng section header block 96 : (e.g. on a hosted platform a FILE * of the fopen'd file). Returns 97 : pointer to iter on success (not just a cast of mem) and NULL on 98 : failure (an indeterminant number of bytes in the stream might have 99 : been consumed on failure). */ 100 : 101 : fd_pcapng_iter_t * 102 : fd_pcapng_iter_new( void * mem, 103 : void * file ); 104 : 105 : /* fd_pcapng_iter_delete destroys an fd_pcap_iter_t. Returns the 106 : underlying memory region (not just a cast of iter). The caller 107 : regains ownership of the memory region and stream handle. */ 108 : 109 : void * 110 : fd_pcapng_iter_delete( fd_pcapng_iter_t * iter ); 111 : 112 : /* fd_pcapng_iter_next extracts the next frame from the pcapng stream. 113 : Returns a pointer to the frame descriptor on success and NULL on 114 : failure. Failure reasons include normal end of section (or file), 115 : fread failures, or file corruption. Details of all failures except 116 : normal end-of-file are logged with a warning. Last error code can 117 : be retrieved with fd_pcapng_iter_err. 118 : 119 : On successful return, the return value itself and the frame data 120 : are backed by a thread-local memory region that is valid until delete 121 : or next iter_next. */ 122 : 123 : fd_pcapng_frame_t * 124 : fd_pcapng_iter_next( fd_pcapng_iter_t * iter ); 125 : 126 : /* fd_pcapng_iter_ele returns the current iterator element. */ 127 : 128 : fd_pcapng_frame_t * 129 : fd_pcapng_iter_ele( fd_pcapng_iter_t * iter ); 130 : 131 : /* fd_pcapng_is_pkt returns 1 if given frame (non-NULL) is a regular 132 : captured packet and 0 if it is metadata (such as decryption secrets). */ 133 : 134 : FD_FN_UNUSED FD_FN_PURE static inline int 135 12 : fd_pcapng_is_pkt( fd_pcapng_frame_t const * frame ) { 136 12 : uint ty = frame->type; 137 12 : return (ty==FD_PCAPNG_FRAME_SIMPLE) | (ty==FD_PCAPNG_FRAME_ENHANCED); 138 12 : } 139 : 140 : /* fd_pcapng_iter_err returns the last encountered error. Uses fd_io 141 : error codes. */ 142 : 143 : FD_FN_PURE int 144 : fd_pcapng_iter_err( fd_pcapng_iter_t const * iter ); 145 : 146 : /* Write API **********************************************************/ 147 : 148 : /* fd_pcapng_shb_defaults stores default options for an SHB based on the 149 : system environment into opt. Given opt must be initialized prior to 150 : call. */ 151 : 152 : void 153 : fd_pcapng_shb_defaults( fd_pcapng_shb_opts_t * opt ); 154 : 155 : /* fd_pcapng_fwrite_shb writes a little endian pcapng SHB v1.0 (Section 156 : Header Block) to the stream pointed to by file. Same semantics as 157 : fwrite (returns the number of headers written, which should be 1 on 158 : success and 0 on failure). opt contains options embedded into SHB 159 : and may be NULL. 160 : 161 : The PCAPNG spec requires an SHB v1.0 at the beginning of the file. 162 : Multiple SHBs per file are permitted. An SHB clears any side effects 163 : induced by blocks (such as the timestamp resolution of an IDB). It 164 : is the caller's responsibility to maintain 4 byte alignment for 165 : stream pointer of file. (all functions in this API will write 166 : multiples of 4). 167 : 168 : If SHB is not first of file, this function currently makes no attempt 169 : to fix up the length field of the preceding SHB (may change in the 170 : future). */ 171 : 172 : ulong 173 : fd_pcapng_fwrite_shb( fd_pcapng_shb_opts_t const * opt, 174 : void * file ); 175 : 176 : #if FD_HAS_HOSTED 177 : 178 : /* fd_pcapng_idb_defaults stores default options for an IDB based on the 179 : system environment into opt. if_idx is the operating system's 180 : interface index. (THIS IS UNRELATED TO THE PCAPNG INTERFACE INDEX). 181 : Returns 0 on success and -1 on failure. Reasons for failure are 182 : written to log. On failure, partially writes opt. */ 183 : 184 : int 185 : fd_pcapng_idb_defaults( fd_pcapng_idb_opts_t * opt, 186 : uint if_idx ); 187 : 188 : #endif /* FD_HAS_HOSTED */ 189 : 190 : /* fd_pcapng_fwrite_idb writes an IDB (Interface Description Block) to 191 : the stream pointed to by file. Usually a successor of an SHB. Refer 192 : to fd_pcapng_fwrite_shb for use of opt, file args. link_type is one 193 : of FD_PCAPNG_LINKTYPE_*. opt->tsresol is ignored. fd_pcapng always 194 : writes TSRESOL==9 (nanoseconds). */ 195 : 196 : /* FD_PCAPNG_LINKTYPE_*: Link types (currently only Ethernet supported) */ 197 : 198 0 : #define FD_PCAPNG_LINKTYPE_ETHERNET (1U) /* IEEE 802.3 Ethernet */ 199 0 : #define FD_PCAPNG_LINKTYPE_RAW (101U) /* IPv4 or IPv6 */ 200 0 : #define FD_PCAPNG_LINKTYPE_COOKED (113U) /* Linux "cooked" capture */ 201 0 : #define FD_PCAPNG_LINKTYPE_USER0 (147U) /* DLT_USER0 */ 202 0 : #define FD_PCAPNG_LINKTYPE_IPV4 (228U) /* IPv4 */ 203 : 204 : ulong 205 : fd_pcapng_fwrite_idb( uint link_type, 206 : fd_pcapng_idb_opts_t const * opt, 207 : void * file ); 208 : 209 : /* fd_pcapng_fwrite_pkt writes an EPB (Enhanced Packet Block) containing 210 : an ethernet frame at time ts (in nanos). Same semantics as fwrite 211 : (returns the number of packets written, which should be 1 on success 212 : and 0 on failure). */ 213 : 214 : ulong 215 : fd_pcapng_fwrite_pkt1( void * file, 216 : void const * payload, 217 : ulong payload_sz, 218 : void const * options, 219 : ulong options_sz, 220 : uint if_idx, 221 : long ts ); 222 : 223 : static inline ulong 224 : fd_pcapng_fwrite_pkt( long ts, 225 : void const * payload, 226 : ulong payload_sz, 227 12 : void * file ) { 228 : return fd_pcapng_fwrite_pkt1( file, payload, payload_sz, NULL, 0UL, 0U, ts ); 229 12 : } 230 : 231 : /* fd_pcapng_fwrite_tls_key_log writes TLS key log info to a PCAPNG via 232 : a DSB (Decryption Secrets Block). Similar semantics to fwrite 233 : (returns 1 on success and 0 on failure, but will dispatch multiple 234 : fwrite calls internally). log points to first byte of NSS key log 235 : in ASCII format. log_sz is byte size of log. */ 236 : 237 : ulong 238 : fd_pcapng_fwrite_tls_key_log( uchar const * log, 239 : uint log_sz, 240 : void * file ); 241 : 242 : FD_PROTOTYPES_END 243 : 244 : #endif /* HEADER_fd_src_util_net_fd_pcapng_h */