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_ostream_hdr behaves exactly like fd_pcap_fwrite_hdr except
128 : that the data is written to a fd_io_buffered_ostream_t stream.
129 : Returns nonzero on failure. */
130 :
131 : int
132 : fd_pcap_ostream_hdr( fd_io_buffered_ostream_t * out,
133 : uint link_layer_type );
134 :
135 : /* fd_pcap_pkt_sz returns the number of bytes needed to write a pcap
136 : entry for the given hdr_sz + payload_sz. Returns a negative number
137 : if the given hdr/payload are too large for the pcap file. */
138 :
139 : long
140 : fd_pcap_pkt_sz( ulong hdr_sz,
141 : ulong payload_sz );
142 :
143 : /* fd_pcap_pkt writes the pcap ethernet frame formed by concatenating
144 : hdr/payload/fcs as appropriate for a pcap file at time ts (will be
145 : encoded with ns resolution). hdr should start on the first byte of
146 : the Ethernet header and payload should end on the last byte of the
147 : Ethernet payload. For normal (uncorrupted) frames:
148 :
149 : _fcs = fd_eth_fcs_append( fd_eth_fcs( _hdr, hdr_sz ), _payload, _payload_sz )
150 :
151 : The resulting pcap entry is written to the given pointer, which must
152 : have at least fd_pcap_pkt_sz( hdr_sz, payload_sz ) bytes of free
153 : space to write into. Returns pcap entry size on success and negative
154 : on failure. */
155 :
156 : long
157 : fd_pcap_pkt( void * out,
158 : long ts,
159 : void const * _hdr,
160 : ulong hdr_sz,
161 : void const * _payload,
162 : ulong payload_sz,
163 : uint _fcs );
164 :
165 : /* fd_pcap_fwrite_pkt behaves like fd_pcap_pkt except that it writes
166 : data to the stream pointed to by file.
167 :
168 : Same semantics as fwrite: returns number of packets written -> 1 on
169 : success and 0 on failure (logs details on failure). */
170 :
171 : ulong
172 : fd_pcap_fwrite_pkt( long ts,
173 : void const * _hdr,
174 : ulong hdr_sz,
175 : void const * _payload,
176 : ulong payload_sz,
177 : uint _fcs,
178 : void * file );
179 :
180 : /* fd_pcap_ostream_pkt behaves like fd_pcap_pkt except that it writes
181 : data to a fd_io_buffered_ostream_t stream. Returns nonzero on
182 : failure. */
183 :
184 : int
185 : fd_pcap_ostream_pkt( fd_io_buffered_ostream_t * out,
186 : long ts,
187 : void const * _hdr,
188 : ulong hdr_sz,
189 : void const * _payload,
190 : ulong payload_sz,
191 : uint _fcs );
192 :
193 : FD_PROTOTYPES_END
194 :
195 : #endif /* HEADER_fd_src_util_net_fd_pcap_h */
196 :
|