Line data Source code
1 : #ifndef HEADER_fd_src_util_net_fd_pcap_h 2 : #define HEADER_fd_src_util_net_fd_pcap_h 3 : 4 : #include "../log/fd_log.h" 5 : #include "fd_eth.h" 6 : 7 0 : #define FD_PCAP_ITER_TYPE_ETHERNET (0UL) 8 0 : #define FD_PCAP_ITER_TYPE_COOKED (1UL) 9 : 10 : #define FD_PCAP_LINK_LAYER_ETHERNET ( 1U) 11 : #define FD_PCAP_LINK_LAYER_USER0 (147U) 12 : 13 : /* Opaque handle of a pcap iterator */ 14 : 15 : struct fd_pcap_iter; 16 : typedef struct fd_pcap_iter fd_pcap_iter_t; 17 : 18 : FD_PROTOTYPES_BEGIN 19 : 20 : /* fd_pcap_iter_new creates an iterator suitable for reading a pcap 21 : file. file should be non-NULL handle of a stream seeked to the first 22 : byte of the pcap file (e.g. on a hosted platform a FILE * of the 23 : fopen'd file). Returns file on success (the pcap_iter will have 24 : ownership of the file stream) and NULL on failure (an indeterminant 25 : number of bytes in the stream might have been consumed on failure). */ 26 : 27 : fd_pcap_iter_t * 28 : fd_pcap_iter_new( void * file ); 29 : 30 : /* fd_pcap_iter_file returns the file stream of the pcap file being 31 : iterated over. fd_pcap_iter_type returns the type of pcap file being 32 : iterated over (return value will be a FD_PCAP_ITER_TYPE_*). Assumes 33 : iter is a current iterator and the iterator is unchanged. No bytes 34 : in the underlying stream are consumed. */ 35 : 36 1443 : FD_FN_CONST static inline void * fd_pcap_iter_file( fd_pcap_iter_t * iter ) { return (void *)(((ulong)iter) & ~1UL); } 37 1440 : FD_FN_CONST static inline ulong fd_pcap_iter_type( fd_pcap_iter_t * iter ) { return ((ulong)iter) & 1UL; } 38 : 39 : /* fd_pcap_iter_delete destroys a fd_pcap_iter_t. Returns the handle of 40 : the underlying stream; the caller has ownership of the stream. */ 41 : 42 3 : FD_FN_CONST static inline void * fd_pcap_iter_delete( fd_pcap_iter_t * iter ) { return fd_pcap_iter_file( iter ); } 43 : 44 : /* fd_pcap_iter_next extracts the next packet from the pcap stream. 45 : Returns pkt_sz the number of bytes in the packet on success and 0 on 46 : on failure. Failure reasons include normal end-of-file, fread 47 : failures, pcap file corruption, pcap file contains truncated packets 48 : and pkt_max is too small for pkt_sz. Details of all failures except 49 : normal end-of-file are logged with a warning. 50 : 51 : On a successful return, the memory region pointed to by pkt will 52 : contain the pkt_sz bytes of the extracted packet starting from the 53 : first byte of Ethernet header to the last byte of whatever was 54 : captured for that packet (e.g. the last byte of the Ethernet payload, 55 : the last byte of the Ethernet FCS, etc). *_pkt_ts will contain the 56 : packet timestamp (assumes that the pcap captured at nanosecond 57 : resolution). The iterator's underlying stream pointer will be 58 : advanced exactly on pcap pkt (and the underlying stream will have 59 : consumed bytes up to the next pkt). If iterating over over a cooked 60 : capture, pkt will have use a phony Ethernet header with no VLAN 61 : tagging that mangles cooked sll dir/ha_type/ha_len fields into the 62 : dst mac and the ha into the src mac). 63 : 64 : On a failed return, pkt and pkt_ts are untouched. If not a normal 65 : EOF, the iterator's underlying stream may have consumed an 66 : indeterminant number of bytes. */ 67 : 68 : ulong 69 : fd_pcap_iter_next( fd_pcap_iter_t * iter, 70 : void * pkt, 71 : ulong pkt_max, 72 : long * _pkt_ts ); 73 : 74 : /* fd_pcap_iter_next extracts the next packet from the pcap stream, 75 : placing the packet headers in one output buffer and the packet 76 : payload in another output buffer. Returns 1 on success and 0 on 77 : failure. Failure reasons include normal end-of-file, fread failures, 78 : pcap file corruption, pcap file contains truncated packets, 79 : hdr_sz is too small for the packet's headers, and pld_sz is too small 80 : for the packet's payload. Details of all failures except normal 81 : end-of-file are logged with a warning. 82 : 83 : For the purposes of this function, Ethernet, IPv4 and UDP headers are 84 : the only ones that are recognized as headers. This function 85 : considers all bytes not part of one of the listed header types as 86 : payload. 87 : 88 : When the function is called, hdr_buf must point the first byte of a 89 : *hdr_sz byte-sized region of writable memory, and pld_buf must point 90 : to the first byte of a *pld_sz byte-sized region of writable memory. 91 : 92 : On successful return, the memory regions pointed to by hdr_buf and 93 : pld_buf will respectively contain the packet's headers (starting with 94 : the first byte of the Ethernet header) and the packet's payload 95 : (ending with whatever was captured for that packet, which could 96 : potentially include the Ethernet FCS). The iterator's underlying 97 : stream will advance one packet. 98 : The ulongs pointed to by hdr_sz and pld_sz will be updated with the 99 : number of bytes written to hdr_buf and pld_buf, respectively. 100 : *_pkt_ts will contain the packet timestamp (assumes that the pcap 101 : captured at nanosecond resolution). 102 : 103 : 104 : If the underlying stream is at EOF when this function is called, it 105 : will return 0, but not modify the contents of hdr_buf or pld_buf. In 106 : other failure cases, an indeterminate number of bytes between 0 and 107 : *{hdr,pld}_sz bytes, inclusive, may be written to {hdr,pld}_buf, 108 : respectively. */ 109 : int 110 : fd_pcap_iter_next_split( fd_pcap_iter_t * iter, 111 : void * hdr_buf, 112 : ulong * hdr_sz, 113 : void * pld_buf, 114 : ulong * pld_sz, 115 : long * _pkt_ts ); 116 : 117 : /* fd_pcap_fwrite_hdr write a little endian 2.4 pcap header to the 118 : stream pointed to by file. link_layer_type should be one of the 119 : FD_PCAP_LINK_LAYER_* values defined above. Same semantics as fwrite 120 : (returns number of headers written, which should be 1 on success and 121 : 0 on failure). */ 122 : 123 : ulong 124 : fd_pcap_fwrite_hdr( void * file, 125 : uint link_layer_type ); 126 : 127 : /* fd_pcap_fwrite_pkt writes the pcap ethernet frame formed by 128 : concatenating hdr/payload/fcs to appropriate for a pcap file at time 129 : ts (will be encoded with ns resolution). hdr should start on the 130 : first byte of the Ethernet header and payload should end on the last 131 : byte of the Ethernet payloaded. For normal (uncorrupted) frames: 132 : 133 : _fcs = fd_eth_fcs_append( fd_eth_fcs( _hdr, hdr_sz ), _payload, _payload_sz ) 134 : 135 : Same semantics as fwrite: returns number of packets written -> 1 on 136 : success and 0 on failure (logs details on failure). */ 137 : 138 : ulong 139 : fd_pcap_fwrite_pkt( long ts, 140 : void const * _hdr, 141 : ulong hdr_sz, 142 : void const * _payload, 143 : ulong payload_sz, 144 : uint _fcs, 145 : void * file ); 146 : 147 : FD_PROTOTYPES_END 148 : 149 : #endif /* HEADER_fd_src_util_net_fd_pcap_h */ 150 :