1 /** @internal
2  **
3  **
4  ** @file fbcollector.h
5  ** IPFIX Collecting Process single transport session implementation
6  **
7  ** ------------------------------------------------------------------------
8  ** Copyright (C) 2006-2019 Carnegie Mellon University. All Rights Reserved.
9  ** ------------------------------------------------------------------------
10  ** Authors: Brian Trammell
11  ** ------------------------------------------------------------------------
12  ** @OPENSOURCE_LICENSE_START@
13  ** libfixbuf 2.0
14  **
15  ** Copyright 2018-2019 Carnegie Mellon University. All Rights Reserved.
16  **
17  ** NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
18  ** ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS"
19  ** BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND,
20  ** EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT
21  ** LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY,
22  ** EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE
23  ** MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF
24  ** ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR
25  ** COPYRIGHT INFRINGEMENT.
26  **
27  ** Released under a GNU-Lesser GPL 3.0-style license, please see
28  ** LICENSE.txt or contact permission@sei.cmu.edu for full terms.
29  **
30  ** [DISTRIBUTION STATEMENT A] This material has been approved for
31  ** public release and unlimited distribution.  Please see Copyright
32  ** notice for non-US Government use and distribution.
33  **
34  ** Carnegie Mellon(R) and CERT(R) are registered in the U.S. Patent
35  ** and Trademark Office by Carnegie Mellon University.
36  **
37  ** DM18-0325
38  ** @OPENSOURCE_LICENSE_END@
39  ** ------------------------------------------------------------------------
40  */
41 
42 
43 
44 #ifndef FB_COLLECTOR_H_
45 #define FB_COLLECTOR_H_
46 
47 #define _FIXBUF_SOURCE_
48 #include <fixbuf/public.h>
49 
50 
51 /* 30 mins in seconds */
52 #define FB_UDP_TIMEOUT 1800
53 
54 
55 /**
56  * fbCollectorClose_fn
57  *
58  * the close function for a given collector; it is transport
59  * specific
60  *
61  * @param collector the handle to the collecting process
62  *
63  */
64 typedef void        (*fbCollectorClose_fn)(
65     fbCollector_t               *collector);
66 
67 
68 
69 /** structure definition of the start of IPFIX & NetFlow messages */
70 typedef struct fbCollectorMsgVL_st {
71     uint16_t                    n_version;
72     uint16_t                    n_len;
73 } fbCollectorMsgVL_t;
74 
75 
76 /**
77  * fbCollectorClearTranslator
78  *
79  * After setting an input translator for a collector, this function clears
80  * that operation.  The collector, after this call, will again operate as
81  * an IPFIX collector.
82  *
83  * @param collector a collecting process endpoint.
84  * @param err An error message set on return when an error occurs
85  *
86  * @return TRUE on success, FALSE on error
87  */
88 gboolean    fbCollectorClearTranslator(
89     fbCollector_t   *collector,
90     GError          **err);
91 
92 
93 /**
94  * fbCollectorPostProc_fn
95  *
96  * The defines the function for the post processing function for
97  * implementing a translator to IPFIX.  This gets called after
98  * a PDU for the protocol is read.
99  *
100  * @param collector a collecting process endpoint
101  * @param dataBuf a pointer to the PDU body
102  * @param err An error message set on return when an error occurs
103  *
104  * @return TRUE of success, FALSE on error
105  */
106 typedef gboolean    (*fbCollectorPostProc_fn)(
107     fbCollector_t               *collector,
108     uint8_t                     *dataBuf,
109     size_t                      *bufLen,
110     GError                      **err);
111 
112 
113 /**
114  * fbCollectorVLMessageSize_fn
115  *
116  * This function returns the size of the PDU for a read.  It is
117  * specific to the protocol to be translated.
118  *
119  * @param collector a collecting process endpoint
120  * @param hdr a pointer to the IPFIX header (although can be cast
121  *            into a uint8_t * and used as a pointer into the
122  *            buffer)
123  * @param b_len the length of the header just read in
124  * @param m_len a return value with the length of the PDU to be read
125  * @param err An error message set on the return when an error occurs
126  *
127  * @return TRUE on success, FALSE on error
128  */
129 typedef gboolean    (*fbCollectorVLMessageSize_fn)(
130     fbCollector_t               *collector,
131     fbCollectorMsgVL_t          *hdr,
132     size_t                      b_len,
133     uint16_t                    *m_len,
134     GError                      **err);
135 
136 /**
137  * fbCollectorMessageHeader_fn
138  *
139  * This function is called for message based read channels when the
140  * fbCollectorVLMessageSize_fn is not called.  (UDP & SCTP)  TCP &
141  * files are read as streams and the concept of a PDU doesn't exist
142  * in the same fashion as message based protocols.  This function
143  * reconstructs the header of a message in order for it to be workable
144  * with the fbCollectorPostProc_fn.
145  *
146  * Or you could view it this way, this function is the result of taking
147  * an optimization in fbCollectorVLMessageSize_fn which modifies the
148  * header in order to avoid a mempy.  This is where the memcpy happens
149  * if you don't call fbCollectorVLMessageSize_fn.  (At least for NetFlow
150  * V9.)
151  *
152  * @param collector pointer to the collector state structure
153  * @param buffer pointer to the raw data buffer
154  * @param b_len length of the buffer passed in
155  * @param m_len length of the message on output (might be different
156  *              than b_len from transformations made here)
157  * @param err An error message set on return if an error occurs
158  *
159  * @return TRUE on success, FALSE on error (check err)
160  *
161  */
162 typedef gboolean    (*fbCollectorMessageHeader_fn)(
163     fbCollector_t               *collector,
164     uint8_t                     *buffer,
165     size_t                      b_len,
166     uint16_t                    *m_len,
167     GError                      **err);
168 
169 /**
170  * fbCollectorTransClose_fn
171  *
172  * This is called to cleanup any translator state when a collector
173  * with a translator is closed.
174  *
175  * @param collector a collecting process endpoint
176  *
177  */
178 typedef void        (*fbCollectorTransClose_fn)(
179     fbCollector_t               *collector);
180 
181 
182 /**
183  * fbCollectorSessionTimeout_fn
184  *
185  * This is the definition of the function the collector calls when it
186  * times out a UDP session.  It needs to be a function pointer to allow
187  * translators the ability to free any state that is associated with
188  * the timed out session.
189  *
190  * @param collector pointer to collector
191  * @param session pointer to session that is being timed out
192  *
193 */
194 typedef void (*fbCollectorSessionTimeout_fn)(
195     fbCollector_t                *collector,
196     fbSession_t                  *session);
197 
198 
199 /**
200  * fbCollectorSetTranslator
201  *
202  * This sets a translator on the given collecting process.  There are various
203  * function points that need to be set in order to implement a collector that
204  * can read something other than IPFIX, e.g. NetFlow.  Not all functions need
205  * to be reimplemented, depending on the protocol to be adapted, however, a
206  * valid function pointer needs to be provided for each function.  The
207  * fbcollector and fbnetflow source code can provide more detailed example
208  * and information about the exact implementation.
209  *
210  * @param collector a collecting process endpoint
211  * @param postProcFunc a function that gets called after a pdu has been read
212  *                     so that any necessary transformations may occur
213  * @param vlMessageFunc this function is used to determine how large a single
214  *                      read should be from the file/network handle; it should
215  *                      return a whole PDU if possible
216  * @param headerFunc function to transform the header after a block read before
217  *                      it is sent to the postProcFunc (called when
218  *                      vlMessageFunc isn't)
219  * @param trCloseFunc this function gets called when the collector gets closed
220  *                    to clean up any data, etc. that the the translator
221  *                    requires
222  * @param timeOutFunc this function gets called when the collector times out
223  *                    UDP sessions, so it can clear any related state.
224  * @param opaque the fixbuf standard collector code will not look at this
225  *               pointer.  The translator can use this and retrieve it from
226  *               the collector structure as needed during its operation
227  * @param err An error message set on return when an error occurs
228  *
229  * @return TRUE on success, FALSE on error
230  */
231 gboolean    fbCollectorSetTranslator(
232     fbCollector_t                *collector,
233     fbCollectorPostProc_fn       postProcFunc,
234     fbCollectorVLMessageSize_fn  vlMessageFunc,
235     fbCollectorMessageHeader_fn  headerFunc,
236     fbCollectorTransClose_fn     trCloseFunc,
237     fbCollectorSessionTimeout_fn timeOutFunc,
238     void                         *opaque,
239     GError                       **err);
240 
241 
242 /**
243  * fbCollectorRead_fn
244  *
245  * This is the definition of the read function the collector calls in order
246  * to read a PDU from the stream/file.  It is defined as a function pointer
247  * to be able to accomodate the various different connection types supported
248  * by fixbuf.
249  *
250  * @param collector a collecting process endpoint
251  * @param msgbase the buffer to store the PDU in
252  * @param msglen the length of the PDU stored in msgbase
253  * @param err An error message set on return of a failure
254  *
255  * @return TRUE on success, FALSE on error
256  *
257  */
258 typedef gboolean    (*fbCollectorRead_fn)(
259     fbCollector_t               *collector,
260     uint8_t                     *msgbase,
261     size_t                      *msglen,
262     GError                      **err);
263 
264 
265 struct fbCollector_st {
266     /** Listener from which this Collector was created. */
267     fbListener_t                *listener;
268     /**
269      * Application context. Created and owned by the application
270      * when the listener calls the <new collector> callback.
271      */
272     void                        *ctx;
273     /** Cached peer address. Filled in at allocation time */
274     union {
275         struct sockaddr         so;
276         struct sockaddr_in      ip4;
277         struct sockaddr_in6     ip6;
278     }                           peer;
279     /** Current export stream */
280     union {
281         /** Buffered file pointer, for file transport */
282         FILE                    *fp;
283         /**
284          * Unbuffered socket, for SCTP, TCP, or UDP transport.
285          * Also used as base socket for TLS and DTLS support.
286          */
287         int                     fd;
288 #if HAVE_SPREAD
289         fbSpreadSpec_t *        spread;
290 #endif
291     }                           stream;
292 
293     /**
294      * Interrupt pipe read end file descriptor.
295      * Used to unblock a call to fbListenerWait().
296      */
297     int                         rip;
298     /**
299      * Interrupt pipe write end file descriptor.
300      * Used to unblock a call to fbListenerWait().
301      */
302     int                         wip;
303     gboolean                    bufferedStream;
304     gboolean                    translationActive;
305     gboolean                    active;
306     gboolean                    accept_only;
307     gboolean                    multi_session;
308     uint32_t                    obdomain;
309     time_t                      time;
310 #if HAVE_OPENSSL
311     /** OpenSSL socket, for TLS or DTLS over the socket in fd. */
312     SSL                         *ssl;
313 #endif
314 #if HAVE_SPREAD
315     /** Need something to distinguish collectors if we have spread but don't
316         use it */
317     uint8_t                    spread_active;
318 #endif
319     fbCollectorRead_fn          coread;
320     fbCollectorVLMessageSize_fn coreadLen;
321     fbCollectorPostProc_fn      copostRead;
322     fbCollectorMessageHeader_fn comsgHeader;
323     fbCollectorClose_fn         coclose;
324     fbCollectorTransClose_fn    cotransClose;
325     fbCollectorSessionTimeout_fn cotimeOut;
326     void                        *translatorState;
327     fbUDPConnSpec_t             *udp_head;
328     fbUDPConnSpec_t             *udp_tail;
329 };
330 
331 #endif
332