1 /*
2  ** public.h
3  ** fixbuf IPFIX Implementation Public Interface
4  **
5  ** ------------------------------------------------------------------------
6  ** Copyright (C) 2006-2019 Carnegie Mellon University. All Rights Reserved.
7  ** ------------------------------------------------------------------------
8  ** Authors: Brian Trammell, Dan Ruef
9  ** ------------------------------------------------------------------------
10  ** @OPENSOURCE_LICENSE_START@
11  ** libfixbuf 2.0
12  **
13  ** Copyright 2018-2019 Carnegie Mellon University. All Rights Reserved.
14  **
15  ** NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
16  ** ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS"
17  ** BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND,
18  ** EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT
19  ** LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY,
20  ** EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE
21  ** MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF
22  ** ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR
23  ** COPYRIGHT INFRINGEMENT.
24  **
25  ** Released under a GNU-Lesser GPL 3.0-style license, please see
26  ** LICENSE.txt or contact permission@sei.cmu.edu for full terms.
27  **
28  ** [DISTRIBUTION STATEMENT A] This material has been approved for
29  ** public release and unlimited distribution.  Please see Copyright
30  ** notice for non-US Government use and distribution.
31  **
32  ** Carnegie Mellon(R) and CERT(R) are registered in the U.S. Patent
33  ** and Trademark Office by Carnegie Mellon University.
34  **
35  ** DM18-0325
36  ** @OPENSOURCE_LICENSE_END@
37  **
38  ** ------------------------------------------------------------------------
39  */
40 
41 /**
42  * @mainpage libfixbuf - IPFIX Protocol Library
43  *
44  * \subpage How-To
45  *
46  * @section Introduction
47  *
48  * libfixbuf is a compliant implementation of the IPFIX Protocol,
49  * as defined in the "Specification of the IPFIX Protocol for the Exchange of
50  * Flow Information" ([RFC 7011][]). It supports the information model
51  * defined in "Information Model for IP Flow Information Export"
52  * ([RFC 7012][]), extended as proposed by "Bidirectional Flow Export using
53  * IPFIX" ([RFC 5103][]) to support information elements for representing
54  * biflows.  libfixbuf supports structured data elements as described
55  * in "Export of Structured Data in IPFIX" ([RFC 6313][]), which adds the
56  * ability to export basicLists, subTemplateLists, and subTemplateMultiLists.
57  * libfixbuf can export type information for IPFIX
58  * elements as described in "Exporting Type Information for IPFIX Information
59  * Elements" ([RFC 5610][]), and it supports reading this information.
60  *
61  * libfixbuf supports UDP, TCP, SCTP, TLS over TCP, and Spread as transport
62  * protocols. Support for DTLS over UDP and DTLS over SCTP is forthcoming.
63  * It also supports operation as an IPFIX File Writer or IPFIX File Reader as
64  * defined in "Specification of the IPFIX File Format" ([RFC 5655][]).
65  *
66  * libfixbuf's public API is defined in public.h; see the \ref How-To section
67  * or public.h for general documentation on getting started with libfixbuf, as
68  * well as detailed documentation on the public API calls and data types.
69  *
70  * [ipfixDump][] is a command line tool for printing the contents of
71  * an IPFIX file as text.  As of libfixbuf-2.3.0, ipfixDump is
72  * distributed with libfixbuf.  (Previously it was distributed with
73  * [YAF][].)
74  *
75  * A Python API to libfixbuf is available in the [pyfixbuf][] package,
76  * distributed separately.
77  *
78  * [RFC 5103]:  https://tools.ietf.org/html/rfc5103
79  * [RFC 5610]:  https://tools.ietf.org/html/rfc5610
80  * [RFC 5655]:  https://tools.ietf.org/html/rfc5655
81  * [RFC 6313]:  https://tools.ietf.org/html/rfc6313
82  * [RFC 7011]:  https://tools.ietf.org/html/rfc7011
83  * [RFC 7012]:  https://tools.ietf.org/html/rfc7012
84  * [YAF]:       https://tools.netsa.cert.org/YAF/index.html
85  * [ipfixDump]: https://tools.netsa.cert.org/fixbuf/ipfixDump.html
86  * [pyfixbuf]:  https://tools.netsa.cert.org/pyfixbuf/index.html
87  *
88  * @section Downloading
89  *
90  * libfixbuf is distributed from
91  * https://tools.netsa.cert.org/fixbuf/download.html
92  *
93  * @section Building
94  *
95  * libfixbuf uses a reasonably standard autotools-based build system.
96  * The customary build procedure (`./configure && make && make install`)
97  * should work in most environments.
98  *
99  * The ipfixDump application, its manual page, and a support file
100  * (`cert_ipfix.xml`) are built and installed by default (as of
101  * libfixbuf-2.3.0).  Use --disable-tools to bulid and install the libfixbuf
102  * library only.
103  *
104  * libfixbuf requires [GLib-2.0][] version 2.18 or later. GLib is available on
105  * most modern Linux distributions and BSD ports collections or in
106  * [source form][].
107  *
108  * libfixbuf automatically uses the getaddrinfo(3) facility and the
109  * accompanying dual IPv4/IPv6 stack support if present. getaddrinfo(3)
110  * must be present to export or collect flows over IPv6.
111  *
112  * libfixbuf does not build with SCTP support by default. The --with-sctp
113  * option must be given to the libfixbuf ./configure script to include SCTP
114  * support. Also note that SCTP requires kernel support, and applications
115  * built against libfixbuf with libsctp may fail at runtime if that kernel
116  * support is not present.
117  *
118  * libfixbuf does not build with TLS support by default. The --with-openssl
119  * option must be given to the libfixbuf ./configure script to include TLS
120  * support.
121  *
122  * Spread support requires [Spread][] 4.1 or
123  * later. libfixbuf does not build with Spread support by default.
124  * The --with-spread option must be given to libfixbuf ./configure script to
125  * include Spread support.
126  *
127  * [GLib-2.0]:     https://developer.gnome.org/glib/stable/
128  * [Spread]:       http://www.spread.org/
129  * [source form]:  https://download.gnome.org/sources/glib/
130  *
131  * @section Known Issues
132  *
133  * The following are known issues with libfixbuf as of version 1.0.0:
134  *
135  *   - There is no support for DTLS over UDP or DTLS over SCTP transport.
136  *   - There is no support for application-selectable SCTP stream assignment
137  *     or SCTP partial reliability. Templates are sent reliably on stream 0,
138  *     and data sets are sent reliably on stream 1.
139  *   - There is no automatic support for periodic template retransmission
140  *     or periodic template expiration as required when transporting IPFIX
141  *     over UDP. Applications using libfixbuf to transport IPFIX messages
142  *     over UDP must maintain these timeouts and manually manage the session.
143  *     However, inactive UDP collector sessions are timed out after 30 minutes,
144  *     at which time the session is freed and all templates associated with the
145  *     session are removed.
146  *
147  * @section Copyright
148  *
149  * libfixbuf is copyright 2005-2019 Carnegie Mellon University, and is released
150  * under the GNU Lesser General Public License (LGPL) Version 3.
151  * See the LICENSE.txt file in the distribution for details.
152  *
153  * libfixbuf was developed at Carnegie Mellon University
154  * by Brian Trammell and the CERT Network Situational Awareness Group
155  * Engineering Team for use in the YAF and SiLK tools.
156  *
157  */
158 
159 /**
160  *
161  * @page How-To Getting started with libfixbuf
162  *
163  * Include fixbuf/public.h
164  * in order to use the public fixbuf API.
165  *
166  * This documentation uses IPFIX terminology as defined in [RFC 7011][],
167  * "Specification of the IPFIX Protocol for the Exchange of Flow
168  * Information"
169  *
170  * The following sections provide information on specific libfixbuf usage:
171  *
172  * - \ref export Exporters
173  * - \ref read  IPFIX File Collectors
174  * - \ref collect Network Collectors
175  * - \ref udp UDP Collectors
176  * - \ref v9 NetFlow v9 Collectors
177  * - \ref sflow sFlow Collectors
178  * - \ref spread Spread Collectors
179  * - \ref noconnect Connection-less collector
180  * - \ref lists BasicLists, SubTemplateLists, SubTemplateMultiLists
181  * - \ref rfc_5610 RFC 5610
182  *
183  * @section types Data Types
184  *
185  * public.h defines the data types and routines required to support IPFIX
186  * Exporting Process and IPFIX Collecting Process creation. Each data type is
187  * manipulated primarily by routines named "fb" followed by the type name
188  * (e.g., "Session", "Collector") followed by a description of the routine's
189  * action. The routines operating on the fBuf_t IPFIX Message buffer type are
190  * named beginning with "fBuf".
191  *
192  * The @ref fBuf_t opaque type implements a transcoding IPFIX Message buffer
193  * for both export and collection, and is the "core" interface to the fixbuf
194  * library.
195  *
196  * The @ref fbInfoModel_t opaque type implements an IPFIX Information Model,
197  * including both [IANA managed][] Information Elements and vendor-specific
198  * Information Elements. The @ref fbTemplate_t opaque type implements an IPFIX
199  * Template or an IPFIX Options Template. Both are defined in terms of
200  * Information Elements, represented by the @ref fbInfoElement_t public type.
201  * An fBuf_t message buffer maintains internal Templates, which represent
202  * records within the fixbuf application client, and external Templates,
203  * which represent records as they appear on the wire, for use during
204  * transcoding. For a Spread Exporter, Templates are managed per group.  For
205  * a Spread Collector, Templates are managed per Session.
206  *
207  * The state of an IPFIX Transport Session, including IPFIX Message Sequence
208  * Number tracking and the internal and external Templates in use within the
209  * Session, are maintained by the @ref fbSession_t opaque type.
210  *
211  * An Exporting Process' connection to its corresponding Collecting Process is
212  * encapsulated by the @ref fbExporter_t opaque type. Exporters may be created
213  * to connect via the network using one of the supported IPFIX transport
214  * protocols, or to write to IPFIX Files specified by name or by open ANSI C
215  * file pointer.
216  *
217  * A Collecting Process' connection to a corresponding Exporting Process is
218  * encapsulated by the @ref fbCollector_t opaque type. The passive connection
219  * used to listen for connections from Exporting Processes is managed by the
220  * @ref fbListener_t opaque type; Collectors can be made to read from IPFIX
221  * Files specified directly by name or by open ANSI C file pointer, as well.
222  *
223  * Network addresses are specified for Exporters, Collectors, and Listeners
224  * using the @ref fbConnSpec_t and @ref fbTransport_t public types.
225  *
226  * This file also defines the GError error codes used by all the fixbuf types
227  * and routines within the FB_ERROR_DOMAIN domain.
228  *
229  * [IANA managed]: https://www.iana.org/assignments/ipfix/ipfix.xhtml
230  * [RFC 7011]:     https://tools.ietf.org/html/rfc7011
231  *
232  * @page export Exporter Usage
233  *
234  * How-To Export IPFIX:
235  * Each fixbuf application must have a single fbInfoModel_t instance that
236  * represents the Information Elements that the application understands.
237  * The fbInfoModelAlloc() call allocates a new Information Model with the
238  * IANA-managed information elements (current as of the fixbuf release date)
239  * preloaded. Additional vendor-specific information elements may be added
240  * with fbInfoModelAddElement(), fbInfoModelAddElementArray(),
241  * fbInfoModelReadXMLFile(), and fbInfoModelReadXMLData().
242  *
243  * To create an Exporter, first create an @ref fbSession_t attached to the
244  * application's @ref fbInfoModel_t to hold the Exporter's Transport Session
245  * state using fbSessionAlloc(). If exporting via the Spread protocol, create
246  * an @ref fbSpreadParams_t and set its session to your newly defined session,
247  * group names (a null terminated array), and Spread daemon name.
248  *
249  * Then create an @ref fbExporter_t to encapsulate the connection to the
250  * Collecting Process or the file on disk, using the fbExporterAllocFP(),
251  * fbExporterAllocFile(), fbExporterAllocNet(), fbExporterAllocBuffer(),
252  * or fbExporterAllocSpread() calls.
253  *
254  * With an fbSession_t and an fbExporter_t available, create a buffer for
255  * writing via fBufAllocForExport().
256  *
257  * Create and populate templates for addition to this session using the
258  * fbTemplate calls, then add them to the session via fbSessionAddTemplate()
259  * or fbSessionAddTemplateWithMetadata().
260  *
261  * If exporting via Spread, before calling fbSessionAddTemplate(), set the
262  * group that should receive this template with the fBufSetSpreadExportGroup()
263  * call.  If more than 1 group should receive the template, use the
264  * fbSessionAddTemplatesMulticast() which will call fBufSetSpreadExportGroup()
265  * on the given group(s) multicast the template to the given group(s).
266  * For Spread, do not use fbSessionAddTemplate() to send to multiple groups.
267  *
268  * Once the templates have been added to the session, use
269  * fbSessionExportTemplates() to add the templates to the buffer and then
270  * set the internal and external template IDs with fBufSetInternalTemplate()
271  * and fBufSetExportTemplate().  You can then use fBufAppend() to write
272  * records into IPFIX Messages and Messages to the output stream.
273  *
274  * If using Spread, call fBufSetSpreadExportGroup() to set the groups to
275  * export to on the buffer before calling fBufAppend().
276  *
277  * Note that Templates use internal reference counting, so they may be added
278  * to multiple sessions, or to the same session using multiple template IDs or
279  * multiple domains, or as both an internal and an external template on the
280  * same session.
281  *
282  * By default, fBufAppend() will emit an IPFIX Message to the output stream
283  * when the end of the message buffer is reached on write. The
284  * fBufSetAutomaticMode() call can be used to modify this behavior,
285  * causing fBufAppend() to return FB_ERROR_EOM when at end of message. Use
286  * this if your application requires manual control of message export. In this
287  * case, fBufEmit() will emit a Message to the output stream.
288  *
289  * If not in automatic mode and a session's templates do not fit into a single
290  * message, use fbSessionExportTemplate() to export each template individually
291  * instead of relying on fbSessionExportTemplates().
292  *
293  * Manual control of message export is incompatible with template and
294  * information element metadata (fbSessionSetMetadataExportTemplates() and
295  * fbSessionSetMetadataExportElements()).  There are several functions that
296  * can cause the metadata options records to be exported, and the session must
297  * be free to create a new record set or template set as needed.
298  *
299  *
300  * @page read IPFIX File Collectors
301  *
302  * How-To Read IPFIX Files:
303  *
304  * Using fixbuf to read from IPFIX Files as a Collecting Process is very
305  * much like the Export case. Create an fbInfoModel_t using fbInfoModelAlloc()
306  * and any additional, vendor-specific information elements using
307  * fbInfoModelAddElement(), fbInfoModelAddElementArray(),
308  * fbInfoModelReadXMLFile(), or fbInfoModelReadXMLData().  Next create
309  * an fbSession_t using fbSessionAlloc() and add internal templates via
310  * fbSessionAddTemplate(). External templates do not need to be added
311  * for collection, as they will be loaded from templates in the file.
312  *
313  * Then create an fbCollector_t to encapsulate the file, using the
314  * fbCollectorAllocFP() or fbCollectorAllocFile() calls.
315  *
316  * With an fbSession_t and an fbCollector_t available, create a buffer for
317  * writing via fBufAllocForCollection(). Set the internal template
318  * ID with fBufSetInternalTemplate(), and use
319  * fBufNext() to read records from IPFIX Messages and Messages from the
320  * input stream.
321  *
322  * By default, fBufNext() will consume an IPFIX Message from the input stream
323  * when the end of the message buffer is reached on read. The
324  * fBufSetAutomaticMode() call can be used to modify this behavior,
325  * causing fBufNext() to return FB_ERROR_EOM when at end of message. Use
326  * this if your application requires manual control of message collection.
327  * In this case, fBufNextMessage() will consume a Message from the input
328  * stream.
329  *
330  * @page collect Network Collectors
331  *
332  * Listening over the Network - TCP Recommended:
333  *
334  * An additional type, @ref fbListener_t, is used to build Collecting Processes
335  * to listen for connections from IPFIX Exporting Processes via the network.
336  * To use a listener, first create an fbInfoModel_t using fbInfoModelAlloc()
337  * and any additional, vendor-specific information elements using
338  * fbInfoModelAddElement(), fbInfoModelAddElementArray(),
339  * fbInfoModelReadXMLFile(), or fbInfoModelReadXMLData().  Next create
340  * an fbSession_t using fbSessionAlloc() and add internal templates via
341  * fbSessionAddTemplate(). Instead of
342  * maintaining state for a particular Transport Session, this fbSession_t
343  * instance will be used as a template for each Transport Session created
344  * by the listener.
345  *
346  * Then create an fbListener_t to encapsulate a passive socket on the network
347  * to wait for connections from Exporting Processes using the
348  * fbListenerAlloc() call.
349  *
350  * To wait for a connection from an Exporting Process, call fbListenerWait(),
351  * which handles the cloning of the fbSession_t, the creation of the
352  * fbCollector_t, and the creation of the buffer for reading from that
353  * collector, and returns the newly created fBuf_t instance.
354  *
355  * A listener binds to each address returned by getaddrinfo().  Once a
356  * packet has been received, the collector will only read packets on the
357  * address it received the first packet UNLESS fbListenerWait() is called
358  * again.  If the application is expecting multiple connections or IPFIX
359  * records from multiple IPFIX (UDP) exporters, then the application should
360  * put the fBuf_t returned from fbListenerWait() into to manual mode by
361  * calling fBufSetAutomaticMode() with FALSE as the second argument and
362  * handle FB_ERROR_EOM errors
363  * returned from fBufNext() by calling fbListenerWait() again.
364  *
365  * Each listener tracks every active collector/buffer (i.e., each active
366  * Session) it created; the fbListenerWait() call will return an fBuf_t from
367  * which another IPFIX Message may be read if no new connections are available.
368  * The preferred parameter may be used to request an fBuf_t to try first, to
369  * minimize switching among available Sessions. See the documentation for
370  * fbListenerWait() for more details.
371  *
372  * If an application wants to wait for connections on multiple ports or
373  * multiple transport protocols, the application can use fbListenerGroupWait()
374  * to accept multiple connections.  The application should create separate
375  * sessions and fbConnSpec_ts for each fbListener and call fbListenerAlloc()
376  * to allocate each listener.  Create an fbListenerGroup_t by calling
377  * fbListenerGroupAlloc() and add each listener to the group using
378  * fbListenerGroupAddListener().  Instead of calling fbListenerWait(), use
379  * the function fbListenerGroupWait() to listen on all addresses in the group.
380  * fbListenerGroupWait() returns an fbListenerGroupResult_t which is a linked
381  * list of results.  The fbListenerGroupResult_t contains a pointer to an
382  * fBuf_t and the fbListener_t that created the fBuf_t as well as a pointer
383  * to the next result, if available.  Use fbListenerFreeGroupResult() to free
384  * the result when fBufNext() has been called on each fBuf_t.
385  *
386  * The application could also use fbListenerWaitNoCollectors() to handle only
387  * the initial accepting of a connection (for TCP).  Once the application
388  * returns to fbListenerWaitNoCollectors(), fixbuf will ignore that socket
389  * descriptor for the length of the connection.
390  *
391  * Additionally, the application can use fbListenerOwnSocketCollectorTCP()
392  * to provide its own socket for listening instead of libfixbuf creating
393  * one for it.
394  *
395  * To reject incoming connections, the application should use the
396  * @ref fbListenerAppInit_fn function callback.  This will be called right
397  * after accept() is called (in the TCP case).  The application can veto the
398  * connection by returning FALSE.  Once the connection is vetoed, fixbuf
399  * will not listen on that socket descriptor.
400  * If the appinit() function should reject a connection the application
401  * should set the error code to FB_ERROR_NLREAD and the application should
402  * ignore FB_ERROR_NLREAD error codes.  The appinit() function works slightly
403  * different for UDP.  See the @ref udp "UDP instructions" for how to use
404  * appinit() for collecting IPFIX over UDP.
405  *
406  * @page udp UDP Collectors
407  *
408  * How-To Collect IPFIX over UDP:
409  *
410  * It is not recommended to use UDP for IPFIX transport, since
411  * UDP is not a reliable transport protocol, and therefore cannot guarantee
412  * the delivery of messages.  libfixbuf stores sequence numbers and reports
413  * potential loss of messages.  Templates over UDP must be re-sent at regular
414  * intervals.  Fixbuf does not automatically retransmit messages at regular
415  * intervals, it is left to the application author to call
416  * fbSessionExportTemplates().  In accordance with RFC 7011, the templates
417  * should be resent at least three times in the Template refresh timeout
418  * period.  Make sure the record size does not exceed the path MTU.
419  * libfixbuf will return an error if the message exceeds the path MTU.
420  *
421  * A UDP collector session is associated with a unique IP, observation domain
422  * pair.  UDP sessions timeout after 30 minutes of inactivity.  When a session
423  * times out, all templates and state are discarded, this includes any related
424  * NetFlow v9 templates and/or state.  libfixbuf will discard
425  * any data records for which it does not contain a template for. Template IDs
426  * are unique per UDP session (IP and Observation Domain.) Once
427  * templates are refreshed, old templates may not be used or referenced by
428  * the collecting session.  A UDP collector manages multiple sessions on
429  * one collector and fBuf.  If the application is using the @ref
430  * fbListenerAppInit_fn and @ref fbListenerAppFree_fn functions to maintain
431  * context per session, it is
432  * necessary to call fbCollectorGetContext() after each call to fBufNext() to
433  * receive the correct context pointer (as opposed to calling it after
434  * fbListenerWait() returns in the TCP case).  If the application needs to
435  * manage context PER SESSION, the application must turn on multi-session mode
436  * w/ fbCollectorSetUDPMultiSession() (this allows for backwards compatibility
437  * with old applications.)  Previously, the appinit() function was called
438  * only from fbListenerAlloc() for UDP connections, which did not allow the
439  * application the peer information.  The appinit() function is now called
440  * during fbListenerAlloc() (with a NULL peer address) and also when
441  * a new UDP connection is made to the collector, giving the application
442  * veto power over session creation.  If the application does not call
443  * fbCollectorSetUDPMultiSession(), the application will not receive the
444  * callback to it's appinit() function, which only allows the application
445  * to set one context pointer on all sessions.  Likewise, appfree() is only
446  * called once, when the collector is freed, if not in multi-session mode.
447  * If the application is in multi-session mode, appfree() will be called
448  * once for each session when the collector is freed AND anytime a session
449  * is timed out.
450 
451  * Note: If the appinit() function returns FALSE, libfixbuf will
452  * reject any subsequent messages from the
453  * peer address, observation domain until the timeout period has expired.
454  * If the appinit() function should reject a "connection" the application
455  * should set the error code to FB_ERROR_NLREAD and return FALSE.
456  *      Example usage:
457  *     \code{.c}
458  *         g_set_error(error, FB_ERROR_DOMAIN, FB_ERROR_NLREAD, "some msg");
459  *      \endcode
460  *
461  *
462  * To only accept IPFIX from one host without using the appinit() and
463  * appfree() functions, it is encouraged to
464  * use fbCollectorSetAcceptOnly().  UDP messages received from other hosts
465  * will return FB_ERROR_NLREAD.  The application should ignore errors with
466  * this error code by clearing the error and calling fBufNext().
467  *
468  * @page v9  NetFlow v9 Collectors
469  *
470  * How-To use libfixbuf as a NetFlow v9 Collector:
471  *
472  * libfixbuf can be used as a [NetFlow v9][] collector and convert NetFlow to
473  * IPFIX.  Follow the @ref udp "steps above" to create an fbListener.
474  * After creating
475  * the listener, retrieve the collector by calling fbListenerGetCollector()
476  * before calling fbCollectorSetNetflowV9Translator().  Fixbuf can decode all
477  * NetFlow v9 information elements up to 346.  Since fixbuf removes the
478  * SysUpTime from the NetFlow v9 Header, when fixbuf encounters elements 21
479  * and 22 (which rely on the SysUpTime to determine flow start and end times)
480  * it will add IPFIX Element 160 (systemInitTimeMilliseconds) to the template
481  * and corresponding flow record. systemInitTimeMilliseconds is the Packet
482  * Export Time (found in the NetFlow v9 Header) converted to milliseconds
483  * minus the SysUpTime. Also, for arbitrary Cisco Elements (ID > 346), fixbuf
484  * will convert the element ID to 9999 in order to decode the element properly.
485  * The exceptions are elements 33002 (NF_F_FW_EXT_EVENT) and 40005
486  * (NF_F_FW_EVENT) which are often exported from Cisco's ASA device. These
487  * elements will be converted to their corresponding element id's in
488  * libfixbuf's default Information Model, 9997 and 9998 respectively.
489  * Similarly, the Cisco ASA will also export elements 40001, 40002, 40003,
490  * and 40004.  These elements are substituted with the IPFIX elements 225, 226,
491  * 227, and 228 respectively.
492  *
493  * libfixbuf will also convert NetFlow v9 Options Templates and Options Records
494  * to IPFIX.  Due to the differences between IPFIX and NetFlow v9 Options
495  * Templates the NetFlow v9 Scope Field Type is dropped and replaced with the
496  * Information Element ID 263, messageScope.  The Scope Field Length will
497  * be carried over to the IPFIX Options Template, and the messageScope will
498  * have the length specified by Scope Field Length.  This holds true for all
499  * Scope Elements defined in the NetFlow v9 Options Template.  In order to
500  * retrieve the value for the Scope Field Type, the IPFIX internal template
501  * should use the messageScope Information Element and use the length
502  * override (the default length for messageScope is 1).
503  *
504  * libfixbuf differentiates NetFlow v9 streams by IP and observation domain.
505  * If no activity is seen from a NetFlow v9 exporter within 30 minutes, the
506  * session and all the templates associated with it will be freed. It is best
507  * to set the template timeout period on the device to under 30 minutes.
508  *
509  * fbCollectorGetNetflowMissed() can be used to retrieve the number of
510  * potential missed export packets.  This is not the number of FLOW records
511  * that the collector has missed.  NetFlow v9 increases sequence numbers
512  * by the number of export packets it has sent, NOT the number of flow
513  * records.  An export packet may not contain any flow records.  Fixbuf
514  * tries to account for any reboot of the device and not count large
515  * sequence number discrepancies in it's missed count.
516  *
517  * To disable NetFlow v9 log messages such as sequence number mismatch
518  * messages, option template removal messages, and record count discrepancy
519  * messages, run `make clean`, `CFLAGS="-DFB_SUPPRESS_LOGS=1" make -e`,
520  * `make install` when installing libfixbuf.
521  *
522  * [NetFlow v9]: https://tools.ietf.org/html/rfc3954
523  *
524  * @page sflow sFlow Collectors
525  *
526  * How to use libfixbuf to collect sFlow v5
527  *
528  * libfixbuf can be used to collect sFlow and convert sFlow to
529  * IPFIX.  Follow the @ref udp "steps above" to create an fbListener.
530  * After creating
531  * the listener, retrieve the collector by calling fbListenerGetCollector()
532  * before calling fbCollectorSetSFlowTranslator().  Essentially, the libfixbuf
533  * translator is an IPFIX mediator which converts sFlow to IPFIX.  sFlow v5 is
534  * a fixed format protocol.  The same steps are used to retrieve flow records
535  * from the buffer, call fBufNext().  The internal template should contain
536  * some subset of the fields listed below.  sFlow Data Records will have a
537  * template ID of 0xEEEE and the Options Records will have a template ID of
538  * 0xEEEF.
539  *
540  * Fixbuf first reads the sFlow header to ensure the buffer contains
541  * sFlow v5.  Fixbuf currently only has support for sFlow v5.  The
542  * sFlow header only contains the time since the device last rebooted
543  * (but not the time of reboot) and this time will be reported in the
544  * systemInitTimeMilliseconds field. Fixbuf records the time that the
545  * sFlow message was received in the collectionTimeMilliseconds field.
546  * Once the first message has been received, the translator will
547  * create an external buffer and export the fixed templates to the
548  * fixbuf session.  Note: the first sFlow message that fixbuf receives
549  * will not be processed - this is used to setup the translation
550  * process.  The translator will keep track of sequence numbers per
551  * peer (IP)/observation domain (agent ID) by default.  There are
552  * multiple sequence numbers in sFlow.  Each sFlow message has a
553  * sequence number and each sample has a sequence number.  The sFlow
554  * message sequence number is used to determine if sFlow messages have
555  * been dropped.  Fixbuf will report if either sequence number is out
556  * of sequence and emit a warning. The warning is just for
557  * notification, libfixbuf will process all well-formed samples that
558  * it receives.
559  *
560  * libfixbuf will process Flow Samples (1), Extended Flow Samples (3), Counter
561  * Samples (2), and Extended Counter Samples (4).  Any other format will
562  * return an FB_ERROR_SFLOW.  Applications should ignore (and potentially log)
563  * FB_ERROR_SFLOW errors.  FB_ERROR_SFLOW errors are not fatal.
564  * With an sFlow sample, fixbuf can handle the following formats:
565  *
566  * - Raw Packet Data, enterprise = 0, format = 1
567  * - Ethernet Frame Data, enterprise = 0, format = 2
568  * - IPv4 Data, enterprise = 0, format = 3
569  * - IPv6 Data, enterprise = 0, format = 4
570  * - Extended Switch data, enterprise = 0, format = 1001
571  * - Extended Router data, enterprise = 0, format = 1002
572  * - Extended Gatway Data, enterprise = 0, format = 1003
573  *
574  * Any other flow sample format will be silently ignored.
575  * Each sFlow flow record can contain the following fields, formats are listed
576  * in the parenthesis:
577  *
578  *  IPFIX FIELDS | sFlow FIELDS | Reduced Length
579  * ------------- | ------------- | -------------
580  * sourceIPv6Address | Ipv6 Address in IPv6 (4) or Raw Packet (1) Data | N
581  * destinationIPv6Address | Ipv6 Address in IPv6 (4) or Raw Packet (1) Data| N
582  * ipNextHopIPv6Address | Extended Router Data (1002) | N
583  * bgpNextHopIPv6Address | Extended Gateway Data (1003) | N
584  * collectorIPv6Address | Message Header Data | N
585  * collectionTimeMilliseconds | Message Header Data | N
586  * systemInitTimeMilliseconds | Message Header Data | N
587  * collectorIPv4Address | Message Header Data | N
588  * protocolIdentifier | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | N
589  * ipClassOfService | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | N
590  * sourceIPv4PrefixLength  |Extended Router Data (1002) | N
591  * destinationIPv4PrefixLength | Extended Router Data (1002) | N
592  * sourceIPv4Address | IPv4 (3) or Raw Packet (1) Data | N
593  * destinationIPv4Address | IPv4 (3) or Raw Packet (1) Data| N
594  * octetTotalCount | Flow Sample Header Data | 4
595  * packetTotalCount | Flow Sample Header Data | 4
596  * ingressInterface | Flow Sample Header Data | N
597  * egressInterface | Flow Sample Header Data | N
598  * sourceMacAddress | Ethernet (2), IPv4 (3), IPv6 (4) or Raw Packet (1) Data | N
599  * destinationMacAddress | Ethernet (2), IPv4 (3), IPv6 (4) or Raw Packet (1) Data | N
600  * ipNextHopIPv4Address | Extended Router Data (1002) | N
601  * bgpSourceAsNumber | Extended Gateway Data (1003)| N
602  * bgpDestinationAsNumber| Extended Gateway Data (1003) | N
603  * bgpNextHopIPv4Address| Extended Gateway Data (1003) | N
604  * samplingPacketInterval | Message Header Data | N
605  * samplingPopulation| Message Header Data | N
606  * droppedPacketTotalCount| Message Header Data | 4
607  * selectorId| Message Header Data | 4
608  * vlanId | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | N
609  * sourceTransportPort | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | N
610  * destinationTransportPort | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | N
611  * tcpControlBits | IPv4 (3) or IPv6 (4) or Raw Packet (1) Data | 2
612  * dot1qVlanId | Extended Switch Data (1001) | N
613  * postDot1qVlanId | Extended Switch Data (1001) | N
614  * dot1qPriority  | Extended Switch Data (1001) | N
615  *
616  * libfixbuf will also convert sFlow Counter Records to Options Records
617  * in IPFIX. libfixbuf will only process the Generic Interface Counters
618  * (format = 1).  Other formats will be silently ignored.
619  * The following fields are present in the Counter (Options) Template/Record:
620  *
621  *  IPFIX FIELDS | sFlow FIELDS | Reduced Length
622  * ------------- | ------------- | --------------
623  * collectorIPv6Address | Message Header Data | N
624  * collectionTimeMilliseconds | Message Header Data | N
625  * systemInitTimeMilliseconds | Message Header Data | N
626  * collectorIPv4Address  | Message Header Data | N
627  * ingressInterface | Counter Sample Header Data | N
628  * octetTotalCount | ifINOctets (1) | N
629  * ingressInterfaceType | ifType (1) | N
630  * packetTotalCount | ifInUcastPkts (1) | 4
631  * ingressMulticastPacketTotalCount | ifInMulticastPkts (1) | 4
632  * ingressBroadcastPacketTotalCount | ifInBroadcastPkts (1) | 4
633  * notSentPacketTotalCount | ifInDiscards (1) | 4
634  * droppedPacketTotalCount | ifInErrors (1) | 4
635  * postOctetTotalCount | ifOutOctets (1) | N
636  * ignoredPacketTotalCount | ifInUnknownProtos (1) | 4
637  * postPacketTotalCount | ifOutUcastPkts (1) | 4
638  * egressBroadcastPacketTotalCount |  ifOutBroadcastPkts (1) | 4
639  * selectorId | Message Header Data | 4
640  *
641  *
642  * fbCollectorGetSFlowMissed() can be used to retrieve the number of
643  * potential missed export packets.  This is not the number of FLOW samples
644  * that the collector has missed.  Fixbuf
645  * tries to account for any reboot of the device and not count large
646  * sequence number discrepancies in it's missed count.
647  *
648  * Fixbuf will return FB_ERROR_SFLOW if it tries to process any
649  * malformed samples.
650  *
651  * @page spread Spread Collectors
652  *
653  * How-To use the Spread Protocol:
654  *
655  * The instructions for using [Spread][] in libfixbuf are similar to the
656  * setup for reading from IPFIX files.  As described above in the @ref export
657  * "Exporters"
658  * section, the first step is to create an fbInfoModel_t and fbSession_t.
659  * Next, create the internal template(s) and add it to the fbSession_t.
660  * Define an @ref fbSpreadParams_t and set the session, groups to subscribe to,
661  * and Spread Daemon name.
662  *     Example usage:
663  *     \code{.c}
664  *       fbSpreadParams_t spread;
665  *       char *groups[25];
666  *       groups[0] = strdup("group1");
667  *       groups[1] = '\0';
668  *       spread.daemon = "daemon1"
669  *       spread.groups = groups;
670  *       spread.session = session;
671  *       collector = fbCollectorAllocSpread(0, &spread, &err);
672  *      \endcode
673  *
674  * Then create an fbCollector_t to connect and listen to the Spread Daemon
675  * using fbCollectorAllocSpread().
676  *
677  * With an fbSession_t and fbCollector_t available, create a buffer for
678  * writing via fBufAllocForCollection().  Set the internal template ID with
679  * fBufSetInternalTemplate(), and use fBufNext() to read records from IPFIX
680  * Messages published to the group your collector is subscribing to.
681  *
682  * To view all the Spread Groups that were sent the incoming record, call
683  * fbCollectorGetSpreadReturnGroups() on the collector.
684  *
685  * [Spread]:  http://www.spread.org/
686  *
687  * @page noconnect Connection-less Collector
688  *
689  * How-To use libfixbuf with just a data buffer:
690  *
691  * To use fixbuf independent of the transport mode, the application must
692  * create an fbInfoModel_t using fbInfoModelAlloc()
693  * and any additional, vendor-specific information elements using
694  * fbInfoModelAddElement(), fbInfoModelAddElementArray(),
695  * fbInfoModelReadXMLFile(), or fbInfoModelReadXMLData().  Next create
696  * an fbSession_t using fbSessionAlloc() and add internal templates via
697  * fbSessionAddTemplate().
698  * The application will handle all connections and reading and simply
699  * pass fixbuf
700  * the buffer to be decoded.  The buffer must contain valid IPFIX and should
701  * begin with the standard IPFIX header.  Ideally, the application should
702  * provide the necessary templates before any data records to ensure that
703  * the application can decode all of the data records.
704  *
705  * The application should NOT create an fbCollector.  To create the fBuf,
706  * use fBufAllocForCollection() and set the second parameter to NULL.
707  * The application then has everything needed to start reading from the IPFIX
708  * source.  Ideally, the application will read the first 4 bytes of the message
709  * first to determine the length of the next IPFIX message.  The first 2 bytes
710  * are the IPFIX version (0x000A) and the third and fourth bytes are the length
711  * of the following IPFIX message (including the IPFIX message header). The
712  * application should then continue reading the length of the IPFIX message
713  * into an allocated buffer.  The buffer should then be set on the fBuf by
714  * calling fBufSetBuffer(). The application will continue to call fBufNext()
715  * to receive the data records until fBufNext() returns FALSE with error
716  * code FB_ERROR_BUFSZ.  However, if the fBuf is in manual mode
717  * (see fBufSetAutomaticMode()) AND the application was reading the
718  * message length, fixbuf will first return an FB_ERROR_EOM which will
719  * signal to the application to perform another read (if the application
720  * ignores FB_ERROR_EOM errors and calls fBufNext(), fBufNext() will then
721  * return FB_ERROR_BUFSZ). This error notifies the application that there is
722  * not enough data in the buffer to read a full IPFIX message.  If the
723  * application only read the size of the IPFIX message, the entire buffer
724  * should have been read.  However, if the application was reading more than
725  * the IPFIX message length, additional data may remain in the buffer that
726  * belongs to the next IPFIX message.  To determine how much data was left
727  * in the buffer unread, fBufRemaining() will return the length
728  * of the buffer that was not processed.  That remaining data should be copied
729  * to the beginning of the buffer and the remaining IPFIX message data should
730  * be read.  After each read, the application needs to call fBufSetBuffer().
731  * Note that fBufSetBuffer() sets the collector and exporter on the fBuf to
732  * NULL.  The application should clear the FB_ERROR_BUFSZ and/or FB_ERROR_EOM
733  * error when they occur using g_clear_error().
734  *
735  * fixbuf may return the following error codes if it encounters one
736  * of the below issues.  The application should determine the error and
737  * respond appropriately.
738  *
739  *  - FB_ERROR_IPFIX
740  *     - If the first 2 bytes != 0x000A
741  *     - If the length in the header < 16
742  *  - FB_ERROR_EOM
743  *     - If the application read only the message length and the application
744  *       called fBufSetAutomaticMode(fbuf, FALSE) (the fBuf is in manual mode).
745  *       This means the remaining buffer length == 0 and the application
746  *       should clear the error and perform another read
747  *  - FB_ERROR_BUFSZ
748  *     - If the header message length > the given buffer length
749  *     - if the given buffer == NULL
750  *     - If the given buffer length < 16
751  *     - If buffer length == 0
752  *
753  *
754  *     Example usage:
755  *     \code{.c}
756  *        FILE *fp;
757  *        uint8_t buf[65535];
758  *        ...
759  *        while (fread(buf, 1, 4, fp) == 4) {
760  *           len = ntohs(*((uint16_t *)(buf+2)));
761  *           rc = fread(buf+4, 1, len-4, fp);
762  *           if (rc > 0) {
763  *               fBufSetBuffer(fbuf, buf, rc+4);
764  *           } else if (feof(fp))
765  *           ....
766  *           for (;;) {
767  *               ret = fBufNext(fbuf, (uint8_t *)rec, &len, &err);
768  *               if (FALSE == ret) {
769  *                  if (g_error_matches(err, FB_ERROR_DOMAIN, FB_ERROR_BUFSZ)){
770  *                     rem = fBufRemaining(fbuf);
771  *                     g_clear_error(&err);
772  *                     break;
773  *                  }
774  *               }
775  *            }
776  *        }
777  *      \endcode
778  *
779  * @page lists Lists in IPFIX
780  *
781  * How-To deal with BasicLists, SubTemplateLists, & SubTemplateMultiLists:
782  *
783  * @section general General Information
784  * Each of the list structures uses a nested list of data.
785  * The basic list nests a single information element, while the others use a
786  * nested template.  The template used for nesting is part of the listed
787  * templates sent to the collector when the connection is made, or when the
788  * data transfer begins.  There is no way to mark a template from this list as
789  * one that will be nested, or one that will be used as the highest level
790  * template.  Each of the templates in the list are treated as equals.
791  *
792  * The collector does not learn which template or information element is nested
793  * until the data arrives.  This requires flexibility in the collectors to
794  * handle each of the possible results.
795  *
796  * @subsection internalTemplates Internal Templates for Sub Templates
797  * The setting of the internal template has not changed with the addition of
798  * the list structures.  The internal template is still used to perform the
799  * initial decoding of the data that arrives at the collector.
800  *
801  * Basic lists are not transcoded in the same way as templates because they
802  * contain just one information element, thus having no order, so the data can
803  * just be parsed and copied to a buffer.
804  *
805  * The question with decoding sub templates becomes, what do we use as an
806  * internal template for any sub templates that arrive?  The answer is a new
807  * structure in fixbuf that pairs external and internal template IDs for use
808  * in decoding sub templates.  The pairs are added to the session that is used
809  * for the connection, using fbSessionAddTemplatePair().
810  *
811  * Because the external template IDs are only unique for that session, the
812  * collector must know the IDs of the templates that are collected in order to
813  * pair an internal template with the external template.  As a result, callback
814  * functionality may be enabled (via  fbSessionAddNewTemplateCallback())
815  * to alert the user when a new external
816  * template has arrived.  The callback functions are stored in the session
817  * structure, which manages the templates.  The callback function,
818  * @ref fbNewTemplateCallback_fn, receives the session
819  * pointer, the template, the template ID, a context pointer for the
820  * application to use, and the location in which to store the template's
821  * context variable.  The
822  * callback also gives the user another callback that can be used to free the
823  * context variable upon template deletion.  This information is sufficient for
824  * the application to successfully add template pairs to the session for sub
825  * template decoding.
826  *
827  * If the application does not use the callback or does not add any template
828  * pairs to the session, then fixbuf will transcode each of the sub templates
829  * as if the external and internal template were same.  This causes all of the
830  * fields sent over the wire to be transcoded into the data buffer on the
831  * collecting side.  The details of that template are passed up to the
832  * collector upon receipt of data so it knows how the data is structured in
833  * the buffer.
834  *
835  * If the application adds any template pair to the list, then the list will be
836  * referenced for each transcode.  Any external template the application
837  * wishes to process MUST have an entry in the list.
838  * There are 3 cases for entries in the list:
839  *   -# There is no entry for the given external template ID, so the entire
840  *      sub template is ignored by the transcoder.
841  *      The collector will be given a sub template list (or multi list entry)
842  *      struct with the number of elements in the list set to 0, and the data
843  *      pointer set to NULL.
844  *   -# The listing exists, and the external and internal template IDs are set
845  *      to the same value.  When decoding, the list of internal templates is
846  *      queried to see if a template exists with the same ID as the external
847  *      template. If not, the transcoder decodes each of the
848  *      information elements, in the same order, into the buffer. This is a
849  *      change as setting them equal to each other used to force a full decode.
850  *      This change highlights the need for careful template ID management.
851  *   -# The listing exists, and the external and internal template IDs are
852  *      different.  This will transcode in the standard way external templates
853  *      have been transcoded into internal templates, selecting the desired
854  *      elements (listed in the internal template) from the data that arrived
855  *      in the external template.
856  *
857  *
858  *
859  * @subsection iterating Iterating Over the Lists
860  * There are four scenarios in which the user needs to iterate through the
861  * elements in a list, whether to fill in, or process the data:
862  *  -#  Iterating over the repeated information element data in a basic list
863  *  -#  Iterating over the decoded data elements in a sub template list
864  *  -#  Iterating over the entries that make up a sub template multi list
865  *  -#  Iterating over the decoded data elements in an entry of a sub template
866  *      multi list
867  * The two iterating mechanisms are the same in each case:
868  * Each of the function names start with the structure being iterated over,
869  * e.g., fbBasicList, or fbSubTemplateMultiListEntry
870  *  -# Indexing
871  *     The function used here is (structName)GetIndexed(dataPtr or entry)()
872  *     It takes a pointer to the struct, and the index to be retrieved.
873  *     Example usage:
874  *     \code{.c}
875  *          for(i = 0; myStructPtr = ...GetIndexedDataPtr(listPtr, i); i++) {
876  *              process the data that myStructPtr points to.
877  *          }
878  *      \endcode
879  *     The loop will end when the function returns NULL because
880  *     i is beyond the end of the list.
881  *
882  *  -# Incrementing
883  *     The function used here is (structName)GetNext(dataPtr or entry)()
884  *     It takes a pointer to the struct, and a pointer to an element in the
885  *     list.  Pass in NULL at the beginning to get the first element back.
886  *     Example usage:
887  *     \code{.c}
888  *          myStructPtr = NULL;
889  *          while(myStructPtr = ...GetNextPtr(listPtr, myStructPtr)) {
890  *              process the data that myStructPtr points to.
891  *          }
892  *      \endcode
893  *     The loop will end when the function returns NULL because
894  *     it gets passed the end of the list.  A key part here is
895  *     initializing myStructPtr to NULL at the beginning.
896  *
897  * @page rfc_5610 RFC 5610
898  *
899  * What is RFC 5610?
900  *
901  * [RFC 5610][] provides a mechanism to export full type information for
902  * Information Elements from the IPFIX Information Model.  Libfixbuf
903  * version 1.4 and later provides API functions to create IPFIX
904  * Option Template/Records that can encode the full set of properties
905  * for the definition of an Information Element in order for a
906  * Collecting Process to be able to know how to decode data that
907  * contains enterprise-specific Information Elements.
908  *
909  * [RFC 5610]: https://tools.ietf.org/html/rfc5610
910  *
911  * @section exp RFC 5610 Exporters
912  *
913  * To create a new enterprise-specific Information Element, the
914  * Exporting Process should define a new information element using the
915  * FB_IE_INIT_FULL() macro to provide the name, private enterprise
916  * number, id, length, description, data type, and units of the
917  * information element.  The Information Elements should then be added
918  * to the Information Model using fbInfoModelAddElement() or
919  * fbInfoModelAddElementArray().  Alternatively, a file or a string
920  * containing an XML registry that describes Information Elements may
921  * be parsed and loaded into the Information Model using
922  * fbInfoModelReadXMLFile() or fbInfoModelReadXMLData().
923  *
924  * Once an enterprise-specific information element exists, there are
925  * two ways to export that information.  The simplest way is to
926  * configure automated enterprise-specific information element
927  * information export.  This is done by calling
928  * fbSessionSetMetadataExportElements() with the `enabled` parameter set to
929  * `TRUE`.  Once this has been set, the full set of information
930  * elements in the information model that have a non-zero Private
931  * Enterprise Number will be exported every time template records are
932  * exported (fbSessionExportTemplates()).
933  *
934  * The other option is to export the information element options
935  * records manually. An information element options template can then
936  * be created using fbInfoElementAllocTypeTemplate().  This creates an
937  * option template that contains all of the necessary properties to
938  * define an Information Element:
939  *
940  * - privateEnterpriseNumber
941  * - informationElementId
942  * - informationElementDataType
943  * - informationElementSemantics
944  * - informationElementUnits
945  * - informationElementRangeBegin
946  * - informationElementRangeEnd
947  * - informationElementName
948  * - informationElementDescription
949  *
950  * Then the template can be added to the session using
951  * fbSessionAddTemplate().  You will need to add it twice, once as an
952  * internal template, and once as an external template.  Create the
953  * exporter and fbuf as described above for the necessary mode of
954  * transport.  Then, to write out an information element options
955  * record, use fbInfoElementWriteOptionsRecord(), using the template
956  * IDs returned by the fbSessionAddTemplate() calls as the internal
957  * and export template IDs, passing it a pointer to the information
958  * element you want to export.  For example:
959  *
960  *  \code{.c} fbInfoElementWriteOptionsRecord(fbuf, fbInfoModelGetElementByName(infoModel, "myNewElement"), itid, etid, *err); \endcode
961  *
962  * The Options Record will automatically be appended to the fbuf
963  * and will be sent upon calling fBufEmit().
964  *
965  * @section col RFC 5610 - Collector Usage
966  *
967  * In order to collect the above Options records, the collecting
968  * process may use fBufSetAutomaticInsert()
969  * after creating an fBuf to automatically insert any information
970  * elements into the Information Model.
971  *
972  * Alternatively, the collecting process may manually define the above Options
973  * Template and provide a template callback function (via
974  * fbSessionAddNewTemplateCallback()) to collect and add each element to the
975  * Information Model using fbInfoElementAddOptRecElement() and
976  * fbInfoModelTypeInfoRecord().
977  *
978  *
979  */
980 
981 /**
982  * @file
983  *
984  *  Fixbuf IPFIX protocol library public interface
985  *
986  */
987 
988 #ifndef _FB_PUBLIC_H_
989 #define _FB_PUBLIC_H_
990 #include <fixbuf/autoinc.h>
991 #include <fixbuf/version.h>
992 
993 #ifdef __cplusplus
994 extern "C" {
995 #endif
996 
997 
998 /**
999  * Evaluates to a non-zero value if the version number of libfixbuf is
1000  * at least major.minor.release.
1001  */
1002 #define FIXBUF_CHECK_VERSION(major, minor, release)    \
1003     (FIXBUF_VERSION_MAJOR > (major) || \
1004      (FIXBUF_VERSION_MAJOR == (major) && FIXBUF_VERSION_MINOR > (minor)) || \
1005      (FIXBUF_VERSION_MAJOR == (major) && FIXBUF_VERSION_MINOR == (minor) && \
1006       FIXBUF_VERSION_RELEASE >= (release)))
1007 
1008 /*
1009  * Error Handling Definitions
1010  */
1011 
1012 /** All fixbuf errors are returned within the FB_ERROR_DOMAIN domain. */
1013 #define FB_ERROR_DOMAIN             g_quark_from_string("fixbufError")
1014 /** No template was available for the given template ID. */
1015 #define FB_ERROR_TMPL               1
1016 /**
1017  * End of IPFIX message. Either there are no more records present in the
1018  * message on read, or the message MTU has been reached on write.
1019  */
1020 #define FB_ERROR_EOM                2
1021 /**
1022  * End of IPFIX Message stream. No more messages are available from the
1023  * transport layer on read, either because the session has closed, or the
1024  * file has been processed.
1025  */
1026 #define FB_ERROR_EOF                3
1027 /**
1028  * Illegal IPFIX message content on read. The input stream is malformed, or
1029  * is not an IPFIX Message after all.
1030  */
1031 #define FB_ERROR_IPFIX              4
1032 /**
1033  * A message was received larger than the collector buffer size.
1034  * Should never occur. This condition is checked at the transport layer
1035  * in case future versions of fixbuf support dynamic buffer sizing.
1036  */
1037 #define FB_ERROR_BUFSZ              5
1038 /** The requested feature is not yet implemented. */
1039 #define FB_ERROR_IMPL               6
1040 /** An unspecified I/O error occured. */
1041 #define FB_ERROR_IO                 7
1042 /**
1043  * No data is available for reading from the transport layer.
1044  * Either a transport layer read was interrupted, or timed out.
1045  */
1046 #define FB_ERROR_NLREAD             8
1047 /**
1048  * An attempt to write data to the transport layer failed due to
1049  * closure of the remote end of the connection. Currently only occurs with
1050  * the TCP transport layer.
1051  */
1052 #define FB_ERROR_NLWRITE            9
1053 /**
1054  * The specified Information Element does not exist in the Information Model.
1055  */
1056 #define FB_ERROR_NOELEMENT          10
1057 /**
1058  * A connection or association could not be established or maintained.
1059  */
1060 #define FB_ERROR_CONN               11
1061 /**
1062  * Illegal NetflowV9 content on a read.  Can't parse the Netflow header or
1063  * the stream is not a NetflowV9 stream
1064  */
1065 #define FB_ERROR_NETFLOWV9          12
1066 /**
1067  * Miscellaneous error occured during translator operation
1068  */
1069 #define FB_ERROR_TRANSMISC          13
1070 /**
1071  * Illegal sFlow content on a read.
1072  */
1073 #define FB_ERROR_SFLOW              14
1074 /**
1075  * Setup error
1076  */
1077 #define FB_ERROR_SETUP              15
1078 /**
1079  * Internal template with defaulted element sizes
1080  */
1081 #define FB_ERROR_LAXSIZE            16
1082 
1083 /*
1084  * Public Datatypes and Constants
1085  */
1086 
1087 /**
1088  * An IPFIX message buffer. Used to encode and decode records from
1089  * IPFIX Messages. The internals of this structure are private to
1090  * libfixbuf.
1091  */
1092 typedef struct fBuf_st fBuf_t;
1093 
1094 /**
1095  * A variable-length field value. Variable-length information element
1096  * content is represented by an fbVarfield_t on the internal side of the
1097  * transcoder; that is, variable length fields in an IPFIX Message must be
1098  * represented by this structure within the application record.
1099  */
1100 typedef struct fbVarfield_st {
1101     /** Length of content in buffer. */
1102     size_t      len;
1103     /**
1104      * Content buffer. In network byte order as appropriate. On write, this
1105      * buffer will be copied into the message buffer. On read, this buffer
1106      * points into the message buffer and must be copied by the caller before
1107      * any call to fBufNext().
1108      */
1109     uint8_t     *buf;
1110 } fbVarfield_t;
1111 
1112 
1113 /**
1114  * An IPFIX information model. Contains information element definitions.
1115  * The internals of this structure are private to libfixbuf.
1116  */
1117 typedef struct fbInfoModel_st fbInfoModel_t;
1118 
1119 /**
1120  * An iterator over the information elements in an information model.
1121  */
1122 typedef GHashTableIter fbInfoModelIter_t;
1123 
1124 /**
1125  * Convenience macro for creating full @ref fbInfoElement_t static
1126  * initializers.  Used for creating information element arrays suitable for
1127  * passing to fbInfoModelAddElementArray().
1128  */
1129 #define FB_IE_INIT_FULL(_name_, _ent_, _num_, _len_, _flags_, _min_, _max_, _type_, _desc_)\
1130     { {(const struct fbInfoElement_st*)_name_}, 0, _ent_, _num_, _len_, _flags_, _min_, _max_, _type_, _desc_ }
1131 
1132 /**
1133  * Convenience macro for creating default @ref fbInfoElement_t
1134  * static initializers.  Used for creating information element arrays
1135  * suitable for passing to fbInfoModelAddElementArray().
1136  * @deprecated Use @ref FB_IE_INIT_FULL instead.
1137  */
1138 #define FB_IE_INIT(_name_, _ent_, _num_, _len_, _flags_) \
1139     FB_IE_INIT_FULL(_name_, _ent_, _num_, _len_, _flags_, 0, 0, 0, (char*)NULL)
1140 
1141 
1142 /**
1143  * Convenience macro defining a null @ref fbInfoElement_t initializer to
1144  * terminate a constant information element array for passing to
1145  * fbInfoModelAddElementArray().
1146  */
1147 #define FB_IE_NULL FB_IE_INIT(NULL, 0, 0, 0, 0)
1148 
1149 /**
1150  * Convenience macro for extracting the information element
1151  * semantic value from the flags member of the @ref fbInfoElement_t struct.
1152  * See https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-information-element-semantics
1153  *
1154  */
1155 #define FB_IE_SEMANTIC(flags) ((flags & 0x0000ff00) >> 8)
1156 
1157 /**
1158  * Convenience macro for extracting the information element
1159  * units value from the flags member of the @ref fbInfoElement_t struct.
1160  * See https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-information-element-units.
1161  */
1162 #define FB_IE_UNITS(flags) ((flags & 0xFFFF0000) >> 16)
1163 
1164 /**
1165  * Default treatment flags value. Provided for initializer convenience.
1166  * Corresponds to octet-array semantics for a non-reversible, non-alien IE.
1167  */
1168 #define FB_IE_F_NONE                            0x00000000
1169 
1170 /**
1171  * Information element endian conversion bit in the flags member of @ref
1172  * fbInfoElement_t. If set, IE is an integer and will be endian-converted on
1173  * transcode.
1174  */
1175 #define FB_IE_F_ENDIAN                          0x00000001
1176 
1177 /**
1178  * Information element reversible bit in the flags member of @ref
1179  * fbInfoElement_t.  Adding the information
1180  * element via fbInfoModelAddElement() or fbInfoModelAddElementArray()
1181  * will cause a second, reverse information element to be added to the
1182  * model following the conventions in IETF RFC 5103.  This means that,
1183  * if there is no enterprise number, the reverse element will get an
1184  * enterprise number of @ref FB_IE_PEN_REVERSE, and if there is an
1185  * enterprise number, the reverse element's numeric identifier will
1186  * have its @ref FB_IE_VENDOR_BIT_REVERSE bit set.
1187  */
1188 #define FB_IE_F_REVERSIBLE                      0x00000040
1189 
1190 /**
1191  * Information element alien bit in the flags member of @ref
1192  * fbInfoElement_t. If set, IE is enterprise-specific and was recieved via an
1193  * external template at a Collecting Process. It is therefore subject to
1194  * semantic typing via options (not yet implemented). Do not set this flag on
1195  * information elements added programmatically to an information model via
1196  * fbInfoModelAddElement() or fbInfoModelAddElementArray().
1197  */
1198 #define FB_IE_F_ALIEN                           0x00000080
1199 
1200 /**
1201  * An Information Element Semantics Flags used to describe an information
1202  * element as a quantity.
1203  */
1204 #define FB_IE_QUANTITY                          0x00000100
1205 
1206 /**
1207  * An Information Element Semantics Flags used to describe an information
1208  * element as a totalCounter.
1209  *
1210  */
1211 #define FB_IE_TOTALCOUNTER                      0x00000200
1212 
1213 /**
1214  * An Information Element Semantics Flag used to describe an information
1215  * element as a deltaCounter.
1216  */
1217 #define FB_IE_DELTACOUNTER                      0x00000300
1218 
1219 /**
1220  * An Information Element Semantics Flag used to describe an information
1221  * element as an identifier.
1222  */
1223 #define FB_IE_IDENTIFIER                        0x00000400
1224 
1225 /**
1226  * An Information Element Semantics Flag used to describe an information
1227  * element as a flags element.
1228  */
1229 #define FB_IE_FLAGS                             0x00000500
1230 
1231 /**
1232  * An Information Element Semantics Flag used to describe an information
1233  * element as a List Element.
1234  *
1235  */
1236 #define FB_IE_LIST                              0x00000600
1237 
1238 /**
1239  * An Information Element Semantics Flag used to describe an information
1240  * element as an SNMP counter.
1241  *
1242  */
1243 #define FB_IE_SNMPCOUNTER                       0x00000700
1244 
1245 /**
1246  * An Information Element Semantics Flag used to describe an information
1247  * element as a SNMP gauge.
1248  *
1249  */
1250 #define FB_IE_SNMPGAUGE                         0x00000800
1251 
1252 /**
1253  * An Information Element Semantics Flag used to describe an information
1254  * element as a Default element.
1255  *
1256  */
1257 #define FB_IE_DEFAULT                           0x00000000
1258 
1259 /**
1260  * Information Element Units - See RFC 5610
1261  *
1262  */
1263 
1264 /**
1265  * An Information Element Units Flag used to describe the units
1266  * of an information element. See RFC 5610
1267  *
1268  */
1269 #define FB_UNITS_BITS                           0x00010000
1270 /**
1271  * An Information Element Units Flag used to describe the units
1272  * of an information element. See RFC 5610
1273  *
1274  */
1275 #define FB_UNITS_OCTETS                         0x00020000
1276 /**
1277  * An Information Element Units Flag used to describe the units
1278  * of an information element. See RFC 5610
1279  *
1280  */
1281 #define FB_UNITS_PACKETS                        0x00030000
1282 /**
1283  * An Information Element Units Flag used to describe the units
1284  * of an information element. See RFC 5610
1285  *
1286  */
1287 #define FB_UNITS_FLOWS                          0x00040000
1288 /**
1289  * An Information Element Units Flag used to describe the units
1290  * of an information element. See RFC 5610
1291  *
1292  */
1293 #define FB_UNITS_SECONDS                        0x00050000
1294 /**
1295  * An Information Element Units Flag used to describe the units
1296  * of an information element. See RFC 5610
1297  *
1298  */
1299 #define FB_UNITS_MILLISECONDS                   0x00060000
1300 /**
1301  * An Information Element Units Flag used to describe the units
1302  * of an information element. See RFC 5610
1303  *
1304  */
1305 #define FB_UNITS_MICROSECONDS                   0x00070000
1306 /**
1307  * An Information Element Units Flag used to describe the units
1308  * of an information element. See RFC 5610
1309  *
1310  */
1311 #define FB_UNITS_NANOSECONDS                    0x00080000
1312 /**
1313  * An Information Element Units Flag used to describe the units
1314  * of an information element. See RFC 5610
1315  *
1316  */
1317 #define FB_UNITS_WORDS                          0x00090000
1318 /**
1319  * An Information Element Units Flag used to describe the units
1320  * of an information element. See RFC 5610
1321  *
1322  */
1323 #define FB_UNITS_MESSAGES                       0x000A0000
1324 /**
1325  * An Information Element Units Flag used to describe the units
1326  * of an information element. See RFC 5610
1327  *
1328  */
1329 #define FB_UNITS_HOPS                           0x000B0000
1330 /**
1331  * An Information Element Units Flag used to describe the units
1332  * of an information element. See RFC 5610
1333  *
1334  */
1335 #define FB_UNITS_ENTRIES                        0x000C0000
1336 /**
1337  * An Information Element Units Flag used to describe the units
1338  * of an information element.  Added for layer 2 frames
1339  *
1340  */
1341 #define FB_UNITS_FRAMES                         0x000D0000
1342 /**
1343  * An Information Element Units Flag used to describe the units
1344  * of an information element.  See RFC 8045.
1345  *
1346  */
1347 #define FB_UNITS_PORTS                          0x000E0000
1348 /**
1349  * An Information Element Units Flag used to describe the units
1350  * of an information element.  See RFC 5477.
1351  *
1352  */
1353 #define FB_UNITS_INFERRED                       0x000F0000
1354 
1355 /**
1356  * Information element length constant for variable-length IE.
1357  */
1358 #define FB_IE_VARLEN                            65535
1359 
1360 /**
1361  * Information element number constant for basic lists.
1362  * This may change upon updates to the specification.
1363  * @deprecated Collectors should use the `type` member of the
1364  * @ref fbInfoElement_t or use fbInfoModelGetElementByName() to query the
1365  * @ref fbInfoModel_t, and libfixbuf will remove this value in a future
1366  * release.
1367  */
1368 #define FB_IE_BASIC_LIST                        291
1369 /**
1370  * Information element number constant for sub template lists.
1371  * This may change upon updates to the IPFIX lists specification.
1372  * @deprecated Collectors should use the `type` member of the
1373  * @ref fbInfoElement_t or use fbInfoModelGetElementByName() to query the
1374  * @ref fbInfoModel_t, and libfixbuf will remove this value in a future
1375  * release.
1376  */
1377 #define FB_IE_SUBTEMPLATE_LIST                  292
1378 /**
1379  * Information element number constant for sub template multi lists.
1380  * This may change upon updates to the IPFIX lists specification.
1381  * @deprecated Collectors should use the `type` member of the
1382  * @ref fbInfoElement_t or use fbInfoModelGetElementByName() to query the
1383  * @ref fbInfoModel_t, and libfixbuf will remove this value in a future
1384  * release.
1385 */
1386 #define FB_IE_SUBTEMPLATE_MULTILIST             293
1387 
1388 /**
1389  * Private enterprise number for reverse information elements (see RFC
1390  * 5103 section 6.1).  If an information element with
1391  * @ref FB_IE_F_REVERSIBLE and a zero enterprise number (i.e., an
1392  * IANA-assigned information element) is added to a model, the reverse
1393  * IE will be generated by setting the enterprise number to this
1394  * constant.
1395  */
1396 #define FB_IE_PEN_REVERSE                       29305
1397 
1398 /**
1399  * Reverse information element bit for vendor-specific information elements
1400  * (see RFC 5103 section 6.2). If an information element with @ref
1401  * FB_IE_F_REVERSIBLE and a non-zero enterprise number (i.e., a
1402  * vendor-specific information element) is added to a model, the reverse IE
1403  * number will be generated by ORing this bit with the given forward
1404  * information element number.
1405  */
1406 #define FB_IE_VENDOR_BIT_REVERSE                0x4000
1407 
1408 /**
1409  * Generic Information Element ID for undefined Cisco NetFlow v9 Elements.
1410  *
1411  *
1412  */
1413 #define FB_CISCO_GENERIC                       9999
1414 /**
1415  * Information Element ID for Cisco NSEL Element NF_F_FW_EVENT often
1416  * exported by Cisco's ASA Device.  This must be converted to a different
1417  * Information Element ID due to the reverse IE bit in IPFIX.
1418  * Cisco uses IE ID 40005.
1419  * http://www.cisco.com/en/US/docs/security/asa/asa82/netflow/netflow.html
1420  */
1421 #define FB_CISCO_ASA_EVENT_ID                  9998
1422 /**
1423  * Information Element ID for Cisco NSEL Element NF_F_FW_EXT_EVENT often
1424  * exported by Cisco's ASA Device.  This must be converted to a different
1425  * Information Element ID due to the reverse IE bit in IPFIX.
1426  * Cisco uses IE ID 33002
1427  * http://www.cisco.com/en/US/docs/security/asa/asa82/netflow/netflow.html
1428  * More Information about event codes can be found here:
1429  * http://www.cisco.com/en/US/docs/security/asa/asa84/system/netflow/netflow.pdf
1430  */
1431 #define FB_CISCO_ASA_EVENT_XTRA                9997
1432 /**
1433  * Reverse information element name prefix. This string is prepended to an
1434  * information element name, and the first character after this string
1435  * is capitalized, when generating a reverse information element.
1436  */
1437 #define FB_IE_REVERSE_STR                       "reverse"
1438 
1439 /** Length of reverse information element name prefix. */
1440 #define FB_IE_REVERSE_STRLEN                    7
1441 
1442 /**
1443  * From RFC 5610: A description of the abstract data type of an IPFIX
1444  * information element as registered in the IANA IPFIX IE Data Type
1445  * subregistry.
1446  * https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-information-element-data-types
1447  */
1448 typedef enum fbInfoElementDataType_en {
1449     /** The "octetArray" data type: A finite-length string of
1450      *  octets. */
1451     FB_OCTET_ARRAY,
1452     /** The "unsigned8" data type: A non-negative integer value in the
1453      *  range of 0 to 255 (0xFF). */
1454     FB_UINT_8,
1455     /** The "unsigned16" data type: A non-negative integer value in
1456      *  the range of 0 to 65535 (0xFFFF). */
1457     FB_UINT_16,
1458     /** The "unsigned32" data type: A non-negative integer value in
1459      *  the range of 0 to 4_294_967_295 (0xFFFFFFFF). */
1460     FB_UINT_32,
1461     /** The "unsigned64" data type: A non-negative integer value in
1462      *  the range of 0 to 18_446_744_073_709_551_615
1463      *  (0xFFFFFFFFFFFFFFFF). */
1464     FB_UINT_64,
1465     /** The "signed8" data type: An integer value in the range of -128
1466      *  to 127. */
1467     FB_INT_8,
1468     /** The "signed16" data type: An integer value in the range of
1469      *  -32768 to 32767.*/
1470     FB_INT_16,
1471     /** The "signed32" data type: An integer value in the range of
1472      *  -2_147_483_648 to 2_147_483_647.*/
1473     FB_INT_32,
1474     /** The "signed64" data type: An integer value in the range of
1475      *  -9_223_372_036_854_775_808 to 9_223_372_036_854_775_807. */
1476     FB_INT_64,
1477     /** The "float32" data type: An IEEE single-precision 32-bit
1478      *  floating point type. */
1479     FB_FLOAT_32,
1480     /** The "float64" data type: An IEEE double-precision 64-bit
1481      *  floating point type. */
1482     FB_FLOAT_64,
1483     /** The "boolean" data type: A binary value: "true" or "false". */
1484     FB_BOOL,
1485     /** The "macAddress" data type: A MAC-48 address as a string of 6
1486      *  octets. */
1487     FB_MAC_ADDR,
1488     /** The "string" data type: A finite-length string of valid
1489      *  characters from the Unicode character encoding set. */
1490     FB_STRING,
1491     /** The "dateTimeSeconds" data type: An unsigned 32-bit integer
1492      *  containing the number of seconds since the UNIX epoch,
1493      *  1970-Jan-01 00:00 UTC.  */
1494     FB_DT_SEC,
1495     /** The "dateTimeMilliseconds" data type: An unsigned 64-bit
1496      *  integer containing the number of milliseconds since the UNIX
1497      *  epoch, 1970-Jan-01 00:00 UTC.  */
1498     FB_DT_MILSEC,
1499     /** The "dateTimeMicroseconds" data type: Two 32-bit fields where
1500      *  the first is the number seconds since the NTP epoch,
1501      *  1900-Jan-01 00:00 UTC, and the second is the number of
1502      *  1/(2^32) fractional seconds. */
1503     FB_DT_MICROSEC,
1504     /** The "dateTimeMicroseconds" data type: Two 32-bit fields where
1505      *  the first is the number seconds since the NTP epoch,
1506      *  1900-Jan-01 00:00 UTC, and the second is the number of
1507      *  1/(2^32) fractional seconds. */
1508     FB_DT_NANOSEC,
1509     /** The "ipv4Address" data type: A value of an IPv4 address. */
1510     FB_IP4_ADDR,
1511     /** The "ipv6Address" data type: A value of an IPv6 address. */
1512     FB_IP6_ADDR,
1513     /** The "basicList" data type: A structured data element as
1514      *  described in RFC6313, Section 4.5.1. */
1515     FB_BASIC_LIST,
1516     /** The "subTemplateList" data type: A structured data element as
1517      *  described in RFC6313, Section 4.5.2. */
1518     FB_SUB_TMPL_LIST,
1519     /** The "subTemplateMultiList" data type: A structured data element as
1520      *  described in RFC6313, Section 4.5.3. */
1521     FB_SUB_TMPL_MULTI_LIST
1522 } fbInfoElementDataType_t;
1523 
1524 /**
1525  * A single IPFIX Information Element definition.
1526  * An Information Element defines the type of data in each field of
1527  * a record. This structure may be contained in an @ref fbInfoModel_t,
1528  * in which case the name field contians the information element name,
1529  * or an an @ref fbTemplate_t, in which case the canon field references the
1530  * @ref fbInfoElement_t contained within the Information Model.
1531  */
1532 typedef struct fbInfoElement_st {
1533     /** Information element name. */
1534     union {
1535         /**
1536          * Pointer to canonical copy of IE.
1537          * Set by fbInfoElementCopyToTemplate(),
1538          * and valid only for template IEs.
1539          */
1540         const struct fbInfoElement_st *canon;
1541         /**
1542          * Information element name. Storage for this is managed
1543          * by fbInfoModel. Valid only for model IEs.
1544          */
1545         const char                    *name;
1546     }  ref;
1547 
1548     /**
1549      * Multiple IE index. Must be 0 for model IEs.
1550      * Defines the ordering of identical IEs in templates.
1551      * Set and managed automatically by the fbTemplate_t routines.
1552      */
1553     uint32_t            midx;
1554     /** Private Enterprise Number. Set to 0 for IETF-defined IEs. */
1555     uint32_t            ent;
1556     /**
1557      * Information Element number. Does not include the on-wire
1558      * enterprise bit; i.e. num & 0x8000 == 0 even if ent > 0.
1559      */
1560     uint16_t            num;
1561     /** Information element length in octets. */
1562     uint16_t            len;
1563     /** Flags. Bitwise OR of FB_IE_F_* constants. */
1564     /** Use Macros to get units and semantic */
1565     uint32_t            flags;
1566     /** range min */
1567     uint64_t            min;
1568     /** range max */
1569     uint64_t            max;
1570     /** Data Type */
1571     uint8_t             type;
1572     /** description */
1573     const char          *description;
1574 } fbInfoElement_t;
1575 
1576 /**
1577  * The corresponding C struct for a record whose template is the
1578  * RFC5610 Information Element Type Options Template.
1579  *
1580  * If collecting this record, use the function fbInfoElementAddOptRecElement()
1581  * to add the @ref fbInfoElement_t it describes to the @ref fbInfoModel_t.
1582  *
1583  * To export RFC5610 elements, use fbSessionSetMetadataExportElements().
1584  *
1585  * fbInfoElementSpec_t rfc5610_spec[] = {
1586  *     {"privateEnterpriseNumber",         4, 0 },
1587  *     {"informationElementId",            2, 0 },
1588  *     {"informationElementDataType",      1, 0 },
1589  *     {"informationElementSemantics",     1, 0 },
1590  *     {"informationElementUnits",         2, 0 },
1591  *     {"paddingOctets",                   6, 0 },
1592  *     {"informationElementRangeBegin",    8, 0 },
1593  *     {"informationElementRangeEnd",      8, 0 },
1594  *     {"informationElementName",          FB_IE_VARLEN, 0 },
1595  *     {"informationElementDescription",   FB_IE_VARLEN, 0 },
1596  *     FB_IESPEC_NULL
1597  * };
1598  *
1599  */
1600 typedef struct fbInfoElementOptRec_st {
1601     /** private enterprise number */
1602     uint32_t       ie_pen;
1603     /** information element id */
1604     uint16_t       ie_id;
1605     /** ie data type */
1606     uint8_t        ie_type;
1607     /** ie semantic */
1608     uint8_t        ie_semantic;
1609     /** ie units */
1610     uint16_t       ie_units;
1611     /** padding to align with template */
1612     uint8_t        padding[6];
1613     /** ie range min */
1614     uint64_t       ie_range_begin;
1615     /** ie range max */
1616     uint64_t       ie_range_end;
1617     /** information element name */
1618     fbVarfield_t   ie_name;
1619     /** information element description */
1620     fbVarfield_t   ie_desc;
1621 } fbInfoElementOptRec_t;
1622 
1623 
1624 /**
1625  * Template ID argument used when adding an @ref fbTemplate_t to an @ref
1626  * fbSession_t that automatically assigns a template ID.
1627  *
1628  * Functions that accept this value include fbSessionAddTemplate(),
1629  * fbSessionAddTemplatesMulticast(), and others.
1630  *
1631  * For internal templates, FB_TID_AUTO starts from 65535 and decrements.  For
1632  * external templates, FB_TID_AUTO starts from 256 and increments.  This is to
1633  * avoid inadvertant unrelated external and internal templates having the same
1634  * ID.
1635  */
1636 #define FB_TID_AUTO         0
1637 
1638 /**
1639  * Reserved set ID for template sets, per RFC 7011.
1640  */
1641 #define FB_TID_TS           2
1642 
1643 /**
1644  * Reserved set ID for options template sets, per RFC 7011.
1645  */
1646 #define FB_TID_OTS          3
1647 
1648 /**
1649  * Minimum non-reserved template ID available for data sets, per RFC 7011.
1650  */
1651 #define FB_TID_MIN_DATA     256
1652 
1653 /**
1654  * An IPFIX Template or Options Template. Templates define the structure of
1655  * data records and options records within an IPFIX Message.
1656  * The internals of this structure are private to libfixbuf.
1657  */
1658 typedef struct fbTemplate_st fbTemplate_t;
1659 
1660 /**
1661  * Convenience macro defining a null information element specification
1662  * initializer (@ref fbInfoElementSpec_t) to terminate a constant information
1663  * element specifier array for passing to fbTemplateAppendSpecArray().
1664  */
1665 #define FB_IESPEC_NULL { NULL, 0, 0 }
1666 
1667 /**
1668  * A single IPFIX Information Element specification.  Used to name an
1669  * information element (@ref fbInfoElement_t) for inclusion in an @ref
1670  * fbTemplate_t by fbTemplateAppendSpecArray() and for querying whether a
1671  * template contains an element via fbTemplateContainsElementByName().
1672  */
1673 typedef struct fbInfoElementSpec_st {
1674     /** Information element name */
1675     char                *name;
1676     /**
1677      * The size of the information element in bytes.  For internal
1678      * templates, this is the size of the memory location that will be
1679      * filled by the transcoder (i.e., the size of a field in a
1680      * struct). Zero cannot be used to default the size of elements
1681      * used in internal templates. This is so changes in the "default"
1682      * length will not silently be different then the sizes of fields
1683      * in an internal struct definition. Zero can be used as the size
1684      * of #FB_IE_VARLEN elements.  This field can also be used to
1685      * specify reduced-length encoding.
1686      */
1687     uint16_t            len_override;
1688     /**
1689      * Application flags word. If nonzero, then the flags argument to
1690      * fbTemplateAppendSpec(), fbTemplateAppendSpecArray(), or
1691      * fbTemplateContainsAllFlaggedElementsByName() MUST match ALL the bits of
1692      * this flags word in order for the information element to be considered.
1693      */
1694     uint32_t            flags;
1695 } fbInfoElementSpec_t;
1696 
1697 /**
1698  * An IPFIX Transport Session state container. Though Session creation and
1699  * lifetime are managed by the @ref fbCollector_t and @ref fbExporter_t types,
1700  * each @ref fBuf_t buffer uses this type to store session state, including
1701  * internal and external Templates and Message Sequence Number information.
1702  */
1703 typedef struct fbSession_st fbSession_t;
1704 
1705 /** Transport protocol for connection specifier. */
1706 typedef enum fbTransport_en {
1707     /**
1708      * Partially reliable datagram transport via SCTP.
1709      * Only available if fixbuf was built with SCTP support.
1710      */
1711     FB_SCTP,
1712     /** Reliable stream transport via TCP. */
1713     FB_TCP,
1714     /** Unreliable datagram transport via UDP. */
1715     FB_UDP,
1716     /**
1717      * Secure, partially reliable datagram transport via DTLS over SCTP.
1718      * Only available if fixbuf was built with OpenSSL support.
1719      * Requires an OpenSSL implementation of DLTS over SCTP, not yet available.
1720      */
1721     FB_DTLS_SCTP,
1722     /**
1723      * Secure, reliable stream transport via TLS over TCP.
1724      * Only available if fixbuf was built with OpenSSL support.
1725      */
1726     FB_TLS_TCP,
1727     /**
1728      * Secure, unreliable datagram transport via DTLS over UDP.
1729      * Only available if fixbuf was built with OpenSSL support.
1730      * Requires OpenSSL 0.9.8 or later with DTLS support.
1731      */
1732     FB_DTLS_UDP
1733 } fbTransport_t;
1734 
1735 /**
1736  * Connection specifier. Used to define a peer address for @ref
1737  * fbExporter_t, or a passive address for @ref fbListener_t.
1738  */
1739 typedef struct fbConnSpec_st {
1740     /** Transport protocol to use */
1741     fbTransport_t       transport;
1742     /** Hostname to connect/listen to. NULL to listen on all interfaces. */
1743     char                *host;
1744     /** Service name or port number to connect/listen to. */
1745     char                *svc;
1746     /** Path to certificate authority file. Only used for OpenSSL transport. */
1747     char                *ssl_ca_file;
1748     /** Path to certificate file. Only used for OpenSSL transport. */
1749     char                *ssl_cert_file;
1750     /** Path to private key file. Only used for OpenSSL transport. */
1751     char                *ssl_key_file;
1752     /** Private key decryption password. Only used for OpenSSL transport. */
1753     char                *ssl_key_pass;
1754     /**
1755      * Pointer to address info cache. Initialize to NULL.
1756      * For fixbuf internal use only.
1757      */
1758     void                *vai;
1759     /**
1760      * Pointer to SSL context cache. Initialize to NULL.
1761      * For fixbuf internal use only.
1762      */
1763     void                *vssl_ctx;
1764 } fbConnSpec_t;
1765 
1766 /**
1767  * Convenience macro defining a null static @ref fbConnSpec_t.
1768  */
1769 #define FB_CONNSPEC_INIT { FB_SCTP, NULL, NULL,         \
1770                            NULL, NULL, NULL, NULL,      \
1771                            NULL, NULL }
1772 
1773 #if HAVE_SPREAD
1774 
1775 /**
1776  * Initialization macro for @ref fbSpreadParams_t.
1777  */
1778 #define FB_SPREADPARAMS_INIT { 0, 0, 0 }
1779 
1780 /**
1781  * Spread connection parameters. Used to define a spread daemon and group
1782  * or list of groups for spread.
1783  */
1784 
1785 typedef struct fbSpreadParams_st {
1786     /** pointer to the session, this MUST be set to a valid session before
1787     *   the spec is passed to fbExporterAllocSpread(). */
1788     fbSession_t * session;
1789     /** pointer to the daemon host address, in Spread format.  Must be set
1790     *   before the spec is passed to fbExporterAllocSpread() */
1791     char *          daemon;
1792     /** pointer to array of group names, must have at least one, and must
1793     *   be null term array */
1794     char **         groups;
1795 } fbSpreadParams_t;
1796 
1797 #endif /* HAVE_SPREAD */
1798 
1799 /**
1800  * IPFIX Exporting Process endpoint. Used to export messages from an associated
1801  * IPFIX Message Buffer to a remote Collecting Process, or to an IPFIX File.
1802  * The internals of this structure are private to libfixbuf.
1803  */
1804 typedef struct fbExporter_st fbExporter_t;
1805 
1806 /**
1807  * IPFIX Collecting Process endpoint. Used to collect messages into an
1808  * associated IPFIX Message Buffer from a remote Exporting Process, or from
1809  * an IPFIX File. Use this with the @ref fbListener_t structure to
1810  * implement a full Collecting Process, including Transport Session
1811  * setup. The internals of this structure are private to libfixbuf.
1812  */
1813 typedef struct fbCollector_st fbCollector_t;
1814 
1815 /**
1816  * IPFIX Collecting Process session listener. Used to wait for connections
1817  * from IPFIX Exporting Processes, and to manage open connections via a
1818  * select(2)-based mechanism. The internals of this structure are private
1819  * to libfixbuf.
1820  */
1821 typedef struct fbListener_st fbListener_t;
1822 
1823 /*
1824  *  ListenerGroup and associated data type definitions
1825  */
1826 
1827 /**
1828  * Structure that represents a group of listeners.
1829  */
1830 typedef struct fbListenerGroup_st fbListenerGroup_t;
1831 
1832 /**
1833  *  ListenerEntry's make up an @ref fbListenerGroup_t as a linked list
1834  */
1835 typedef struct fbListenerEntry_st {
1836     /** pointer to the next listener entry in the linked list */
1837     struct fbListenerEntry_st  *next;
1838     /** pointer to the previous listener entry in the linked list */
1839     struct fbListenerEntry_st  *prev;
1840     /** pointer to the listener to add to the list */
1841     fbListener_t               *listener;
1842 } fbListenerEntry_t;
1843 
1844 /**
1845  * A ListenerGroupResult contains the fbListener whose listening socket got a
1846  * new connection (cf. fbListenerGroupWait()).  It is tied to the @ref fBuf_t
1847  * that is produced for the connection.  These comprise a linked list.
1848  */
1849 typedef struct fbListenerGroupResult_st {
1850     /** Pointer to the next listener group result */
1851     struct fbListenerGroupResult_st *next;
1852     /** pointer to the listener that received a new connection */
1853     fbListener_t                    *listener;
1854     /** pointer to the fbuf created for that new connection */
1855     fBuf_t                          *fbuf;
1856 } fbListenerGroupResult_t;
1857 
1858 /**
1859  * A callback function that is called when a template is freed.  This
1860  * function should be set during the @ref fbNewTemplateCallback_fn.
1861  *
1862  * @param tmpl_ctx a pointer to the ctx that is stored within the fbTemplate.
1863  *                 This is the context to be cleaned up.
1864  * @param app_ctx the app_ctx pointer that was passed to the
1865  *                fbSessionAddNewTemplateCallback() call.  This is for
1866  *                context only and should not be cleaned up.
1867  * @return NO return value
1868  */
1869 typedef void (*fbTemplateCtxFree_fn)(
1870     void           *tmpl_ctx,
1871     void           *app_ctx);
1872 
1873 /**
1874  * A callback function that will be called when the session receives
1875  * a new external template.  This callback can be used to assign an
1876  * internal template to an incoming external template for nested template
1877  * records using fbSessionAddTemplatePair() or to apply some context variable
1878  * to a template.
1879  *
1880  * The callback should be set using fbSessionAddNewTemplateCallback(), and
1881  * that function should be called after fbSessionAlloc().  Libfixbuf often
1882  * clones session upon receiving a connection (particularly in the UDP case
1883  * since a collector and fbuf can have multiple sessions), and this callback
1884  * is carried over to cloned sessions.
1885  *
1886  * @param session a pointer to the session that received the template
1887  * @param tid the template ID for the template that was received
1888  * @param tmpl pointer to the template information of the received template
1889  * @param app_ctx the app_ctx pointer that was passed to the
1890  *                fbSessionAddNewTemplateCallback() call
1891  * @param tmpl_ctx pointer that is stored in the fbTemplate structure.
1892  * @param tmpl_ctx_free_fn a callback function that should be called to
1893  *                 free the tmpl_ctx when the template is freed/replaced.
1894  * @return NO return value
1895  */
1896 typedef void (*fbNewTemplateCallback_fn) (
1897     fbSession_t           *session,
1898     uint16_t              tid,
1899     fbTemplate_t          *tmpl,
1900     void                  *app_ctx,
1901     void                  **tmpl_ctx,
1902     fbTemplateCtxFree_fn  *tmpl_ctx_free_fn);
1903 
1904 
1905 /**
1906  * The following Semantic values are for use in the structured Data Types:
1907  * basicLists, subTemplateLists, and subTemplateMultiLists.
1908  */
1909 /**
1910  * Semantic field for indicating the value has not been set
1911  */
1912 #define FB_LIST_SEM_UNDEFINED       0xFF
1913 /**
1914  * Semantic field for none-of value defined in RFC 6313
1915  */
1916 #define FB_LIST_SEM_NONE_OF         0x00
1917 /**
1918  * Semantic field for exactly-one-of value defined in RFC 6313
1919  */
1920 #define FB_LIST_SEM_EXACTLY_ONE_OF  0x01
1921 /**
1922  * Semantic field for the one-or-more-of value defined in RFC 6313
1923  */
1924 #define FB_LIST_SEM_ONE_OR_MORE_OF  0x02
1925 /**
1926  * Semantic field for the all-of value defined in RFC 6313
1927  */
1928 #define FB_LIST_SEM_ALL_OF          0x03
1929 /**
1930  * Semantic field for the ordered value defined in RFC 6313
1931  */
1932 #define FB_LIST_SEM_ORDERED         0x04
1933 
1934 /**
1935  * Validates the value of a structured data types semantic field, as defined
1936  * in RFC 6313 and listed at IANA.
1937  *
1938  * @param semantic The value of the semantic field to be checked
1939  * @return TRUE if valid (0xFF, 0x00-0x04), FALSE otherwise
1940  */
1941 gboolean fbListValidSemantic(
1942     uint8_t semantic);
1943 
1944 /****** BASICLIST FUNCTIONS AND STRUCTS *******/
1945 /**
1946  * A basic list element in a template which structure represents a
1947  * basic list on the internal side, basic lists in an IPFIX Message must
1948  * be represented by this structure within the application record.
1949  */
1950 typedef struct fbBasicList_st {
1951     /** pointer to the information element that is repeated in the list */
1952     const fbInfoElement_t   *infoElement;
1953     /** pointer to the memory that stores the elements in the list */
1954     uint8_t                 *dataPtr;
1955     /** number of elements in the list */
1956     uint16_t                numElements;
1957     /** length of the buffer used to store the elements in the list */
1958     uint16_t                dataLength;
1959     /** semantic field to describe the list */
1960     uint8_t                 semantic;
1961 } fbBasicList_t;
1962 
1963 
1964 /**
1965  * Allocates and returns an empty Basic List Structure.
1966  *
1967  * @return a pointer to the allocated basic list in memory
1968  */
1969 fbBasicList_t*  fbBasicListAlloc(
1970     void);
1971 
1972 /**
1973  * Initializes the basic list structure based on the parameters.
1974  * This function allocates a buffer large enough to hold
1975  * num elements amount of the infoElements.
1976  *
1977  * @param basicList a pointer to the basic list structure to fill
1978  * @param semantic the semantic value to be used in the basic list
1979  * @param infoElement a pointer to the info element to be used in the list
1980  * @param numElements number of elements in the list
1981  * @return a pointer to the memory where the list data is to be written
1982  */
1983 
1984 void* fbBasicListInit(
1985     fbBasicList_t          *basicList,
1986     uint8_t                 semantic,
1987     const fbInfoElement_t  *infoElement,
1988     uint16_t                numElements);
1989 
1990 /**
1991  *  use this function to initialize the basic list, but it gets the pointer
1992  *  to a buffer and its length allocated independently from these functions
1993  *  This will generally be used by a collector that does not want to
1994  *  free and allocate new buffers for each incoming message
1995  *
1996  * @param basicList a pointer to the basic list structure to fill
1997  * @param semantic the semantic value to be used in the basic list
1998  * @param infoElement a pointer to the info element to be used in the list
1999  * @param numElements number of elements in the list
2000  * @param dataLength length of the buffer passed to the function
2001  * @param dataPtr pointer to the buffer previously allocated for the list
2002  * @return a pointer to the beginning of the buffer on success, NULL on failure
2003  */
2004 void* fbBasicListInitWithOwnBuffer(
2005     fbBasicList_t          *basicList,
2006     uint8_t                 semantic,
2007     const fbInfoElement_t  *infoElement,
2008     uint16_t                numElements,
2009     uint16_t                dataLength,
2010     uint8_t                *dataPtr);
2011 
2012 /**
2013  * Initializes a basic list structure for collection.  The key
2014  * part of this function is it sets the dataPtr to NULL.
2015  * If your basic list is declared as a pointer, then allocated using
2016  * something like g_slice_alloc0 which sets it all to zero, you do not
2017  * need to call this function.  But if your basic list struct isn't
2018  * a pointer, there dataPtr parameter will be set to garbage, which will
2019  * break other fixbuf calls, so this function is required
2020  *
2021  * @param basicList pointer to the basic list to be initialized
2022  * @return NONE
2023  */
2024 void fbBasicListCollectorInit(
2025     fbBasicList_t  *basicList);
2026 
2027 /**
2028  * Returns the number of elements the basic list is capable of holding.
2029  * @param basicList pointer to the basic list
2030  * @return the number of elements on the basic list
2031  * @since libfixbuf 2.3.0
2032  */
2033 uint16_t fbBasicListCountElements(
2034     const fbBasicList_t    *basicList);
2035 
2036 /**
2037  *  Gets the Semantic field for Basic List.
2038  *  presumably used in collectors after decoding
2039  *
2040  *  @param basicList pointer to the basic list to retrieve the semantic from
2041  *  @return the 8-bit semantic value describing the basic list
2042  */
2043 uint8_t fbBasicListGetSemantic(
2044     fbBasicList_t  *basicList);
2045 
2046 /**
2047  *  Sets the semantic for describing a basic list.
2048  *  generally used in exporters before decoding
2049  *
2050  *  @param basicList pointer to the basic list to set the semantic
2051  *  @param semantic value to set the semantic field to
2052  *  @return NONE
2053  */
2054 void fbBasicListSetSemantic(
2055     fbBasicList_t  *basicList,
2056     uint8_t         semantic);
2057 
2058 /**
2059  * Returns a pointer to the information element used in the basic list.
2060  * It is mainly used in an @ref fbCollector_t to retrieve information.
2061  *
2062  * @param basicList pointer to the basic list to get the infoElement from
2063  * @return pointer to the information element from the list
2064  */
2065 const fbInfoElement_t*  fbBasicListGetInfoElement(
2066      fbBasicList_t  *basicList);
2067 
2068 /**
2069  * Gets a pointer to the data buffer for the basic list.
2070  * @param basicList pointer to the basic list to get the data pointer from
2071  * @return the pointer to the data held by the basic list
2072  */
2073 void* fbBasicListGetDataPtr(
2074     fbBasicList_t   *basicList);
2075 
2076 /**
2077  * Retrieves the element at position `index` in the basic list or returns NULL
2078  * if `index` is out of range.  The first element is at index 0, and the last
2079  * at fbBasicListCountElements()-1.
2080  * @param basicList pointer to the basic list to retrieve the dataPtr
2081  * @param index the index of the element to retrieve (0-based)
2082  * @return a pointer to the data in the index'th slot in the list, or NULL
2083  * if the index is past the bounds of the list
2084  */
2085 void* fbBasicListGetIndexedDataPtr(
2086     fbBasicList_t   *basicList,
2087     uint16_t         index);
2088 
2089 /**
2090  * Retrieves a pointer to the data element in the basicList that follows the
2091  * one at `currentPtr`.  Retrieves the first element if `currentPtr` is NULL.
2092  * Returns NULL when there are no more elements or when `currentPtr` is
2093  * outside the buffer used by the basic list.
2094  * @param basicList pointer to the basic list
2095  * @param currentPtr pointer to the current element being used.  Set to NULL
2096  * to retrieve the first element.
2097  * @return a pointer to the next data slot, based on the current pointer.
2098  * NULL if the new pointer is passed the end of the buffer
2099  */
2100 void* fbBasicListGetNextPtr(
2101     fbBasicList_t   *basicList,
2102     void            *currentPtr);
2103 
2104 /**
2105  * Potentially reallocates the list's internal buffer and returns a handle to
2106  * it.  Specifically, when `newNumElements` differs from
2107  * fbBasicListCountElements(), frees the current buffer that holds the
2108  * elements, allocates a new buffer to accomodate `newNumElements` elements,
2109  * and returns the buffer.  The remaining parameters or the list are
2110  * unchanged.  If the number of elements are the same, the existing buffer is
2111  * returned.
2112  * @param basicList pointer to the basic list to realloc
2113  * @param newNumElements new number of elements to allocate for the list
2114  * @return pointer to the data pointer for the list after realloc
2115  * @see fbBasicListAddNewElements() to add elements to an existing list.
2116  */
2117 void* fbBasicListRealloc(
2118     fbBasicList_t  *basicList,
2119     uint16_t        newNumElements);
2120 
2121 /**
2122  *  Allocates `numNewElements` additional element(s) into the basic list.
2123  *  May only be called after calling fbBasicListInit().
2124  * @param basicList pointer to the basic list to add elements to
2125  * @param numNewElements number of elements to add to the list
2126  * @return a pointer to the newly allocated element(s)
2127  */
2128 void* fbBasicListAddNewElements(
2129     fbBasicList_t  *basicList,
2130     uint16_t        numNewElements);
2131 
2132 /**
2133  * Clears the parameters of the basic list and frees the data buffer.  To
2134  * re-use the basicList after this call, it must be re-initialized via
2135  * fbBasicListInit() or fbBasicListCollectorInit().
2136  * @param basicList pointer to the basic list to clear
2137  * @return NONE
2138  * @see fBufListFree()
2139  */
2140 void fbBasicListClear(
2141     fbBasicList_t  *basicList);
2142 
2143 /**
2144  * Clears the parameters of the basic list, but does not free the buffer.
2145  * This should get used when the user provides their own buffer
2146  * (fbBasicListInitWithOwnBuffer()).
2147  * @param basicList pointer to the basic list to clear without freeing
2148  * @return NONE
2149  */
2150 void fbBasicListClearWithoutFree(
2151     fbBasicList_t  *basicList);
2152 
2153 /**
2154  * Clears the basic list (fbBasicListClear()), then frees the basic list
2155  * itself.  This is typically paired with fbBasicListAlloc(), and it not
2156  * normally needed.
2157  * @param basicList pointer to the basic list to free
2158  * @return NONE
2159  */
2160 void fbBasicListFree(
2161     fbBasicList_t  *basicList);
2162 
2163 
2164 /******* END OF BASICLIST ********/
2165 
2166 
2167 
2168 /******* SUBTEMPLATELIST FUNCTIONS ****/
2169 
2170 /**
2171  * Structure used to hold information of a sub template list.
2172  * This structure is filled in by the user in an exporter to tell
2173  * fixbuf how to encode the data.
2174  * This structure is filled in by the transcoder in a collector,
2175  * feeding the useful information up to the user
2176  */
2177 typedef struct fbSubTemplateList_st {
2178     /** length of the allocated buffer used to hold the data */
2179     /** I made this a union to allow this to work on 64-bit archs */
2180     union {
2181         size_t          length;
2182         uint64_t        extra;
2183     } dataLength;
2184     /** pointer to the template used to structure the data */
2185     const fbTemplate_t  *tmpl;
2186     /** pointer to the buffer used to hold the data */
2187     uint8_t             *dataPtr;
2188     /** ID of the template used to structure the data */
2189     uint16_t            tmplID;
2190     /** number of elements in the list */
2191     uint16_t            numElements;
2192     /** value used to describe the contents of the list, all-of, one-of, etc*/
2193     uint8_t             semantic;
2194 } fbSubTemplateList_t;
2195 
2196 /**
2197  *  Allocates and returns an empty subTemplateList structure.
2198  *  Based on how subTemplateLists will be used and set up amidst data
2199  *  structures, this function may never be used.
2200  * @return pointer to the new sub template list
2201  */
2202 fbSubTemplateList_t* fbSubTemplateListAlloc(
2203     void);
2204 
2205 /**
2206  *  Initializes a subTemplateList structure and allocates the internal buffer
2207  *  to a size capable of holding `numElements` records matching the template.
2208  *  This is mainly used when preparing to encode data for output by an @ref
2209  *  fbExporter_t.  When reading data, use fbSubTemplateListCollectorInit() to
2210  *  initialize the subTemplateList.  The `tmpl` should exist on the @ref
2211  *  fbSession_t that will be used when exporting the record holding this
2212  *  subTemplateList.
2213  *
2214  * @param sTL pointer to the sub template list to initialize
2215  * @param semantic the semantic value used to describe the list contents
2216  * @param tmplID id of the template used for encoding the list data
2217  * @param tmpl pointer to the template struct used for encoding the list data
2218  * @param numElements number of elements in the list
2219  * @return a pointer to the allocated buffer (location of first element)
2220  * @see fbSubTemplateListInitWithOwnBuffer() to manage the memory yourself.
2221  */
2222 void* fbSubTemplateListInit(
2223     fbSubTemplateList_t    *sTL,
2224     uint8_t                 semantic,
2225     uint16_t                tmplID,
2226     const fbTemplate_t     *tmpl,
2227     uint16_t                numElements);
2228 
2229 /**
2230  *  Initializes the subTemplateList but does not allocate a buffer.  It
2231  *  accepts a previously allocated buffer and data length and uses it.
2232  *  This will generally be used in collectors providing their own buffer
2233  *
2234  * @param subTemplateList pointer to the sub template list to initialize
2235  * @param semantic the semantic value used to describe the list contents
2236  * @param tmplID id of the template used for encoding the list data
2237  * @param tmpl pointer to the template struct used for encoding the list data
2238  * @param numElements number of elements in the list
2239  * @param dataLength length of the data buffer
2240  * @param dataPtr pointer to the previously allocated data buffer
2241  * @returns a pointer to that buffer
2242  * @see fbSubTemplateListInit() to have libfixbuf manage the memory.
2243  */
2244 void* fbSubTemplateListInitWithOwnBuffer(
2245     fbSubTemplateList_t    *subTemplateList,
2246     uint8_t                 semantic,
2247     uint16_t                tmplID,
2248     const fbTemplate_t     *tmpl,
2249     uint16_t                numElements,
2250     uint16_t                dataLength,
2251     uint8_t                *dataPtr);
2252 
2253 /**
2254  * Initializes a sub template list variable on a @ref fbCollector_t.  If the
2255  * fbSubTemplateList variable is in a struct, it will likely not be set to 0's
2256  * If not, the dataPtr will not be NULL, so the transcoder will not allocate
2257  * the right memory for it, as it will assuming it's set up.  This will break.
2258  * Call this function right after declaring the struct variable that contains
2259  * the fbSubTemplateList.  It only needs to be called once for each STL.
2260  *
2261  * When using an @ref fbExporter_t, use fbSubTemplateListInit() to initialize
2262  * the subTemplateList.
2263  *
2264  * @param STL pointer to the sub template list to initialize for collection
2265  * @return NONE
2266  */
2267 void fbSubTemplateListCollectorInit(
2268     fbSubTemplateList_t    *STL);
2269 
2270 /**
2271  * Returns a pointer to the buffer that contains the data for the list
2272  * @param subTemplateList pointer to the STL to get the pointer from
2273  * @return a pointer to the data buffer used by the sub template list
2274  */
2275 void* fbSubTemplateListGetDataPtr(
2276     const fbSubTemplateList_t  *subTemplateList);
2277 
2278 /**
2279  * Returns the data for the record at position `index` in the sub template
2280  * list, or returns NULL if `index` is out of range.  The first element is at
2281  * index 0, the last at fbSubTemplateListCountElements()-1.
2282  *
2283  * @param subTemplateList pointer to the STL
2284  * @param index The index of the element to be retrieved (0-based)
2285  * @return a pointer to the desired element, or NULL when out of range
2286  */
2287 void* fbSubTemplateListGetIndexedDataPtr(
2288     const fbSubTemplateList_t  *subTemplateList,
2289     uint16_t                    index);
2290 
2291 /**
2292  * Retrieves a pointer to the data record in the sub template list that
2293  * follows the one at `currentPtr`.  Retrieves the first record if
2294  * `currentPtr` is NULL.  Returns NULL when there are no more records or when
2295  * `currentPtr` is outside the buffer used by the sub template list.
2296  * @param subTemplateList pointer to the STL to get data from
2297  * @param currentPtr pointer to the last element accessed.  NULL causes the
2298  *                   pointer to the first element to be returned
2299  * @return the pointer to the next element in the list.  Returns NULL if
2300  *         currentPtr points to the last element in the list.
2301  */
2302 void* fbSubTemplateListGetNextPtr(
2303     const fbSubTemplateList_t  *subTemplateList,
2304     void                       *currentPtr);
2305 
2306 /**
2307  * Returns the number of elements the sub template list is capable of holding.
2308  * @param subTemplateList pointer to the sub template list
2309  * @return the number of records on the sub template list
2310  * @since libfixbuf 2.3.0
2311  */
2312 uint16_t fbSubTemplateListCountElements(
2313     const fbSubTemplateList_t  *subTemplateList);
2314 
2315 /**
2316  * Sets the semantic parameter of a subTemplateList
2317  * @param subTemplateList pointer to the sub template list
2318  * @param semantic Semantic value for the list
2319  * @return NONE
2320  */
2321 void fbSubTemplateListSetSemantic(
2322     fbSubTemplateList_t    *subTemplateList,
2323     uint8_t                 semantic);
2324 
2325 /**
2326  * Gets the semantic value from a sub template list
2327  * @param subTemplateList pointer to the sub template list
2328  * @return the semantic field from the list
2329  */
2330 uint8_t fbSubTemplateListGetSemantic(
2331     fbSubTemplateList_t    *subTemplateList);
2332 
2333 /**
2334  * Gets the template pointer from the list structure
2335  * @param subTemplateList pointer to the sub template list
2336  * @return a pointer to the template used by the sub template list
2337  */
2338 const fbTemplate_t* fbSubTemplateListGetTemplate(
2339     fbSubTemplateList_t    *subTemplateList);
2340 
2341 /**
2342  * Gets the template ID for the template used by the list
2343  * @param subTemplateList pointer to the sub template list
2344  * @return the template ID used by the sub template list
2345  */
2346 uint16_t fbSubTemplateListGetTemplateID(
2347     fbSubTemplateList_t    *subTemplateList);
2348 
2349 /**
2350  * Potentially reallocates the list's internal buffer and returns a handle to
2351  * it.  Specifically, when `newNumElements` differs from
2352  * fbSubTemplateListCountElements(), frees the sub template list's internal
2353  * data-record buffer, allocates a new buffer to accomodate `newNumElements`
2354  * elements, and returns the buffer.  The remaining parameters of the sub
2355  * template list are unchanged.  If the number of elements are the same, the
2356  * existing buffer is returned.  This function does not free any recursive
2357  * structured-data records used by the existing buffer before reallocating it.
2358  *
2359  * @param subTemplateList pointer to the sub template list to realloc
2360  * @param newNumElements value for the new number of elements for the list
2361  * @return pointer to the data buffer after realloc
2362  * @see fbSubTemplateListAddNewElements() to add elements to an existing list.
2363  */
2364 void* fbSubTemplateListRealloc(
2365     fbSubTemplateList_t    *subTemplateList,
2366     uint16_t                newNumElements);
2367 
2368 /**
2369  * Allocates space for `numNewElements` additional element in the
2370  * subTemplateList.  May only be called after the list has been initialized
2371  * with fbSubTemplateListInit().
2372  *
2373  * @param subTemplateList pointer to the sub template list
2374  * @param numNewElements number of new elements to add to the list
2375  * @return a pointer to the first newly allocated element
2376  */
2377 void* fbSubTemplateListAddNewElements(
2378     fbSubTemplateList_t    *subTemplateList,
2379     uint16_t                numNewElements);
2380 
2381 /**
2382  * Clears a subTemplateList structure, notably freeing the internal buffer and
2383  * setting it to NULL.
2384  *
2385  * This should be used after each call to fBufNext():
2386  * If the dataPtr is not NULL in DecodeSubTemplateList, it will not allocate
2387  * new memory for the new record, which could cause a buffer overflow if the
2388  * new record has a longer list than the current one.
2389  * An alternative is to allocate a large buffer and assign it to dataPtr
2390  * on your own, then never clear it with this.  Be certain this buffer is
2391  * longer than needed for all possible lists
2392  * @param subTemplateList pointer to the sub template list to clear
2393  * @return NONE
2394  * @see fBufListFree()
2395  */
2396 void fbSubTemplateListClear(
2397     fbSubTemplateList_t    *subTemplateList);
2398 
2399 /**
2400  *  Clears the sub template list parameters but does not free the data ptr.
2401  *  This is used in conjuction with fbSubTemplateListInitWithOwnBuffer()
2402  *  because that buffer is allocated at the beginning by the user and will be
2403  *  freed at the end by the user, outside of fixbuf api calls
2404  * @param subTemplateList pointer to the sub template list to clear
2405  * @return NONE
2406  */
2407 void fbSubTemplateListClearWithoutFree(
2408     fbSubTemplateList_t    *subTemplateList);
2409 
2410 /**
2411  *  Clears the sub template list (fbSubTemplateListClear()) then frees the
2412  *  subTemplateList itself.  This is typically paired with
2413  *  subTemplateListAlloc(), and it is unlikely to be used.
2414  *
2415  * @param subTemplateList pointer to the sub template list to free
2416  * @return NONE
2417  */
2418 void fbSubTemplateListFree(
2419     fbSubTemplateList_t    *subTemplateList);
2420 
2421 /********* END OF SUBTEMPLATELIST **********/
2422 /**
2423  *  Entries contain the same type of information at SubTemplateLists:
2424  *  template ID and template pointers to describe the data
2425  *  the number of data elements and the data pointer and data length
2426  *
2427  * Sub template multi lists are inherently nested constructions.
2428  * At a high level, they are a list of sub template lists.
2429  * The first level is a list of fbSubTemplateMultiListEntry_t's, which each
2430  * contain the information that describes the data contained in them.
2431  * Initializing a @ref fbSubTemplateMultiList_t with a semantic and number of
2432  * elements returns memory that contains numElements blocks of memory
2433  * containing fbSubTemplateMultiListEntry_t's.  It is not ready to accept
2434  * data.  Each of the fbSubTemplateMultiListEntry_t's needed to be set up
2435  * then data is copied into the entries.
2436  */
2437 
2438 
2439 typedef struct fbSubTemplateMultiListEntry_st {
2440     /** pointer to the template used to structure the data in this entry */
2441     fbTemplate_t   *tmpl;
2442     /** pointer to the buffer used to hold the data in this entry */
2443     uint8_t        *dataPtr;
2444     /** length of the buffer used to hold the data in this entry */
2445     size_t          dataLength;
2446     /** ID of the template used to structure the data in this entry */
2447     uint16_t        tmplID;
2448     /** number of elements in this entry */
2449     uint16_t        numElements;
2450 } fbSubTemplateMultiListEntry_t;
2451 
2452 /**
2453  * Multilists just contain the semantic to describe the sub lists,
2454  * the number of sub lists, and a pointer to the first entry
2455  */
2456 typedef struct fbSubTemplateMultiList_st {
2457     /** pointer to the first entry in the multi list */
2458     fbSubTemplateMultiListEntry_t  *firstEntry;
2459     /** number of sub template lists in the multi list */
2460     uint16_t                        numElements;
2461     /** value used to describe the list of sub templates */
2462     uint8_t                         semantic;
2463 } fbSubTemplateMultiList_t;
2464 
2465 
2466 /**
2467  *  Allocates and returns an empty subTemplateMultiList structure.
2468  *  Based on how subTemplateMultiLists will be used and
2469  *  set up amidst data structures, this function may never be used.
2470  *
2471  *  @return pointer to the new sub template multi list
2472  */
2473 fbSubTemplateMultiList_t* fbSubTemplateMultiListAlloc(
2474     void);
2475 
2476 
2477 /**
2478  *  Initializes the multi list with the list semantic and allocates memory to
2479  *  store `numElements` entries.
2480  *
2481  * @param STML pointer to the sub template multi list to initialize
2482  * @param semantic value used to describe the entries in the multi list
2483  * @param numElements number of entries in the multi list
2484  * @return pointer to the first uninitialized entry
2485  */
2486 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListInit(
2487     fbSubTemplateMultiList_t   *STML,
2488     uint8_t                     semantic,
2489     uint16_t                    numElements);
2490 
2491 /**
2492  * Returns the number of entries the sub template multi list is capable of
2493  * holding.
2494  * @param STML pointer to the sub template multi list
2495  * @return the number of entries on the sub template multi list
2496  * @since libfixbuf 2.3.0
2497  */
2498 uint16_t fbSubTemplateMultiListCountElements(
2499     const fbSubTemplateMultiList_t *STML);
2500 
2501 /**
2502  * Sets the semantic field for the multi list
2503  * @param STML pointer to the sub template multi list
2504  * @param semantic Value for the semantic field of the sub template multi list
2505  * @return NONE
2506  */
2507 void fbSubTemplateMultiListSetSemantic(
2508     fbSubTemplateMultiList_t   *STML,
2509     uint8_t                     semantic);
2510 
2511 /**
2512  * Gets the semantic paramter from the multi list
2513  * @param STML pointer to the sub template multi list
2514  * @return semantic parameter describing the contents of the multi list
2515  */
2516 uint8_t fbSubTemplateMultiListGetSemantic(
2517     fbSubTemplateMultiList_t   *STML);
2518 
2519 /**
2520  * Clears all of the @ref fbSubTemplateMultiListEntry_t objects on this STML
2521  * (see fbSubTemplateMultiListClearEntries()), then frees the memory
2522  * containing the entries.
2523  * @param STML pointer to the sub template mutli list to clear
2524  * @return NONE
2525  * @see fBufListFree()
2526  */
2527 void fbSubTemplateMultiListClear(
2528     fbSubTemplateMultiList_t   *STML);
2529 
2530 /**
2531  * Clears the memory used by all the entries of a sub template multi list.
2532  * That is, it calls fbSubTemplateMultiListEntryClear() for each entry.  To
2533  * free the memory in the STML that holds these entries, call
2534  * fbSubTemplateMultiListClear().
2535  *
2536  * @note If any of the entries contain another layer of structures, that
2537  * second layer must be freed by the user, as this function cannot do that.
2538  * For example, if an entry's template contains an element of type basicList,
2539  * the memory used by that basicList is not freed by this function.
2540  *
2541  * @param STML pointer to the sub template multi list
2542  * @return NONE
2543  */
2544 void fbSubTemplateMultiListClearEntries(
2545     fbSubTemplateMultiList_t   *STML);
2546 
2547 /**
2548  * Clears the multi list (fbSubTemplateMultiListClear()), then frees the STML
2549  * itself.  This is typically paired with fbSubTemplateMultiListAlloc(), and
2550  * it not normally needed.
2551  * @param STML pointer to the sub template multi list
2552  * @return NONE
2553  */
2554 void fbSubTemplateMultiListFree(
2555     fbSubTemplateMultiList_t   *STML);
2556 
2557 /**
2558  *  Potentially reallocates the list's internal buffer for entries and returns
2559  *  a handle to it.  Specifically, calls fbSubTemplateMultiListClearEntries(),
2560  *  then if `newNumElements` differs from
2561  *  fbSubTemplateMultiListCountElements(), frees the entries buffer, allocates
2562  *  a new one to accomodate `newNumElements` entries, and returns the buffer.
2563  *  If the number of elements are the same, the existing buffer is returned.
2564  *
2565  * @param STML pointer to the sub template mutli list
2566  * @param newNumEntries the new number of entries for the STML
2567  * @return pointer to the first entry
2568  * @see fbSubTemplateMultiListAddNewEntries() to add additional entries to an
2569  * existing STML.
2570  */
2571 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListRealloc(
2572     fbSubTemplateMultiList_t   *STML,
2573     uint16_t                    newNumEntries);
2574 
2575 /**
2576  *  Adds `numNewElements` entries to the multi list of entries.  May only
2577  *  be used after the list has been initialized.
2578  *
2579  * @param STML pointer to the sub template multi list
2580  * @param numNewEntries number of entries to add to the list
2581  * @return a pointer to the new entry
2582  */
2583 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListAddNewEntries(
2584     fbSubTemplateMultiList_t   *STML,
2585     uint16_t                    numNewEntries);
2586 
2587 /**
2588  * Retrieves the first entry in the multi list.
2589  * @param STML pointer to the sub template multi list
2590  * @return pointer to the first entry used by the list
2591  */
2592 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListGetFirstEntry(
2593     fbSubTemplateMultiList_t   *STML);
2594 
2595 /**
2596  * Retrieves a pointer to the entry at a specific index, or returns NULL if
2597  * `index` is out of range.  The first entry is at index 0, the last at
2598  * fbSubTemplateMultiListCountElements()-1.
2599  * @param STML pointer to the sub template mutli list
2600  * @param index index of the entry to be returned (0-based)
2601  * @return the index'th entry used by the list, or NULL if out of range
2602  */
2603 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListGetIndexedEntry(
2604     fbSubTemplateMultiList_t   *STML,
2605     uint16_t                    index);
2606 
2607 /**
2608  * Retrieves a pointer to the entry in the mutli list that follows the one at
2609  * `currentEntry`.  Retrieves the first entry if `currentEntry` is NULL.
2610  * Returns NULL when there are no more entries or when `currentEntry` is
2611  * outside the buffer used by the multi list.
2612  * @param STML pointer to the sub template multi list to get data from
2613  * @param currentEntry pointer to the last element accessed.
2614  *                     NULL means none have been accessed yet
2615  * @return the pointer to the next element in the list.  Returns the NULL
2616  *         if currentEntry points to the last entry.
2617  */
2618 fbSubTemplateMultiListEntry_t* fbSubTemplateMultiListGetNextEntry(
2619     fbSubTemplateMultiList_t       *STML,
2620     fbSubTemplateMultiListEntry_t  *currentEntry);
2621 
2622 /**
2623  *  Initializes the multi list entry with the template values, and allocates
2624  *  the memory used by the entry to hold the data.  This is mainly used when
2625  *  preparing to encode data for output by an @ref fbExporter_t.  The `tmpl`
2626  *  should exist on the @ref fbSession_t that will be used when exporting the
2627  *  record holding the subTemplateMultiList.
2628  *
2629  *  @param entry pointer to the entry to initialize
2630  *  @param tmplID ID of the template used to structure the data elements
2631  *  @param tmpl pointer to the template used to structure the data elements
2632  *  @param numElements number of data elements in the entry
2633  *
2634  *  @return pointer to the data buffer to be filled in
2635  */
2636 void* fbSubTemplateMultiListEntryInit(
2637     fbSubTemplateMultiListEntry_t  *entry,
2638     uint16_t                        tmplID,
2639     fbTemplate_t                   *tmpl,
2640     uint16_t                        numElements);
2641 
2642 /**
2643  *  Potentially reallocates the entry's internal buffer and returns a handle
2644  *  to it.  Specifically, when `newNumEntries` differs from
2645  *  fbSubTemplateMultiListEntryCountElements(), frees the buffer used to store
2646  *  the entry's data records, allocates a new buffer based on the size of the
2647  *  template and `newNumElements`, and returns a handle to that buffer.  The
2648  *  template of the entry is unchanged.  If the number of elements are the
2649  *  same, the existing buffer is returned.  This function does not free any
2650  *  recursive structured-data records used by the existing buffer before
2651  *  reallocating it.
2652  *
2653  *  @param entry pointer to the entry to realloc
2654  *  @param newNumElements the new number of elements for the entry
2655  *  @return pointer to buffer to write data to
2656  *  @see fbSubTemplateMultiListEntryAddNewElements() to add additional
2657  *  elements to an existing sub template multi list entry.
2658  */
2659 void* fbSubTemplateMultiListEntryRealloc(
2660     fbSubTemplateMultiListEntry_t  *entry,
2661     uint16_t                        newNumElements);
2662 
2663 /**
2664  *  Allocates space for `numNewEntries` additional elements in the sub
2665  *  template multi list entry.  May only be called after the STML entry
2666  *  has been initialized with fbSubTemplateMultiListEntryInit().
2667  *
2668  *  @param entry pointer to the STML entry to add additional elements to
2669  *  @param numNewElements number of new elements to add to the STML entry
2670  *  @return a pointer to the first newly allocated element
2671  */
2672 void* fbSubTemplateMultiListEntryAddNewElements(
2673     fbSubTemplateMultiListEntry_t   *entry,
2674     uint16_t                         numNewElements);
2675 
2676 /**
2677  *  Frees the memory holding the records' data used by this entry.  Use @ref
2678  *  fbSubTemplateMultiListClearEntries() to clear all entries in an @ref
2679  *  fbSubTemplateMultiList_t, and fbSubTemplateMultiListClear() to clear the
2680  *  entire sub template multi list.
2681  *
2682  *  @param entry pointer to the entry to clear the contents of.
2683  *  @return NONE
2684  */
2685 void fbSubTemplateMultiListEntryClear(
2686     fbSubTemplateMultiListEntry_t   *entry);
2687 
2688 /**
2689  * Retrieves the data pointer for this entry.
2690  *
2691  * @param entry pointer to the entry to get the data pointer from
2692  * @return pointer to the buffer used to store data for this entry
2693  */
2694 void* fbSubTemplateMultiListEntryGetDataPtr(
2695     fbSubTemplateMultiListEntry_t   *entry);
2696 
2697 /**
2698  * Retrieves a pointer to the data record in this entry that follows the one
2699  * at `currentPtr`.  Retrieves the first record if `currentPtr` is NULL.
2700  * Returns NULL when there are no more records or when `currentPtr` is outside
2701  * the buffer used by the multi list entry.
2702  * @param entry pointer to the entry to get the next element from
2703  * @param currentPtr pointer to the last element accessed.  NULL means return
2704                      a pointer to the first element.
2705  * @return the pointer to the next element in the list.  Returns NULL if
2706  *         currentPtr points to the last element in the list
2707  */
2708 void* fbSubTemplateMultiListEntryNextDataPtr(
2709     fbSubTemplateMultiListEntry_t   *entry,
2710     void                            *currentPtr);
2711 
2712 /**
2713  * Retrieves a pointer to the data element in the entry at position `index`,
2714  * or returns NULL when `index` is out of range.  The first element is at
2715  * index 0, the last at fbSubTemplateMultiListEntryCountElements()-1.
2716  *
2717  * @param entry pointer to the entry to get a data pointer from.
2718  * @param index the number of the element in the list to return
2719  * @return the pointer to the index'th element used by the entry, or NULL when
2720  *         out of range
2721  */
2722 void* fbSubTemplateMultiListEntryGetIndexedPtr(
2723     fbSubTemplateMultiListEntry_t   *entry,
2724     uint16_t                         index);
2725 
2726 /**
2727  * Returns the number of entries the sub template multi list entry is capable
2728  * of holding.
2729  * @param entry pointer to the sub template multi list entry
2730  * @return the number of records on the sub template multi list entry
2731  * @since libfixbuf 2.3.0
2732  */
2733 uint16_t fbSubTemplateMultiListEntryCountElements(
2734     const fbSubTemplateMultiListEntry_t  *entry);
2735 
2736 /**
2737  * Retrieves the template pointer used to structure the data elements.
2738  *
2739  * @param entry pointer to the entry to get the template from
2740  * @return the template pointer used to describe the contents of the entry
2741  */
2742 const fbTemplate_t* fbSubTemplateMultiListEntryGetTemplate(
2743     fbSubTemplateMultiListEntry_t   *entry);
2744 
2745 /**
2746  * Retrieves the template ID for the template used to structure the data.
2747  *
2748  * @param entry pointer to the entry to get the template ID from
2749  * @returns the template ID for template that describes the data
2750  */
2751 uint16_t fbSubTemplateMultiListEntryGetTemplateID(
2752     fbSubTemplateMultiListEntry_t   *entry);
2753 
2754 /************** END OF STML FUNCTIONS *********** */
2755 
2756 /**
2757  * Clears all of the memory that fixbuf allocated during transcode of this
2758  * record.  This frees all of the memory allocated for list structures,
2759  * recursively, when fixbuf was encoding or decoding the record.
2760  *
2761  * The template provided is the internal
2762  * template that was set on the fBuf before fBufNext() or
2763  * fBufAppend() was called with the data.  The template MUST
2764  * match the record or bad things WILL happen without indication.
2765  * This does not free the record itself.  It will only free any
2766  * list information elements and nested list information elements.
2767  *
2768  * @param tmpl pointer to the internal template that MUST match the record
2769  * @param record pointer to the data
2770  * @return NONE
2771  */
2772 void fBufListFree(
2773     fbTemplate_t     *tmpl,
2774     uint8_t          *record);
2775 
2776 
2777 /**
2778  * Allocates and returns an empty listenerGroup.  Use
2779  * fbListenerGroupAddListener() to populate the listenerGroup,
2780  * fbListenerGroupWait() to wait for connections on those listeners, and
2781  * fbListenerGroupFree() when the group is no longer needed.
2782  *
2783  * @return a pointer to the created fbListenerGroup_t, or NULL on error
2784  */
2785 fbListenerGroup_t* fbListenerGroupAlloc(
2786     void);
2787 
2788 /**
2789  * Frees a listener group
2790  *
2791  * @param group fbListenerGroup
2792  * @return nothing
2793  */
2794 void fbListenerGroupFree(
2795     fbListenerGroup_t *group);
2796 
2797 /**
2798  * Adds a previously allocated listener to the previously allocated group.
2799  * The listener is placed at the head of the list
2800  *
2801  * @param group pointer to the allocated group to add the listener to
2802  * @param listener pointer to the listener structure to add to the group
2803  * @return 0 upon success. "1" if entry couldn't be allocated
2804  *         "2" if either of the incoming pointers are NULL
2805  */
2806 int fbListenerGroupAddListener(
2807     fbListenerGroup_t          *group,
2808     const fbListener_t         *listener);
2809 
2810 /**
2811  * Removes the listener from the group.
2812  * IT DOES NOT FREE THE LISTENER OR THE GROUP
2813  *
2814  * @param group pointer to the group to remove from the listener from
2815  * @param listener pointer to the listener to remove from the group
2816  * @return 0 on success, and "1" if the listener is not found
2817  *         "2" if either of the pointers are NULL
2818  */
2819 int fbListenerGroupDeleteListener(
2820     fbListenerGroup_t          *group,
2821     const fbListener_t         *listener);
2822 
2823 /**
2824  *  Accepts connections for multiple listeners.  Works similarly to
2825  *  fbListenerWait(), except that is looks for connections for any listener
2826  *  that is part of a previously allocated and filled listener group.  It
2827  *  returns a pointer to the head of a list of listenerGroupResults.  The
2828  *  caller is responsible for freeing the listenerGroupResult
2829  *  (fbListenerFreeGroupResult()).
2830  *  @param group pointer to the group of listeners to wait on
2831  *  @param err error string structure seen throughout fixbuf
2832  *  @return pointer to the head of the listener group result list
2833  *          NULL on error, and sets the error string
2834  */
2835 fbListenerGroupResult_t* fbListenerGroupWait(
2836     fbListenerGroup_t          *group,
2837     GError                     **err);
2838 
2839 /**
2840  * Frees the listener group result returned from fbListenerGroupWait().
2841  *
2842  * @param result    A listener group result
2843  */
2844 void fbListenerFreeGroupResult(
2845     fbListenerGroupResult_t *result);
2846 
2847 /**
2848  *  Returns an fBuf wrapped around an independently managed socket and a
2849  *  properly created listener for TCP connections.
2850  *  The caller is only responsible for creating the socket.
2851  *  The existing collector code will close the socket and cleanup everything.
2852  *
2853  *  @param listener pointer to the listener to wrap around the socket
2854  *  @param sock the socket descriptor of the independently managed socket
2855  *  @param err standard fixbuf err structure pointer
2856  *  @return pointer to the fbuf for the collector.
2857  *          NULL if sock is 0, 1, or 2 (stdin, stdout, or stderr)
2858  */
2859 fBuf_t  *fbListenerOwnSocketCollectorTCP(
2860     fbListener_t   *listener,
2861     int             sock,
2862     GError        **err);
2863 
2864 /**
2865  *  Same as fbListenerOwnSocketCollectorTCP() but for TLS (not tested)
2866  *
2867  *  @param listener pointer to the listener to wait on
2868  *  @param sock independently managed socket descriptor
2869  *  @param err standard fixbuf err structure pointer
2870  *  @return pointer to the fbuf for the collector
2871  *          NULL if sock is 0, 1, or 2 (stdin, stdout, or stderr)
2872  */
2873 fBuf_t  *fbListenerOwnSocketCollectorTLS(
2874     fbListener_t   *listener,
2875     int             sock,
2876     GError        **err);
2877 
2878 /**
2879  *  Interrupts the select call of a specific collector by way of its fBuf.
2880  *  This is mainly used by fbListenerInterrupt() to interrupt all of the
2881  *  collector sockets well.
2882  */
2883 void    fBufInterruptSocket(
2884     fBuf_t         *fbuf);
2885 
2886 
2887 /**
2888  * Application context initialization function type for fbListener_t.
2889  * Set this function when creating the fbListener_t with fbListenerAlloc().
2890  * This function is called after accept(2) for TCP or SCTP with the peer
2891  * address in the peer argument. For UDP, it is called during fbListener_t
2892  * initialization and the peer address will be NULL.  If the Collector is in
2893  * multi-session mode, the appinit function will be called when a new UDP
2894  * connection occurs with the peer address, similiar to the TCP case.  Use
2895  * fbCollectorSetUDPMultiSession() to turn on multi-session mode
2896  * (off by default).  The application may veto @ref fbCollector_t creation by
2897  * returning FALSE. In multi-session mode, if the connection is to be ignored,
2898  * the application should set error code FB_ERROR_NLREAD on the err and return
2899  * FALSE.  If the application returns FALSE, fixbuf will maintain information
2900  * about that peer, and will reject connections from that peer until shutdown
2901  * or until that session times out.  Fixbuf will return FB_ERROR_NLREAD for
2902  * previously rejected sessions.
2903  * The context (returned via out-parameter ctx) will be
2904  * stored in the fbCollector_t, and is retrievable via a call to
2905  * fbCollectorGetContext().  If not in multi-session mode and using the appinit
2906  * fn, the ctx will be associated with all UDP sessions.
2907  */
2908 typedef gboolean        (*fbListenerAppInit_fn) (
2909     fbListener_t                *listener,
2910     void                        **ctx,
2911     int                         fd,
2912     struct sockaddr             *peer,
2913     size_t                      peerlen,
2914     GError                      **err);
2915 
2916 /**
2917  * Application context free function type for @ref fbListener_t.
2918  * Set this function when creating the fbListener_t with fbListenerAlloc().
2919  * For TCP and SCTP collectors, this is called when the connection is closed.
2920  * If a UDP Collector is in multi-session mode (see appinit fn), then the
2921  * appfree function is called if a session is timed out (does not receive
2922  * a UDP message for more than 30 minutes.)  Called during @ref fbCollector_t
2923  * cleanup.
2924  */
2925 typedef void            (*fbListenerAppFree_fn) (
2926     void                        *ctx);
2927 
2928 /*
2929  * Public Function Calls. These calls will remain available and retain
2930  * their functionality in all subsequent versions of libfixbuf.
2931  */
2932 
2933 
2934 /**
2935  * Sets the internal template on a buffer to the given template ID. The internal
2936  * template describes the format of the record pointed to by the recbase
2937  * parameter to fBufAppend() (for export) and fBufNext() (for collection). The
2938  * given template ID must identify a current internal template in the buffer's
2939  * associated session.
2940  *
2941  * An internal template must be set on a buffer before calling fBufAppend() or
2942  * fBufNext().
2943  *
2944  * @param fbuf      an IPFIX message buffer
2945  * @param int_tid   template ID of the new internal template
2946  * @param err       An error description, set on failure.
2947  * @return TRUE on success, FALSE on failure.
2948  */
2949 
2950 gboolean            fBufSetInternalTemplate(
2951     fBuf_t              *fbuf,
2952     uint16_t            int_tid,
2953     GError              **err);
2954 
2955 /**
2956  * Sets the external template for export on a buffer to the given template ID.
2957  * The external template describes the record that will be written to the
2958  * IPFIX message. The buffer must be initialized for export. The given ID is
2959  * scoped to the observation domain of the associated session
2960  * (see fbSessionSetDomain()), and must identify a current external template
2961  * for the current domain in the buffer's associated session.
2962  *
2963  * An export template must be set on a buffer before calling fBufAppend().
2964  *
2965  * @param fbuf      an IPFIX message buffer
2966  * @param ext_tid   template ID of the new external template within the
2967  *                  current domain.
2968  * @param err       An error description, set on failure.
2969  * @return TRUE on success, FALSE on failure.
2970  */
2971 
2972 gboolean            fBufSetExportTemplate(
2973     fBuf_t              *fbuf,
2974     uint16_t            ext_tid,
2975     GError              **err);
2976 
2977 #if HAVE_SPREAD
2978 /**
2979  * This function checks to see if the groups you are setting on the buffer
2980  * are different than the groups previously set.  If so, it will emit the
2981  * buffer, set the first group on the session (to get templates & sequence
2982  * numbers) and THEN set the desired group(s) for export on a buffer.  This
2983  * should be called before setting external templates with
2984  * fbSessionAddTemplate() and before calling fBufAppend().  If using
2985  * fbSessionAddTemplatesMulticast(), it is not necessary to call this before
2986  * because it is called within this function.
2987  *
2988  * @param fbuf       an IPFIX message buffer
2989  * @param groups     an array of Spread Export Groups
2990  * @param num_groups number of groups from groups to be added
2991  * @param err        an error description, set on failure.
2992  */
2993 void                 fBufSetSpreadExportGroup(
2994     fBuf_t             *fbuf,
2995     char               **groups,
2996     int                num_groups,
2997     GError             **err);
2998 #endif  /* HAVE_SPREAD */
2999 
3000 /**
3001  * Sets the automatic (read/write) mode flag on a buffer.
3002  *
3003  * In automatic write mode, a call to fBufAppend(), fbSessionAddTemplate(), or
3004  * fbSessionExportTemplates() that overruns the available space in the buffer
3005  * will cause a call to fBufEmit() to emit the message in the buffer to the
3006  * exporter before starting a new message.
3007  *
3008  * In automatic read mode, a call to fBufNext() that overruns the buffer will
3009  * cause a call to fBufNextMessage() to read another message from the
3010  * collector before attempting to read a record.
3011  *
3012  * In manual mode, the end of message on any buffer read/write call results in
3013  * the call returning an error with a GError code of FB_ERROR_EOM.
3014  *
3015  * Buffers are created in automatic mode by default.
3016  *
3017  * @param fbuf      an IPFIX message buffer
3018  * @param automatic TRUE for this buffer to be automatic, FALSE for manual.
3019  */
3020 
3021 void                fBufSetAutomaticMode(
3022     fBuf_t              *fbuf,
3023     gboolean            automatic);
3024 
3025 /**
3026  * Enables automatic insertion of RFC 5610 elements on a buffer.
3027  *
3028  * In automatic insertion mode, information element type records that are
3029  * collected by the buffer create an information element (@ref
3030  * fbInfoElement_t) if the record's privateEnterpriseNumber is non-zero.  That
3031  * element is inserted into the information model (@ref fbInfoModel_t) that is
3032  * set on the fbuf's session.  This allows an application to retrieve
3033  * information about a non-standard information elements.  This function
3034  * should be called after the fbuf is created.  This function creates the
3035  * internal template for the Info Element Type Record (@ref
3036  * fbInfoElementOptRec_t) and adds it to the fbuf's session.
3037  *
3038  * For export of RFC 5610 elements, use fbSessionSetMetadataExportElements().
3039  *
3040  * @param fbuf        an IPFIX message buffer
3041  * @param err         Gerror pointer
3042  * @return            TRUE on success, FALSE if the internal template could
3043  *                    not be created
3044  */
3045 gboolean         fBufSetAutomaticInsert(
3046     fBuf_t             *fbuf,
3047     GError             **err);
3048 
3049 
3050 /**
3051  * Retrieves the session associated with a buffer.
3052  *
3053  * @param fbuf      an IPFIX message buffer
3054  * @return the associated session
3055  */
3056 
3057 fbSession_t         *fBufGetSession(
3058     fBuf_t              *fbuf);
3059 
3060 /**
3061  * Frees a buffer. Also frees any associated session, exporter, or collector,
3062  * closing exporting process or collecting process endpoint connections
3063  * and removing collecting process endpoints from any listeners, as necessary.
3064  *
3065  * @param fbuf      an IPFIX message buffer
3066  */
3067 
3068 void                fBufFree(
3069     fBuf_t              *fbuf);
3070 
3071 /**
3072  * Allocates a new buffer for export. Associates the buffer with a given
3073  * session and exporting process endpoint; these become owned by the buffer.
3074  * Session and exporter are freed by fBufFree().  Must never be freed by user
3075  *
3076  * @param session   a session initialized with appropriate
3077  *                  internal and external templates
3078  * @param exporter  an exporting process endpoint
3079  * @return a new IPFIX message buffer, owning the session and exporter,
3080  *         for export use via fBufAppend() and fBufEmit().
3081  */
3082 
3083 fBuf_t              *fBufAllocForExport(
3084     fbSession_t         *session,
3085     fbExporter_t        *exporter);
3086 
3087 /**
3088  * Retrieves the exporting process endpoint associated with a buffer.
3089  * The buffer must have been allocated with fBufAllocForExport();
3090  * otherwise, returns NULL.
3091  *
3092  * @param fbuf      an IPFIX message buffer
3093  * @return the associated exporting process endpoint
3094  */
3095 
3096 fbExporter_t        *fBufGetExporter(
3097     fBuf_t              *fbuf);
3098 
3099 /**
3100  * Associates an exporting process endpoint with a buffer.
3101  * The exporter will be used to write IPFIX messgaes to a transport.
3102  * The exporter becomes owned by the buffer; any previous exporter
3103  * associated with the buffer is closed if necessary and freed.
3104  *
3105  * @param fbuf      an IPFIX message buffer
3106  * @param exporter  an exporting process endpoint
3107  */
3108 
3109 void                fBufSetExporter(
3110     fBuf_t              *fbuf,
3111     fbExporter_t        *exporter);
3112 
3113 
3114 /**
3115  * Retrieves the length of the buffer that is remaining after
3116  * processing.  An IPFIX collector that is not using fixbuf to
3117  * handle connections would use this function upon receiving an
3118  * FB_ERROR_BUFSZ error to determine how many bytes are left in the
3119  * buffer (set by fBufSetBuffer()) that are not processed.
3120  *
3121  * @param fbuf an IPFIX message buffer
3122  * @return length of buffer not read
3123  *
3124  */
3125 size_t fBufRemaining(
3126     fBuf_t      *fbuf);
3127 
3128 
3129 /**
3130  * Sets a buffer on an fBuf for collection.  This can be used
3131  * by applications that want to handle their own connections, file reading,
3132  * etc.  This call should be made after the call to read and before
3133  * calling fBufNext.  fBufNext() will return FB_ERROR_BUFSZ when there is not
3134  * enough buffer space to read a full IPFIX message.
3135  *
3136  * @param fbuf an IPFIX message buffer
3137  * @param buf the data buffer to use for processing IPFIX
3138  * @param buflen the length of IPFIX data in buf
3139  * @see @ref noconnect Connection-less collector
3140  */
3141 void fBufSetBuffer(
3142     fBuf_t         *fbuf,
3143     uint8_t        *buf,
3144     size_t          buflen);
3145 
3146 
3147 /**
3148  * Appends a record to a buffer. Uses the present internal template set via
3149  * fBufSetInternalTemplate() to describe the record of size recsize located
3150  * in memory at recbase.  Uses the present export template set via
3151  * fBufSetExportTemplate() to describe the record structure to be written to
3152  * the buffer. Information Elements present in the external template that are
3153  * not present in the internal template are transcoded into the message as
3154  * zeroes. If the buffer is in automatic mode, may cause a message to be
3155  * emitted via fBufEmit() if there is insufficient space in the buffer for
3156  * the record.
3157  *
3158  * If the internal template contains any variable length Information Elements,
3159  * those must be represented in the record by @ref fbVarfield_t structures.
3160  *
3161  * @param fbuf      an IPFIX message buffer
3162  * @param recbase   pointer to internal record
3163  * @param recsize   size of internal record in bytes
3164  * @param err       an error description, set on failure.
3165  *                  Must not be NULL, as it is used internally in
3166  *                  automatic mode to detect message restart.
3167  * @return TRUE on success, FALSE on failure.
3168  */
3169 
3170 gboolean            fBufAppend(
3171     fBuf_t              *fbuf,
3172     uint8_t             *recbase,
3173     size_t              recsize,
3174     GError              **err);
3175 
3176 /**
3177  * Emits the message currently in a buffer using the associated exporting
3178  * process endpoint.
3179  *
3180  * @param fbuf      an IPFIX message buffer
3181  * @param err       an error description, set on failure.
3182  * @return TRUE on success, FALSE on failure.
3183  */
3184 
3185 gboolean            fBufEmit(
3186     fBuf_t              *fbuf,
3187     GError              **err);
3188 
3189 /**
3190  * Sets the export time on the message currently in a buffer. This will be used
3191  * as the export time of the message created by the first call to fBufAppend()
3192  * after the current message, if any, is emitted. Use 0 for the export time
3193  * to cause the export time to be taken from the system clock at message
3194  * creation time.
3195  *
3196  * @param fbuf      an IPFIX message buffer
3197  * @param extime    the export time in epoch seconds.
3198  */
3199 
3200 void                fBufSetExportTime(
3201     fBuf_t              *fbuf,
3202     uint32_t            extime);
3203 
3204 /**
3205  * Allocates a new buffer for collection. Associates the buffer with a given
3206  * session and collecting process endpoint; these become owned by the buffer
3207  * and must not be freed by the user.  The session and collector are freed by
3208  * fBufFree().
3209  *
3210  * When using libfixbuf to process a buffer of IPFIX data (see
3211  * fBufSetBuffer()), invoke this function with a NULL collector.
3212  *
3213  * @param session   a session initialized with appropriate
3214  *                  internal templates
3215  * @param collector  an collecting process endpoint
3216  * @return a new IPFIX message buffer, owning the session and collector,
3217  *         for collection use via fBufNext() and fBufNextMessage().
3218  */
3219 
3220 fBuf_t              *fBufAllocForCollection(
3221     fbSession_t         *session,
3222     fbCollector_t       *collector);
3223 
3224 /**
3225  * Retrieves the collecting process endpoint associated with a buffer.
3226  * The buffer must have been allocated with fBufAllocForCollection();
3227  * otherwise, returns NULL.
3228  *
3229  * @param fbuf      an IPFIX message buffer
3230  * @return the associated collecting process endpoint
3231  */
3232 
3233 fbCollector_t       *fBufGetCollector(
3234     fBuf_t              *fbuf);
3235 
3236 /**
3237  * Associates an collecting process endpoint with a buffer.
3238  * The collector will be used to read IPFIX messgaes from a transport.
3239  * The collector becomes owned by the buffer; any previous collector
3240  * associated with the buffer is closed if necessary and freed.
3241  *
3242  * @param fbuf      an IPFIX message buffer
3243  * @param collector  an collecting process endpoint
3244  */
3245 
3246 void                fBufSetCollector(
3247     fBuf_t              *fbuf,
3248     fbCollector_t       *collector);
3249 
3250 /**
3251  * Retrieves a record from a buffer. Uses the external template taken from
3252  * the message to read the next record available from a data set in the message.
3253  * Copies the record to a buffer at recbase, with a maximum record size
3254  * pointed to by recsize, described by the present internal template set via
3255  * fBufSetInternalTemplate(). Reads and processes any templates and options
3256  * templates between the last record read (or beginning of message) and the
3257  * next data record. Information Elements present in the internal template
3258  * that are not present in the external template are transcoded into the
3259  * record at recbase as zeroes. If the buffer is in automatic mode, may cause
3260  * a message to be read via fBufNextMessage() if there are no more records
3261  * available in the message buffer.
3262  *
3263  * If the internal template contains any variable length Information Elements,
3264  * those must be represented in the record at recbase by @ref fbVarfield_t
3265  * structures.
3266  *
3267  * @param fbuf      an IPFIX message buffer
3268  * @param recbase   pointer to internal record buffer; will contain
3269  *                  record data after call.
3270  * @param recsize   On call, pointer to size of internal record buffer
3271  *                  in bytes. Contains number of bytes actually transcoded
3272  *                  at end of call.
3273  * @param err       an error description, set on failure.
3274  *                  Must not be NULL, as it is used internally in
3275  *                  automatic mode to detect message restart.
3276  * @return TRUE on success, FALSE on failure.
3277  */
3278 
3279 gboolean            fBufNext(
3280     fBuf_t              *fbuf,
3281     uint8_t             *recbase,
3282     size_t              *recsize,
3283     GError              **err);
3284 
3285 /**
3286  * Reads a new message into a buffer using the associated collecting
3287  * process endpoint. Called by fBufNext() on end of message in automatic
3288  * mode; should be called after an FB_ERROR_EOM return from fBufNext() in
3289  * manual mode, or to skip the current message and go on to the next
3290  * in the stream.
3291  *
3292  * @param fbuf      an IPFIX message buffer
3293  * @param err       an error description, set on failure.
3294  * @return TRUE on success, FALSE on failure.
3295  */
3296 
3297 gboolean            fBufNextMessage(
3298     fBuf_t              *fbuf,
3299     GError              **err);
3300 
3301 /**
3302  * Retrieves the export time on the message currently in a buffer.
3303  *
3304  * @param fbuf      an IPFIX message buffer
3305  * @return the export time in epoch seconds.
3306  */
3307 
3308 uint32_t            fBufGetExportTime(
3309     fBuf_t              *fbuf);
3310 
3311 /**
3312  * Retrieves the external template used to read the last record from the buffer.
3313  * If no record has been read, returns NULL. Stores the external template ID
3314  * within the current domain in ext_tid, if not NULL.
3315  *
3316  * This routine is not particularly useful to applications, as it would be
3317  * called after the record described by the external template had been
3318  * transcoded, and as such could not be used to select an
3319  * appropriate internal template for a given external template. However,
3320  * it is used by fBufNextCollectionTemplate(), and may be useful in certain
3321  * contexts, so is made public.
3322  *
3323  * Usually, you'll want to use fBufNextCollectionTemplate() instead.
3324  *
3325  * @param fbuf      an IPFIX message buffer
3326  * @param ext_tid   pointer to external template ID storage, or NULL.
3327  * @return the external template describing the last record read.
3328  */
3329 
3330 fbTemplate_t    *fBufGetCollectionTemplate(
3331     fBuf_t          *fbuf,
3332     uint16_t        *ext_tid);
3333 
3334 /**
3335  * Retrieves the external template that will be used to read the next record
3336  * from the buffer. If no next record is available, returns NULL. Stores the
3337  * external template ID within the current domain in ext_tid, if not NULL.
3338  * Reads and processes any templates and options
3339  * templates between the last record read (or beginning of message) and the
3340  * next data record. If the buffer is in automatic mode, may cause
3341  * a message to be read via fBufNextMessage() if there are no more records
3342  * available in the message buffer.
3343  *
3344  * @param fbuf      an IPFIX message buffer
3345  * @param ext_tid   pointer to external template ID storage, or NULL.
3346  * @param err       an error description, set on failure.
3347  *                  Must not be NULL, as it is used internally in
3348  *                  automatic mode to detect message restart.
3349  * @return the external template describing the last record read.
3350  */
3351 
3352 fbTemplate_t    *fBufNextCollectionTemplate(
3353     fBuf_t          *fbuf,
3354     uint16_t        *ext_tid,
3355     GError          **err);
3356 
3357 /**
3358  * Allocates a new information model. The information model contains all the
3359  * default information elements in the [IANA-managed][] number space, and may
3360  * be extended via fbInfoModelAddElement(), fbInfoModelAddElementArray(),
3361  * fbInfoModelReadXMLFile(), and fbInfoModelReadXMLData().
3362  *
3363  * An Information Model is required to create Templates and Sessions. Each
3364  * application should have only one Information Model.
3365  *
3366  * @return a new Information Model
3367  *
3368  * [IANA-managed]: https://www.iana.org/assignments/ipfix/ipfix.xhtml
3369  */
3370 
3371 fbInfoModel_t       *fbInfoModelAlloc(
3372     void);
3373 
3374 /**
3375  * Frees an information model. Must not be called until all sessions and
3376  * templates depending on the information model have also been freed; i.e.,
3377  * at application cleanup time.
3378  *
3379  * @param model     An information model
3380  */
3381 
3382 void                fbInfoModelFree(
3383     fbInfoModel_t       *model);
3384 
3385 /**
3386  * Adds a single information element to an information
3387  * model. The information element is assumed to be in "canonical" form; that
3388  * is, its ref.name field should contain the information element name. The
3389  * information element and its name are copied into the model; the caller may
3390  * free or reuse its storage after this call.
3391  *
3392  * See fbInfoModelAddElementArray() for a more convenient method of statically
3393  * adding information elements to information models.
3394  *
3395  * @param model     An information model
3396  * @param ie        Pointer to an information element to copy into the model
3397  */
3398 
3399 void                fbInfoModelAddElement(
3400     fbInfoModel_t       *model,
3401     fbInfoElement_t     *ie);
3402 
3403 /**
3404  * Adds multiple information elements in an array to an information
3405  * model. The information elements are assumed to be in "canonical" form; that
3406  * is, their ref.name fields should contain the information element name. Each
3407  * information element and its name are copied into the model; the caller may
3408  * free or reuse its storage after this call.
3409  *
3410  * The ie parameter points to the first information element in an array,
3411  * usually statically initialized with an array of @ref FB_IE_INIT_FULL macros
3412  * followed by an @ref FB_IE_NULL macro.
3413  *
3414  * @param model     An information model
3415  * @param ie        Pointer to an IE array to copy into the model
3416  *
3417  * @see fbInfoModelReadXMLFile() and fbInfoModelReadXMLData() for
3418  * alternate ways to add information elements to information models.
3419  */
3420 
3421 void                fbInfoModelAddElementArray(
3422     fbInfoModel_t       *model,
3423     fbInfoElement_t     *ie);
3424 
3425 /**
3426  * Adds information specified in the given XML file to the information
3427  * model. The XML file is expected to be in the format used by the
3428  * [IANA IPFIX Entities registry][IPFIX XML], with the following two
3429  * additions:
3430  *
3431  * - A `<cert:enterpriseId>` field may be used to mark the enterprise ID for
3432  *   an element.
3433  *
3434  * - A `<cert:reversible>` field may be used to mark an element as
3435  *   reversible (as per [RFC 5103][]).  Valid values for this field are
3436  *   true, false, yes, no, 1, and 0.
3437  *
3438  * If the XML being parsed contains registries for the element data
3439  * types, semantics, or units, those will be parsed and used to
3440  * interpret the corresponding fields in the element records.  (These
3441  * registries exist in IANA's registry.)
3442  *
3443  * A parsed element that already exists in the given InfoModel will be
3444  * replace the existing element.
3445  * @param model     An information model
3446  * @param filename  The file containing the XML description
3447  * @param err       Return location for a GError
3448  * @return `FALSE` if an error occurred, TRUE on success
3449  * @since libfixbuf 2.1.0
3450  * @see fbInfoModelReadXMLData()
3451  *
3452  * [IPFIX XML]: https://www.iana.org/assignments/ipfix/ipfix.xml
3453  * [RFC 5103]: https://tools.ietf.org/html/rfc5103
3454  */
3455 
3456 gboolean fbInfoModelReadXMLFile(
3457     fbInfoModel_t       *model,
3458     const gchar         *filename,
3459     GError             **err);
3460 
3461 /**
3462  * Adds information specified in the given XML data to the information
3463  * model. The XML data is expected to be in the format used by the
3464  * [IANA IPFIX Entities registry][IPFIX XML], with the following two
3465  * additions:
3466  *
3467  * - A `<cert:enterpriseId>` field may be used to mark the enterprise ID for
3468  *   an element.
3469  *
3470  * - A `<cert:reversible>` field may be used to mark an element as
3471  *   reversible (as per [RFC 5103][]).  Valid values for this field are
3472  *   true, false, yes, no, 1, and 0.
3473  *
3474  * If the XML being parsed contains registries for the element data
3475  * types, semantics, or units, those will be parsed and used to
3476  * interpret the corresponding fields in the element records.  (These
3477  * registries exist in IANA's registry.)
3478  *
3479  * A parsed element that already exists in the given InfoModel will be
3480  * replace the existing element.
3481  * @param model         An information model
3482  * @param xml_data      A pointer to the XML data
3483  * @param xml_data_len  The length of `xml_data` in bytes
3484  * @param err           Return location for a GError
3485  * @return `FALSE` if an error occurred, TRUE on success
3486  * @since libfixbuf 2.1.0
3487  * @see fbInfoModelReadXMLFile()
3488  *
3489  * [IPFIX XML]: https://www.iana.org/assignments/ipfix/ipfix.xml
3490  * [RFC 5103]: https://tools.ietf.org/html/rfc5103
3491  */
3492 
3493 gboolean fbInfoModelReadXMLData(
3494     fbInfoModel_t       *model,
3495     const gchar         *xml_data,
3496     gssize               xml_data_len,
3497     GError             **err);
3498 
3499 /**
3500  * Returns a pointer to the canonical information element within an information
3501  * model given the information element name. The returned information element
3502  * is owned by the information model and must not be modified.
3503  *
3504  * @param model     An information model
3505  * @param name      The name of the information element to look up
3506  * @return          The named information element within the model,
3507  *                  or NULL if no such element exists.
3508  */
3509 
3510 const fbInfoElement_t     *fbInfoModelGetElementByName(
3511     fbInfoModel_t       *model,
3512     const char          *name);
3513 
3514 /**
3515  * Returns a pointer to the canonical information element within an
3516  * information model given the information element ID and enterprise ID.  The
3517  * returned information element is owned by the information model and must not
3518  * be modified.
3519  *
3520  * @param model     An information model
3521  * @param id        An information element id
3522  * @param ent       An enterprise id
3523  * @return          The named information element within the model, or NULL
3524  *                  if no such element exists.
3525  */
3526 
3527 const fbInfoElement_t    *fbInfoModelGetElementByID(
3528     fbInfoModel_t       *model,
3529     uint16_t            id,
3530     uint32_t            ent);
3531 
3532 /**
3533  * Returns the number of information elements in the information model.
3534  *
3535  * @param model     An information model
3536  * @return          The number of information elements in the
3537  *                  information model
3538  */
3539 guint fbInfoModelCountElements(
3540     const fbInfoModel_t *model);
3541 
3542 /**
3543  * Initializes an information model iterator for iteration over the
3544  * information elements (@ref fbInfoElement_t) in the model.  The caller uses
3545  * fbInfoModelIterNext() to visit the elements.
3546  *
3547  * @param iter      A pointer to the iterator to initialize
3548  * @param model     An information model
3549  */
3550 
3551 void fbInfoModelIterInit(
3552     fbInfoModelIter_t   *iter,
3553     const fbInfoModel_t *model);
3554 
3555 /**
3556  * Returns a pointer to the next information element in the information
3557  * model.  Returns NULL once all information elements have been
3558  * returned.
3559  *
3560  * @param iter      An information model iterator
3561  * @return          The next information element within the model, or NULL
3562  *                  if there are no more elements.
3563  */
3564 
3565 const fbInfoElement_t *fbInfoModelIterNext(
3566     fbInfoModelIter_t *iter);
3567 
3568 /**
3569  * Allocates and returns the Options Template that will be used to define
3570  * Information Element Type Records.  This function does not add the template
3571  * to the session or fbuf.  This function allocates the template, appends the
3572  * appropriate elements to the template, and sets the scope on the template.
3573  * See RFC 5610 for more info.
3574  *
3575  * @param model       A pointer to an existing info model
3576  * @param err         GError
3577  * @return            The pointer to the newly allocated template.
3578  *
3579  */
3580 
3581 fbTemplate_t *fbInfoElementAllocTypeTemplate(
3582     fbInfoModel_t          *model,
3583     GError                 **err);
3584 
3585 /**
3586  * Exports an options record to the given fbuf with information element type
3587  * information about the given information element.  See RFC 5610 for details.
3588  * Use fbInfoElementAllocTypeTemplate() and add the returned template
3589  * to the session,  before calling this function.
3590  *
3591  * @param fbuf       An existing fbuf
3592  * @param model_ie   A pointer to the information element to export type info.
3593  * @param itid       The internal template id of the Options Template.
3594  * @param etid       The external template id of the Options Template.
3595  * @param err        GError
3596  * @return           TRUE if successful, FALSE if an error occurred.
3597  */
3598 
3599 gboolean fbInfoElementWriteOptionsRecord(
3600     fBuf_t                  *fbuf,
3601     const fbInfoElement_t   *model_ie,
3602     uint16_t                itid,
3603     uint16_t                etid,
3604     GError                  **err);
3605 
3606 /**
3607  * Adds an element that we received via an RFC 5610 Options Record to the
3608  * given info model.  Returns True if the element was successfully added.
3609  * False, if it couldn't be added.  This function does not add elements that
3610  * have a private enterprise number of 0, for security reasons.
3611  *
3612  * @param model        An information model
3613  * @param rec          A pointer to the received fbInfoElementOptRec.
3614  * @return             TRUE if item was successfully added to info model.
3615  *
3616  */
3617 gboolean fbInfoElementAddOptRecElement(
3618     fbInfoModel_t           *model,
3619     fbInfoElementOptRec_t   *rec);
3620 
3621 /**
3622  * Checks to see if a template contains all of the elements required
3623  * by RFC 5610 for describing an information element type (type metadata).
3624  *
3625  * @param tmpl         A pointer to the template
3626  * @return             TRUE if template contains all the info elements
3627  * @see fbInfoElementAddOptRecElement()
3628  */
3629 gboolean fbInfoModelTypeInfoRecord(
3630     fbTemplate_t            *tmpl);
3631 
3632 /**
3633  * Allocates a new empty template. The template will be associated with the
3634  * given Information Model, and only able to use Information Elements defined
3635  * within that Information Model. Templates may be associated with multiple
3636  * sessions, with different template IDs each time, and as such are
3637  * reference counted and owned by sessions. A template must be associated
3638  * with at least one session or it will be leaked; each template is freed
3639  * after its last associated session is freed.
3640  *
3641  * Use fbTemplateAppend(), fbTemplateAppendSpec(), and
3642  * fbTemplateAppendSpecArray() to "fill in" a template after creating it,
3643  * and before associating it with any session.
3644  *
3645  * @param model     An information model
3646  * @return a new, empty Template.
3647  */
3648 
3649 fbTemplate_t        *fbTemplateAlloc(
3650     fbInfoModel_t       *model);
3651 
3652 /**
3653  * Appends an information element to a template. The information element is
3654  * taken to be an example; the canonical element from the template's
3655  * associated model is looked up by enterprise and element number and
3656  * copied. If no information element exists in the model with the given
3657  * enterprise and element number, it is copied to the model with the name
3658  * "_alienInformationElement".
3659  *
3660  * This call is intended primarily for use by @ref fBuf_t's template reader,
3661  * but can also be useful to simulate receipt of templates over the wire.
3662  *
3663  * @param tmpl      Template to append information element to
3664  * @param ex_ie     Example IE to add to the template
3665  * @param err       an error description, set on failure.
3666  * @return TRUE on success, FALSE on failure.
3667  */
3668 
3669 gboolean            fbTemplateAppend(
3670     fbTemplate_t        *tmpl,
3671     fbInfoElement_t     *ex_ie,
3672     GError              **err);
3673 
3674 /**
3675  * Appends an information element described by specifier to a template.
3676  * The @ref fbInfoElement_t named by the specifier is copied from the
3677  * template's associated @ref fbInfoModel_t, and the length and flags are
3678  * overriden from the specifier.
3679  *
3680  * @param tmpl      Template to append information element to.
3681  * @param spec      Specifier describing information element to append.
3682  * @param flags     Application flags. Must contain all bits of spec flags word
3683  *                  or the append will be silently skipped. Used for
3684  *                  building multiple templates with different information
3685  *                  element features from a single specifier.
3686  * @param err       an error description, set on failure.
3687  * @return TRUE on success, FALSE on failure.
3688  * @see fbTemplateAppendSpecArray()
3689  */
3690 
3691 gboolean            fbTemplateAppendSpec(
3692     fbTemplate_t        *tmpl,
3693     fbInfoElementSpec_t *spec,
3694     uint32_t            flags,
3695     GError              **err);
3696 
3697 /**
3698  * Appends information elements described by a specifier array to a template.
3699  * Calls fbTemplateAppendSpec() for each member of the array until the
3700  * @ref FB_IESPEC_NULL convenience macro is encountered.
3701  *
3702  * @param tmpl      Template to append information element to.
3703  * @param spec      Pointer to first specifier in specifier array to append.
3704  * @param flags     Application flags. Must contain all bits of spec flags word
3705  *                  or the append will be silently skipped. Used for
3706  *                  building multiple templates with different information
3707  *                  element features from a single specifier.
3708  * @param err       an error description, set on failure.
3709  * @return TRUE on success, FALSE on failure.
3710  */
3711 
3712 gboolean            fbTemplateAppendSpecArray(
3713     fbTemplate_t        *tmpl,
3714     fbInfoElementSpec_t *spec,
3715     uint32_t            flags,
3716     GError              **err);
3717 
3718 /**
3719  * Determines number of information elements in a template.
3720  *
3721  * @param tmpl      A template
3722  * @return information element count
3723  */
3724 
3725 uint32_t            fbTemplateCountElements(
3726     fbTemplate_t        *tmpl);
3727 
3728 /**
3729  * Sets the number of information elements in a template that are scope. This
3730  * causes the template to become an options template, and must be called after
3731  * all the scope information elements have been appended to the template.
3732  *
3733  * The scope count may not be greater than the number of IEs in the template.
3734  * A scope_count argument of zero sets the scope count to the number of IEs.
3735  *
3736  * It is expected that this function is only called once per template.
3737  *
3738  * @param tmpl          Template to set scope on
3739  * @param scope_count   Number of scope information elements
3740  */
3741 
3742 void                fbTemplateSetOptionsScope(
3743     fbTemplate_t        *tmpl,
3744     uint16_t            scope_count);
3745 
3746 /**
3747  * Determines number of scope information elements in a template. The template
3748  * is an options template if nonzero.
3749  *
3750  * @param tmpl      A template
3751  * @return scope information element count
3752  */
3753 uint32_t            fbTemplateGetOptionsScope(
3754     fbTemplate_t        *tmpl);
3755 
3756 /**
3757  * Determines if a template contains a given information element. Matches
3758  * against information element private enterprise number, number, and
3759  * multiple-IE index (i.e., to determine if a given template contains six
3760  * instances of a given information element, set ex_ie->midx = 5 before this
3761  * call).
3762  *
3763  * @param tmpl      Template to search
3764  * @param ex_ie     Pointer to an information element to search for
3765  * @return          TRUE if the template contains the given IE
3766  * @see fbTemplateContainsElementByName()
3767  */
3768 
3769 gboolean           fbTemplateContainsElement(
3770     fbTemplate_t            *tmpl,
3771     const fbInfoElement_t   *ex_ie);
3772 
3773 /**
3774  * Determines if a template contains at least one instance of a given
3775  * information element, specified by name in the template's information model.
3776  *
3777  * @param tmpl      Template to search
3778  * @param spec      Specifier of information element to search for
3779  * @return          TRUE if the template contains the given IE
3780  * @see fbTemplateContainsElement(), fbTemplateContainsAllElementsByName(),
3781  * fbTemplateContainsAllFlaggedElementsByName()
3782  */
3783 
3784 gboolean           fbTemplateContainsElementByName(
3785     fbTemplate_t        *tmpl,
3786     fbInfoElementSpec_t *spec);
3787 
3788 /**
3789  * Determines if a template contains at least one instance of each
3790  * @ref fbInfoElement_t in a given information element specifier array.
3791  *
3792  * @param tmpl      Template to search
3793  * @param spec      Pointer to specifier array to search for
3794  * @return          TRUE if the template contains all the given IEs
3795  * @see fbTemplateContainsElementsByName(),
3796  * fbTemplateContainsAllFlaggedElementsByName()
3797  */
3798 
3799 gboolean           fbTemplateContainsAllElementsByName(
3800     fbTemplate_t        *tmpl,
3801     fbInfoElementSpec_t *spec);
3802 
3803 /**
3804  * Determines if a template contains at least one instance of each
3805  * information element in a given information element specifier array that
3806  * match the given flags argument.
3807  *
3808  * @param tmpl      Template to search
3809  * @param spec      Pointer to specifier array to search for
3810  * @param flags     Flags to match info elements. Specifier elements whose
3811  *                  flags member is non-zero and do not match all the bits of
3812  *                  the flags parameter are not checked.
3813  * @return          TRUE if the template contains all the given IEs
3814  * @see fbTemplateContainsElementByName(),
3815  * fbTemplateContainsAllElementsByName()
3816  */
3817 gboolean            fbTemplateContainsAllFlaggedElementsByName(
3818     fbTemplate_t        *tmpl,
3819     fbInfoElementSpec_t *spec,
3820     uint32_t             flags);
3821 
3822 /**
3823  * Returns the information element in the template referenced by the index
3824  *
3825  * @param tmpl      Pointer to the template
3826  * @param IEindex   index of the information element to return
3827  * @return          A pointer to the information element at index IEindex,
3828  *                  NULL if IEindex is greater than number of elements
3829  */
3830 fbInfoElement_t*    fbTemplateGetIndexedIE(
3831     fbTemplate_t       *tmpl,
3832     uint32_t            IEindex);
3833 
3834 
3835 /**
3836  * Returns the information model, as understood by the template.
3837  * @param tmpl Template Pointer
3838  * @return The information model
3839  * @since libfixbuf 2.1.0
3840  */
3841 
3842 fbInfoModel_t *     fbTemplateGetInfoModel(
3843     fbTemplate_t        *tmpl);
3844 
3845 /**
3846  * Frees a template if it is not currently in use by any Session. Use this
3847  * to clean up while creating templates in case of error.
3848  *
3849  * @param tmpl template to free
3850  */
3851 
3852 void                fbTemplateFreeUnused(
3853     fbTemplate_t        *tmpl);
3854 
3855 /**
3856  * Gets the ctx pointer associated with a Template.  The ctx pointer
3857  * is set during the @ref fbNewTemplateCallback_fn when the new template
3858  * is received.
3859  * @param tmpl Template Pointer
3860  * @return ctx The application Context Pointer
3861  */
3862 void               *fbTemplateGetContext(
3863     fbTemplate_t         *tmpl);
3864 
3865 /**
3866  * Gets the length required for a buffer to store a data record
3867  * described by this template. Another way to think about it is this is the
3868  * length of the record when this template is used as an internal template
3869  * @since libfixbuf 2.2.0
3870  */
3871 uint16_t            fbTemplateGetIELenOfMemBuffer(
3872     fbTemplate_t         *tmpl);
3873 
3874 /**
3875  * Allocates a transport session state container. The new session is associated
3876  * with the given information model, contains no templates, and is usable
3877  * either for collection or export.
3878  *
3879  * Each @ref fbExporter_t, @ref fbListener_t, and @ref fbCollector_t must have
3880  * its own session; session state cannot be shared.
3881  *
3882  * The fbSession_t returned by this function is not freed by calling
3883  * fBufFree() or fbListenerFree().  It should be freed by the application
3884  * by calling fbSessionFree().
3885  *
3886  * @param model     An information model.  Not freed by sessionFree.  Must
3887                     be freed by user after calling SessionFree
3888  * @return a new, empty session state container.
3889  */
3890 
3891 fbSession_t         *fbSessionAlloc(
3892     fbInfoModel_t       *model);
3893 
3894 /**
3895  * Configures a session to export type information for enterprise-specific
3896  * information elements as options records according to RFC 5610.  This
3897  * function is a wrapper over fbSessionSetMetadataExportElements() with `tid`
3898  * set to FB_TID_AUTO.
3899  *
3900  * @param session pointer
3901  * @param enabled TRUE to enable type metadata export, FALSE to disable
3902  * @param err error mesasge
3903  * @return TRUE on success, FALSE on failure
3904  * @deprecated Use fbSessionSetMetadataExportElements() instead.
3905  */
3906 
3907 gboolean fbSessionEnableTypeMetadata(
3908     fbSession_t                *session,
3909     gboolean                    enabled,
3910     GError                    **err);
3911 
3912 /**
3913  * Configures a session to export type information for enterprise-specific
3914  * information elements as options records according to RFC 5610.
3915  *
3916  * Regardless of the `enabled` value, this function creates the type
3917  * information template and adds it to the session with the template ID `tid`
3918  * or an arbitrary ID when `tid` is @ref FB_TID_AUTO.
3919  *
3920  * If `enabled` is TRUE, the information metadata is exported each time
3921  * fbSessionExportTemplates() is called.
3922  *
3923  * When collecting, use fBufSetAutomaticInsert() to automatically update the
3924  * information model with these RFC 5610 elements.
3925  *
3926  * @param session pointer
3927  * @param enabled TRUE to enable type metadata export, FALSE to disable
3928  * @param tid the template id to use for type-information records
3929  * @param err error mesasge
3930  * @return the template id for type-information records or 0 if the template
3931  * could not be added to the session.
3932  * @since libfixbuf 2.3.0
3933  */
3934 
3935 uint16_t fbSessionSetMetadataExportElements(
3936     fbSession_t                *session,
3937     gboolean                    enabled,
3938     uint16_t                    tid,
3939     GError                    **err);
3940 
3941 /**
3942  * Configures a session to export template metadata as options records.  This
3943  * function is a wrapper over fbSessionSetMetadataExportTemplates() with
3944  * `tid` set to FB_TID_AUTO.
3945  *
3946  * @param session pointer
3947  * @param enabled TRUE to enable template metadata export, FALSE to disable
3948  * @param err error mesasge
3949  * @return TRUE on success, FALSE on failure
3950  * @see fbSessionSetMetadataExportTemplates(),
3951  * fbSessionAddTemplateWithMetadata()
3952  * @deprecated Use fbSessionSetMetadataExportTemplates() instead.
3953  */
3954 
3955 gboolean fbSessionEnableTemplateMetadata(
3956     fbSession_t                *session,
3957     gboolean                    enabled,
3958     GError                    **err);
3959 
3960 /**
3961  * Configures a session to export template metadata as options records.
3962  * Template metadata is the name and description specified by
3963  * fbSessionAddTemplateWithMetadata().
3964  *
3965  * If enabled, the metadata is exported each time fbSessionExportTemplates()
3966  * or fbSessionExportTemplate() is called.  In addition, the metadata is
3967  * exported when fbSessionAddTemplateWithMetadata() is called if the session
3968  * is associated with an @ref fbExporter_t.
3969  *
3970  * Regardless of the `enabled` value, this function creates the
3971  * template-metadata template and adds it to the session with the template ID
3972  * `tid` or an arbitrary ID when `tid` is @ref FB_TID_AUTO.
3973  *
3974  * @param session pointer
3975  * @param enabled TRUE to enable template metadata export, FALSE to disable
3976  * @param tid the template id to use for template metadata records
3977  * @param err error mesasge
3978  * @return the template id for template-metadata records or 0 if the template
3979  * could not be added to the session.
3980  * @since libfixbuf 2.3.0
3981  */
3982 
3983 uint16_t fbSessionSetMetadataExportTemplates(
3984     fbSession_t                *session,
3985     gboolean                    enabled,
3986     uint16_t                    tid,
3987     GError                    **err);
3988 
3989 /**
3990  * Adds a template to the session, as fbSessionAddTemplate(), with the
3991  * provided metadata.  This function appends the template's metadata to the
3992  * buffer (if currently enabled; c.f. fbSessionSetMetadataExportTemplates())
3993  * as well as the template.
3994  *
3995  * @param session   A session state container
3996  * @param internal  TRUE if the template is internal, FALSE if external.
3997  * @param tid       Template ID to assign, replacing any current template
3998  *                  in case of collision; or FB_TID_AUTO to assign a new tId.
3999  * @param tmpl      Template to add
4000  * @param name      Template name, may not be NULL
4001  * @param description Template description, may be NULL
4002  * @param err       error message
4003  * @return template id of newly added template, 0 on error
4004  * @see fbSessionAddTemplate() for additional information.
4005  */
4006 uint16_t fbSessionAddTemplateWithMetadata(
4007     fbSession_t         *session,
4008     gboolean             internal,
4009     uint16_t             tid,
4010     fbTemplate_t        *tmpl,
4011     const char          *name,
4012     const char          *description,
4013     GError              **err);
4014 
4015 /**
4016  * Gets the info model for the session.
4017  *
4018  * @param session
4019  * @return a pointer to the info model for the session
4020  */
4021 fbInfoModel_t       *fbSessionGetInfoModel(
4022     fbSession_t         *session);
4023 
4024 /**
4025  * This function sets the callback that allows the application to set its
4026  * own context variable with a new incoming template.  Assigning a callback
4027  * is not required and is only useful if the application either needs to
4028  * store some information about the template or to prevent certain nested
4029  * templates from being transcoded.  If the application's template contains
4030  * a subTemplateMultiList or subTemplateList and the callback is not used,
4031  * all incoming templates contained in these lists will be fully transcoded
4032  * and the application is responsible for freeing any nested lists contained
4033  * within those objects.
4034  *
4035  * This function should be called after fbSessionAlloc().  Fixbuf often
4036  * clones sessions upon receiving a connection.  In the TCP case, the
4037  * application has access to the session right after fbListenerWait() returns
4038  * by calling fBufGetSession().  In the UDP case, the application does
4039  * not have access to the fbSession until after a call to fBufNext() for
4040  * fBufNextCollectionTemplate() and by this time the application may have
4041  * already received some templates.  Therefore, it is important to call this
4042  * function before fBufNext().  Any callbacks added to the session will be
4043  * carried over to cloned sessions.
4044  *
4045  * @param session pointer session to assign the callback to
4046  * @param callback the function that should be called when a new template
4047  *                 is received
4048  * @param app_ctx parameter that gets passed into the callback function.
4049  *                This can be used to pass session-specific information
4050  *                state information to the callback function.
4051  * @return NONE
4052  */
4053 void fbSessionAddNewTemplateCallback(
4054     fbSession_t               *session,
4055     fbNewTemplateCallback_fn   callback,
4056     void                      *app_ctx);
4057 
4058 /**
4059  * Adds an external-internal template pair to the session.  This tells the
4060  * transcoder which internal template to use for a given external template
4061  * used in a sub template list, or a sub template multi list.
4062  *
4063  * If the value of int_tid is 0, it tells fixbuf NOT to decode any list where
4064  * the external template is ent_tid. This allows a collector to specify which
4065  * templates that are included in lists it can handle.
4066  *
4067  * If ent_tid and int_tid are set equal to each other, it tells the transcoder
4068  * to decode all of the fields from the external template, by using the
4069  * external template also as the internal template (lining up all the fields)
4070  * The exception to this is if there is an existing internal template with
4071  * the same template ID as the external template. In this case, the internal
4072  * template with the appropriate ID will be used. To avoid this potentially
4073  * unintended consequence, be careful and deliberate with template IDs.
4074  *
4075  * @param session pointer to the session to add the pair to
4076  * @param ent_tid the external template ID
4077  * @param int_tid the internal template ID used to decode the data when the
4078                   associated external template is used
4079  * @return NONE
4080  */
4081 void fbSessionAddTemplatePair(
4082     fbSession_t    *session,
4083     uint16_t        ent_tid,
4084     uint16_t        int_tid);
4085 
4086 /**
4087  * Removes a template pair from the list
4088  * this is called by fixbuf when a template is revoked from the session by
4089  * the node on the other end of the connection
4090  *
4091  * @param session pointer to the session to remove the pair from
4092  * @param ext_tid the external template ID for the pair
4093  * @return NONE
4094  */
4095 void fbSessionRemoveTemplatePair(
4096     fbSession_t    *session,
4097     uint16_t        ext_tid);
4098 
4099 /**
4100  * Function to find a pair, uniquely identified by the external ID, and return
4101  * the associated internal template ID
4102  *
4103  * @param session pointer to the session used to find the pair
4104  * @param ext_tid external template ID used to find a pair
4105  * @return the internal template ID from the pair.  0 if the pair isn't found
4106  */
4107 uint16_t    fbSessionLookupTemplatePair(
4108     fbSession_t    *session,
4109     uint16_t        ext_tid);
4110 
4111 /**
4112  * Frees a transport session state container. This is done automatically when
4113  * freeing the listener or buffer with which the session is
4114  * associated. Use this call if a session needs to be destroyed before it
4115  * is associated.
4116  *
4117  * @param session   session state container to free.
4118  */
4119 
4120 void                fbSessionFree(
4121     fbSession_t         *session);
4122 
4123 /**
4124  * Resets the external state (sequence numbers and templates) in a session
4125  * state container.
4126  *
4127  * FIXME: Verify that this call actually makes sense; either that a session
4128  * is reassociatable with a new collector, or that you need to do this when
4129  * reassociating a collector with a connection. Once this is done, rewrite
4130  * this documentation
4131  *
4132  * @param session   session state container to reset
4133  */
4134 
4135 void                fbSessionResetExternal(
4136     fbSession_t         *session);
4137 
4138 /**
4139  * Sets the current observation domain on a session. The domain
4140  * is used to scope sequence numbers and external templates. This is called
4141  * automatically during collection, but must be called to set the domain
4142  * for export before adding external templates or writing records.
4143  *
4144  * Notice that a domain change does not automatically cause any associated
4145  * export buffers to emit messages; a domain change takes effect with the
4146  * next message started. Therefore, call fBufEmit() before setting the domain
4147  * on the buffer's associated session.
4148  *
4149  * @param session   a session state container
4150  * @param domain    ID of the observation domain to set
4151  */
4152 
4153 void                fbSessionSetDomain(
4154     fbSession_t         *session,
4155     uint32_t            domain);
4156 
4157 /**
4158  * Retrieves the current domain on a session.
4159  *
4160  * @param session a session state container
4161  * @return the ID of the session's current observation domain
4162  */
4163 
4164 uint32_t            fbSessionGetDomain(
4165     fbSession_t         *session);
4166 
4167 /**
4168  * Gets the largest decoded size of an internal template in the session.
4169  * This is the number of bytes needed by store the largest record described
4170  * by an internal template in the session.
4171  * @param session a session
4172  * @return The number of bytes needed to store the largest record described
4173  *  by an internal template in the session
4174  * @since libfixbuf 2.2.0
4175  */
4176 
4177 uint16_t            fbSessionGetLargestInternalTemplateSize(
4178     fbSession_t        *session);
4179 
4180 /**
4181  * Retrieves the collector that was created with the session.
4182  *
4183  * @param session a session state container
4184  * @return fbCollector_t the collector that was created with the session
4185  *
4186  */
4187 fbCollector_t *fbSessionGetCollector(
4188     fbSession_t        *session);
4189 
4190 #if HAVE_SPREAD
4191 /**
4192  * Sets and sends templates for 1 or more groups.
4193  * This loops through the groups and adds the template to each
4194  * group's session and adds the template to the buffer.
4195  * This function is really meant for external templates, since
4196  * they are exported, although can be used for internal templates.
4197  * Since internal templates are not managed per group, they can simply
4198  * be added with fbSessionAddTemplate().
4199  * It is necessary to use this function if you plan on managing
4200  * templates per group.  Using fbSessionAddTemplate() will not allow
4201  * you to send a tmpl(s) to more than 1 group.
4202  *
4203  * @param session    a session state container
4204  * @param groups     group names
4205  * @param internal   TRUE for internal tmpl, FALSE for external
4206  * @param tid        template id, or @ref FB_TID_AUTO for an arbitrary ID
4207  * @param tmpl       pointer to template with template id tid
4208  * @param err        error mesasge
4209  * @return           template ID or 0 on failure
4210  * @see fbSessionAddTemplatesMulticastWithMetadata(), fbSessionAddTemplate()
4211  * for additional information
4212  */
4213 uint16_t        fbSessionAddTemplatesMulticast(
4214     fbSession_t      *session,
4215     char             **groups,
4216     gboolean         internal,
4217     uint16_t         tid,
4218     fbTemplate_t     *tmpl,
4219     GError           **err);
4220 
4221 /**
4222  * Sets and sends templates for 1 or more groups.
4223  * This loops through the groups and adds the template to each
4224  * group's session and adds the template to the buffer.
4225  * This function is really meant for external templates, since
4226  * they are exported, although can be used for internal templates.
4227  * Since internal templates are not managed per group, they can simply
4228  * be added with fbSessionAddTemplate().
4229  * It is necessary to use this function if you plan on managing
4230  * templates per group.  Using fbSessionAddTemplate() will not allow
4231  * you to send a tmpl(s) to more than 1 group.
4232  *
4233  * @param session    a session state container
4234  * @param groups     group names
4235  * @param internal   TRUE for internal tmpl, FALSE for external
4236  * @param tid        template id
4237  * @param tmpl       pointer to template with template id tid
4238  * @param name       name of template (required)
4239  * @param description description of template (optional)
4240  * @param err        error mesasge
4241  * @return           template ID, or 0 on error
4242  */
4243 
4244 uint16_t fbSessionAddTemplatesMulticastWithMetadata(
4245     fbSession_t      *session,
4246     char             **groups,
4247     gboolean         internal,
4248     uint16_t         tid,
4249     fbTemplate_t     *tmpl,
4250     char             *name,
4251     char             *description,
4252     GError           **err);
4253 
4254 
4255 /**
4256  * Enables template metadata export for Spread Sessions.  This function is a
4257  * wrapper over fbSessionSpreadSetMetadataExportTemplates() with `tid` set
4258  * to FB_TID_AUTO.
4259  *
4260  * @param session pointer
4261  * @param groups spread groups to enable
4262  * @param enabled TRUE to enable template metadata export, FALSE to disable
4263  * @param err error message
4264  * @return TRUE on sucess, FALSE if IE template-metadata template could not be
4265  * added to the session.
4266  * @see fbSessionAddTemplatesMulticastWithMetadata()
4267  * @deprecated Use fbSessionSpreadSetMetadataExportTemplates() instead.
4268  */
4269 
4270 gboolean fbSessionSpreadEnableTemplateMetadata(
4271     fbSession_t                *session,
4272     char                       **groups,
4273     gboolean                   enabled,
4274     GError                     **err);
4275 
4276 /**
4277  * Enables template metadata export for Spread Sessions.  Template metadata is
4278  * the name and description specified by
4279  * fbSessionAddTemplatesMulticastWithMetadata().  When `enabled` is TRUE,
4280  * configures a session to send option records that describe templates.
4281  * Regardless of the `enabled` value, this function creates the
4282  * template-metadata template and adds it to the session with the template ID
4283  * `tid` or an arbitrary ID when `tid` is FB_TID_AUTO.
4284  *
4285  * @param session pointer
4286  * @param groups spread groups to enable
4287  * @param enabled TRUE to enable template metadata export, FALSE to disable
4288  * @param tid the template id to use for template-metadata records
4289  * @param err error message
4290  * @return the template id for template-metadata records or 0 if the template
4291  * could not be added to the session.
4292  *
4293  */
4294 
4295 uint16_t fbSessionSpreadSetMetadataExportTemplates(
4296     fbSession_t                *session,
4297     char                       **groups,
4298     gboolean                   enabled,
4299     uint16_t                   tid,
4300     GError                     **err);
4301 
4302 /**
4303  * Enables RFC 5610 information element metadata export for Spread Sessions.
4304  * When `enabled` is TRUE, configures the session to send option records for
4305  * each private enterprise element added to the information model.  This
4306  * function is a wrapper over fbSessionSpreadSetMetadataExportElements() with
4307  * `tid` set to FB_TID_AUTO.
4308  *
4309  * @param session pointer
4310  * @param groups spread groups to enable
4311  * @param enabled TRUE to enable metadata export, FALSE to disable
4312  * @param err error message
4313  * @return TRUE on sucess, FALSE if IE type template could not be added to
4314  * the session.
4315  * @deprecated Use fbSessionSpreadSetMetadataExportElements() instead.
4316  */
4317 
4318 gboolean fbSessionSpreadEnableTypeMetadata(
4319     fbSession_t                *session,
4320     char                       **groups,
4321     gboolean                   enabled,
4322     GError                     **err);
4323 
4324 /**
4325  * Enables RFC 5610 information element metadata export for Spread Sessions.
4326  * When `enabled` is TRUE, configures a session to send option records for
4327  * each private enterprise element added to the information model.  Regardless
4328  * of the `enabled` value, this function creates the type information template
4329  * and adds it to the session with the template ID `tid` or an arbitrary ID
4330  * when `tid` is FB_TID_AUTO.
4331  *
4332  * @param session pointer
4333  * @param groups spread groups to enable
4334  * @param enabled TRUE to enable metadata export, FALSE to disable
4335  * @param tid the template id to use for type metadata records
4336  * @param err error message
4337  * @return the template id for type-information records or 0 if the template
4338  * could not be added to the session.
4339  * @since libfixbuf 2.3.0
4340  */
4341 
4342 uint16_t fbSessionSpreadSetMetadataExportElements(
4343     fbSession_t                *session,
4344     char                       **groups,
4345     gboolean                   enabled,
4346     uint16_t                   tid,
4347     GError                     **err);
4348 #endif  /* HAVE_SPREAD */
4349 
4350 /**
4351  * Exports a single external template in the current domain of a given session.
4352  * Writes the template to the associated export buffer. May cause a message to
4353  * be emitted if the associated export buffer is in automatic mode, or return
4354  * with FB_ERROR_EOM if the associated export buffer is not in automatic mode.
4355  *
4356  * Also exports an options record containing the template's name and
4357  * description if they were specified (fbSessionAddTemplateWithMetadata()) and
4358  * metadata export is enabled (fbSessionSetMetadataExportTemplates()).
4359  *
4360  * @param session   a session state container associated with an export buffer
4361  * @param tid       template ID within current domain to export
4362  * @param err       an error description, set on failure.
4363  * @return TRUE on success, FALSE on failure.
4364  */
4365 
4366 gboolean            fbSessionExportTemplate(
4367     fbSession_t         *session,
4368     uint16_t            tid,
4369     GError              **err);
4370 
4371 /**
4372  * Exports all external templates in the current domain of a given session.
4373  * Writes templates to the associated export buffer. May cause a message to
4374  * be emitted if the associated export buffer is in automatic mode, or return
4375  * with FB_ERROR_EOM if the associated export buffer is not in automatic mode.
4376  *
4377  * When template and/or information element metadata is enabled, those options
4378  * records are also exported.
4379  *
4380  * All external templates are exported each time this function is called.
4381  *
4382  * @param session   a session state container associated with an export buffer
4383  * @param err       an error description, set on failure.
4384  * @return TRUE on success, FALSE on failure.
4385  * @see fbSessionSetMetadataExportTemplates() to enable template metadata,
4386  * fbSessionSetMetadataExportElements() to enable information element metadata
4387  */
4388 
4389 gboolean            fbSessionExportTemplates(
4390     fbSession_t         *session,
4391     GError              **err);
4392 
4393 /**
4394  * Adds a template to a session. If external, adds the template to the current
4395  * domain, and exports the template if the session is associated with an
4396  * export buffer. Gives the template the ID specified in tid, or assigns the
4397  * template an arbitrary ID if tid is @ref FB_TID_AUTO.
4398  *
4399  * Calling this function twice with the same parameters may cause the template
4400  * to be freed and the session to keep a handle to the invalid template.  If
4401  * necessary, first use fbSessionGetTemplate() to check for the presence of
4402  * the template on the session.
4403  *
4404  * @param session   A session state container
4405  * @param internal  TRUE if the template is internal, FALSE if external.
4406  * @param tid       Template ID to assign, replacing any current template
4407  *                  in case of collision; or FB_TID_AUTO to assign a new tId.
4408  * @param tmpl      Template to add
4409  * @param err       An error description, set on failure
4410  * @return the template ID of the added template, or 0 on failure.
4411  * @see fbSessionAddTemplateWithMetadata()
4412  */
4413 uint16_t            fbSessionAddTemplate(
4414     fbSession_t         *session,
4415     gboolean            internal,
4416     uint16_t            tid,
4417     fbTemplate_t        *tmpl,
4418     GError              **err);
4419 
4420 /**
4421  * Removes a template from a session.  If external, removes the template from
4422  * the current domain, and exports a template revocation set if the session is
4423  * associated with an export buffer.
4424  *
4425  * @param session   A session state container
4426  * @param internal  TRUE if the template is internal, FALSE if external.
4427  * @param tid       Template ID to remove.
4428  * @param err       An error description, set on failure
4429  * @return TRUE on success, FALSE on failure.
4430  */
4431 
4432 gboolean            fbSessionRemoveTemplate(
4433     fbSession_t         *session,
4434     gboolean            internal,
4435     uint16_t            tid,
4436     GError              **err);
4437 
4438 /**
4439  * Retrieves a template from a session by ID. If external, retrieves the
4440  * template within the current domain.
4441  *
4442  * @param session   A session state container
4443  * @param internal  TRUE if the template is internal, FALSE if external.
4444  * @param tid       ID of the template to retrieve.
4445  * @param err       An error description, set on failure.
4446  * @return The template with the given ID, or NULL on failure.
4447  */
4448 
4449 fbTemplate_t        *fbSessionGetTemplate(
4450     fbSession_t         *session,
4451     gboolean            internal,
4452     uint16_t            tid,
4453     GError              **err);
4454 
4455 /**
4456  * Allocates an exporting process endpoint for a network connection.
4457  * The remote collecting process is specified by the given connection specifier.
4458  * The underlying socket connection will not be opened until the first message
4459  * is emitted from the buffer associated with the exporter.
4460  *
4461  * @param spec      remote endpoint connection specifier.  A copy is made
4462                     for the exporter, it is freed later.  User is responsible
4463                     for original spec pointer
4464  * @return a new exporting process endpoint
4465  */
4466 
4467 fbExporter_t        *fbExporterAllocNet(
4468     fbConnSpec_t        *spec);
4469 
4470 #if HAVE_SPREAD
4471 /**
4472  * This function is useful if need to know what groups were set on the message.
4473  * Also useful if you are subscribed to more than 1 group, or want to know
4474  * what other groups the message published to.
4475  *
4476  * @param collector
4477  * @param groups of groups
4478  * @return number in the array of groups
4479  */
4480 int fbCollectorGetSpreadReturnGroups(
4481     fbCollector_t *collector,
4482     char *groups[]);
4483 
4484 /**
4485  *  Allocates an exporting process endpoint for a Spread connection.
4486  *  This connection will use the Spread toolkit for exporting and collecting
4487  *  IPFIX records.  Note that the connection to the Spread daemon will not
4488  *  take place until the first message is emitted from the buffer.
4489  *  This is not synonymous with appending the first record to the buffer.
4490  *  NOTE: unlike the other connection specifiers, the session MUST be set
4491  *  in the fbSpreadSpec_t structure BEFORE it is passed to this method.
4492  *
4493  * @param params      Spread connection specifier
4494  * @return a new exporting process endpoint
4495  */
4496 
4497 fbExporter_t        *fbExporterAllocSpread(
4498     fbSpreadParams_t      *params);
4499 
4500 #endif /* HAVE_SPREAD */
4501 
4502 /**
4503  * Allocates an exporting process endpoint for a named file. The underlying
4504  * file will not be opened until the first message is emitted from the
4505  * buffer associated with the exporter.
4506  *
4507  * @param path      pathname of the IPFIX File to write, or "-" to
4508  *                  open standard output.  Path is duplicated and handled.
4509  *                  Original pointer is up to the user.
4510  * @return a new exporting process endpoint
4511  */
4512 
4513 fbExporter_t        *fbExporterAllocFile(
4514     const char          *path);
4515 
4516 /**
4517  * Allocates an exporting process for a buffer. The underlying
4518  * buffer will be allocated to the given size.
4519  *
4520  * @param buf       buffer that will be allocated and used to copy IPFIX to.
4521  * @param bufsize   size of buffer that will be allocated.
4522  *
4523  * @return a new exporting process endpoint
4524  */
4525 fbExporter_t        *fbExporterAllocBuffer(
4526     uint8_t                  *buf,
4527     uint16_t                  bufsize);
4528 
4529 
4530 /**
4531  * Allocates an exporting process endpoint for an opened ANSI C file pointer.
4532  *
4533  * @param fp        open file pointer to write to.  File pointer is created
4534                     and freed outside of the Exporter functions.
4535  * @return a new exporting process endpoint
4536  */
4537 
4538 fbExporter_t        *fbExporterAllocFP(
4539     FILE                *fp);
4540 
4541 /**
4542  * Sets the SCTP stream for the next message exported. To change the SCTP
4543  * stream used for export, first emit any message in the exporter's associated
4544  * buffer with fbufEmit(), then use this call to set the stream for the next
4545  * message. This call cancels automatic stream selection, use
4546  * fbExporterAutoStream() to re-enable it. This call is a no-op for non-SCTP
4547  * exporters.
4548  *
4549  * @param exporter      an exporting process endpoint.
4550  * @param sctp_stream   SCTP stream to use for next message.
4551  */
4552 
4553 void                fbExporterSetStream(
4554     fbExporter_t        *exporter,
4555     int                 sctp_stream);
4556 
4557 /**
4558  * Enables automatic SCTP stream selection for the next message exported.
4559  * Automatic stream selection is the default; use this call to re-enable it
4560  * on a given exporter after using fbExporterSetStream(). With automatic
4561  * stream selection, the minimal behavior specified in the original IPFIX
4562  * protocol (RFC xxxx) is used: all templates and options templates are
4563  * exported on stream 0, and all data is exported on stream 1. This call is a
4564  * no-op for non-SCTP exporters.
4565  *
4566  * @param exporter      an exporting process endpoint.
4567  */
4568 
4569 void                fbExporterAutoStream(
4570     fbExporter_t        *exporter);
4571 
4572 /**
4573  * Forces the file or socket underlying an exporting process endpoint to close.
4574  * No effect on open file endpoints. The file or socket may be reopened on a
4575  * subsequent message emission from the associated buffer.
4576  *
4577  * @param exporter  an exporting process endpoint.
4578  */
4579 void                fbExporterClose(
4580     fbExporter_t       *exporter);
4581 
4582 /**
4583  * Gets the (transcoded) message length that was copied to the
4584  * exporting buffer upon fBufEmit().
4585  *
4586  * @param exporter an exporting process endpoint.
4587  */
4588 size_t fbExporterGetMsgLen(
4589     fbExporter_t   *exporter);
4590 
4591 /**
4592  * Allocates a collecting process endpoint for a named file. The underlying
4593  * file will be opened immediately.
4594  *
4595  * @param ctx       application context; for application use, retrievable
4596  *                  by fbCollectorGetContext()
4597  * @param path      path of file to read, or "-" to read standard input.
4598                     Used to get fp, user creates and frees.
4599  * @param err       An error description, set on failure.
4600  * @return a collecting process endpoint, or NULL on failure.
4601  */
4602 
4603 fbCollector_t       *fbCollectorAllocFile(
4604     void                *ctx,
4605     const char          *path,
4606     GError              **err);
4607 
4608 /**
4609  * Allocates a collecting process endpoint for an open file.
4610  *
4611  * @param ctx       application context; for application use, retrievable
4612  *                  by fbCollectorGetContext()
4613  * @param fp        file pointer to file to read.  Created and freed by user.
4614                     Must be kept around for the life of the collector.
4615  * @return a collecting process endpoint.
4616  */
4617 
4618 fbCollector_t       *fbCollectorAllocFP(
4619     void                *ctx,
4620     FILE                *fp);
4621 
4622 
4623 #if HAVE_SPREAD
4624 /**
4625  *   Allocates a collecting process endpoint for the Spread transport.
4626  *
4627  *   @param ctx      application context
4628  *   @param params   point to fbSpreadSpec_t containing Spread params
4629  *   @param err      error description, set on failure
4630  *
4631  *   @return         a collecting endpoint, or null on failure
4632  */
4633 
4634 fbCollector_t       *fbCollectorAllocSpread(
4635     void                *ctx,
4636     fbSpreadParams_t    *params,
4637     GError              **err);
4638 
4639 #endif /* HAVE_SPREAD */
4640 
4641 /**
4642  * Retrieves the application context associated with a collector. This context
4643  * is taken from the `ctx` argument of fbCollectorAllocFile() or
4644  * fbCollectorAllocFP(), or passed out via the `ctx` argument of the `appinit`
4645  * function argument (@ref fbListenerAppInit_fn) to fbListenerAlloc().
4646  *
4647  * @param collector a collecting process endpoint.
4648  * @return the application context
4649  */
4650 
4651 void                *fbCollectorGetContext(
4652     fbCollector_t       *collector);
4653 
4654 /**
4655  * Closes the file or socket underlying a collecting process endpoint.
4656  * No effect on open file endpoints. If the collector is attached to a
4657  * buffer managed by a listener, the buffer will be removed from the
4658  * listener (that is, it will not be returned by subsequent fbListenerWait()
4659  * calls).
4660  *
4661  * @param collector  a collecting process endpoint.
4662  */
4663 
4664 void                fbCollectorClose(
4665     fbCollector_t       *collector);
4666 
4667 
4668 /**
4669  * Sets the collector to only receive from the given IP address over UDP.
4670  * The port will be ignored.  Use fbListenerGetCollector() to get the pointer
4671  * to the collector after calling fbListenerAlloc(). ONLY valid for UDP.
4672  * Set the address family in address.
4673  *
4674  * @param collector pointer to collector
4675  * @param address pointer to sockaddr struct with IP address and family.
4676  * @param address_length address length
4677  *
4678  */
4679 void                fbCollectorSetAcceptOnly(
4680     fbCollector_t       *collector,
4681     struct sockaddr     *address,
4682     size_t              address_length);
4683 
4684 /**
4685  * Allocates a listener. The listener will listen on a specified local endpoint,
4686  * and create a new collecting process endpoint and collection buffer for each
4687  * incoming connection. Each new buffer will be associated with a clone of
4688  * a given session state container.
4689  *
4690  * The application may associate context with each created collecting process
4691  * endpoint, or veto a connection attempt, via a function colled on each
4692  * connection attempt passed in via the appinit parameter. If this function
4693  * will create application context, provide a function via the
4694  * appfree parameter which will free it.
4695  *
4696  * The fbListener_t returned should be freed by the application by calling
4697  * fbListenerFree().
4698  *
4699  * @param spec      local endpoint connection specifier.
4700                     A copy is made of this, which is freed by listener.
4701                     Original pointer freeing is up to the user.
4702  * @param session   session state container to clone for each collection buffer
4703  *                  created by the listener.  Not freed by listener.  Must
4704  *                  be kept alive while listener exists.
4705  * @param appinit   application connection initiation function. Called on each
4706  *                  collection attempt; vetoes connection attempts and creates
4707  *                  application context.
4708  * @param appfree   application context free function.
4709  * @param err       An error description, set on failure.
4710  * @return a new listener, or NULL on failure.
4711  */
4712 fbListener_t        *fbListenerAlloc(
4713     fbConnSpec_t            *spec,
4714     fbSession_t             *session,
4715     fbListenerAppInit_fn    appinit,
4716     fbListenerAppFree_fn    appfree,
4717     GError                  **err);
4718 
4719 /**
4720  * Frees a listener. Stops listening on the local endpoint, and frees any
4721  * open buffers still managed by the listener.
4722  *
4723  * @param listener a listener
4724  */
4725 
4726 void                fbListenerFree(
4727     fbListener_t            *listener);
4728 
4729 /**
4730  * Waits on a listener. Accepts pending connections from exporting processes.
4731  * Returns the next collection buffer with available data to read; if the
4732  * collection buffer returned by the last call to fbListenerWait() is available,
4733  * it is preferred. Blocks forever (or until fbListenerInterrupt() is called)
4734  * if no messages or connections are available.
4735  *
4736  * To effectively use fbListenerWait(), the application should set up an
4737  * session state container with internal templates, call fbListenerWait()
4738  * to accept a first connection, then read records from the collector buffer
4739  * to end of message (FB_ERROR_EOM). At end of message, the application should
4740  * then call fbListenerWait() to accept pending connections or switch to
4741  * another collector buffer with available data. Note that each collector
4742  * buffer returned created by fbListenerWait() is set to automatic mode using
4743  * fBufSetAutomaticMode().  To modify this behavior, call
4744  * fBufSetAutomaticMode(fbuf, TRUE) on the fbuf returned from this function.
4745  *
4746  * @param listener  a listener
4747  * @param err       An error description, set on failure.
4748  * @return a collection buffer with available data, or NULL on failure.
4749  */
4750 
4751 fBuf_t              *fbListenerWait(
4752     fbListener_t            *listener,
4753     GError                  **err);
4754 
4755 /**
4756  * Waits for an incoming connection, just like fbListenerWait(), except that
4757  * this function doesn't monitor active collectors.  This allows for a
4758  * multi threaded application to have one thread monitoring the listeners,
4759  * and one keeping track of collectors
4760  * @param listener  The listener to wait for connections on
4761  * @param err       An error description, set on failure.
4762  * @return a collection buffer for the new connection, NULL on failure.
4763  */
4764 
4765 fBuf_t              *fbListenerWaitNoCollectors(
4766     fbListener_t            *listener,
4767     GError                  **err);
4768 
4769 /**
4770  * Causes the current or next call to fbListenerWait() to unblock and return.
4771  * Use this from a thread or a signal handler to interrupt a blocked listener.
4772  *
4773  * @param listener listener to interrupt.
4774  */
4775 
4776 void                fbListenerInterrupt(
4777     fbListener_t            *listener);
4778 
4779 
4780 /**
4781  * If a collector is associated with the listener class, this will return a
4782  * handle to the collector state structure.
4783  *
4784  * @param listener handle to the listener state
4785  * @param collector pointer to a collector state pointer, set on return
4786  *        if there is no error
4787  * @param err a GError structure holding an error message on error
4788  * @return FALSE on error, check err, TRUE on success
4789  */
4790 gboolean            fbListenerGetCollector(
4791     fbListener_t        *listener,
4792     fbCollector_t       **collector,
4793     GError              **err);
4794 
4795 
4796 
4797 
4798 /**
4799  * Removes an input translator from a given collector such that it
4800  * will operate on IPFIX protocol again.
4801  *
4802  * @param collector the collector on which to remove
4803  *        the translator
4804  * @param err when an error occurs, a GLib GError
4805  *        structure is set with an error description
4806  *
4807  * @return TRUE on success, FALSE on failure
4808  */
4809 gboolean    fbCollectorClearTranslator(
4810     fbCollector_t   *collector,
4811     GError          **err);
4812 
4813 
4814 /**
4815  * Sets the collector input translator to convert NetFlowV9 into IPFIX
4816  * for the given collector.
4817  *
4818  * @param collector pointer to the collector state
4819  *        to perform Netflow V9 conversion on
4820  * @param err GError structure that holds the error
4821  *        message if an error occurs
4822  *
4823  * @return TRUE on success, FALSE on error
4824  */
4825 gboolean    fbCollectorSetNetflowV9Translator(
4826     fbCollector_t               *collector,
4827     GError                      **err);
4828 
4829 
4830 /**
4831  * Sets the collector input translator to convert SFlow into IPFIX for
4832  * the given collector.
4833  *
4834  * @param collector pointer to the collector state
4835  *        to perform SFlow conversion on
4836  * @param err GError structure that holds the error
4837  *        message if an error occurs
4838  *
4839  * @return TRUE on success, FALSE on error
4840  */
4841 gboolean    fbCollectorSetSFlowTranslator(
4842     fbCollector_t               *collector,
4843     GError                      **err);
4844 
4845 /**
4846  * Returns the number of potential missed export packets of the Netflow
4847  * v9 session that is currently set on the collector (the session is set on
4848  * the collector when an export packet is received) if peer is NULL.  If peer
4849  * is set, this will look up the session for that peer/obdomain pair and return
4850  * the missed export packets associated with that peer and obdomain.  If
4851  * peer/obdomain pair doesn't exist, this function returns 0.
4852  * This can't return the number of missed flow records since Netflow v9
4853  * increases sequence numbers by the number of export packets it has sent,
4854  * NOT the number of flow records (like IPFIX and netflow v5 does).
4855  *
4856  * @param collector
4857  * @param peer [OPTIONAL] peer address of NetFlow v9 exporter
4858  * @param peerlen size of peer object
4859  * @param obdomain observation domain of NetFlow v9 exporter
4860  * @return number of missed packets since beginning of session
4861  *
4862  */
4863 uint32_t fbCollectorGetNetflowMissed(
4864     fbCollector_t         *collector,
4865     struct sockaddr       *peer,
4866     size_t                 peerlen,
4867     uint32_t               obdomain);
4868 
4869 /**
4870  * Returns the number of potential missed export packets of the
4871  * SFlow session that is identified with the given ip/agentID. The agent
4872  * ID is a field that is in the sFlow header and is sent with every
4873  * packet.  Fixbuf keeps track of sequence numbers for sFlow sessions
4874  * per agent ID.
4875  *
4876  * @param collector
4877  * @param peer address of exporter to lookup
4878  * @param peerlen sizeof(peer)
4879  * @param obdomain observation domain of peer exporter
4880  * @return number of missed packets since beginning of session
4881  *
4882  */
4883 
4884 uint32_t fbCollectorGetSFlowMissed(
4885     fbCollector_t         *collector,
4886     struct sockaddr       *peer,
4887     size_t                 peerlen,
4888     uint32_t               obdomain);
4889 
4890 /**
4891  * Retrieves information about the node connected to this collector
4892  *
4893  * @param collector pointer to the collector to get peer information from
4894  * @return pointer to sockaddr structure containing IP information of peer
4895  */
4896 struct sockaddr* fbCollectorGetPeer(
4897     fbCollector_t   *collector);
4898 
4899 /**
4900  * Retrieves the observation domain of the node connected to the UDP collector.
4901  * The observation domain only gets set on the collector when collecting
4902  * via UDP.  If the collector is using another mode of transport, use
4903  * fbSessionGetDomain().
4904  *
4905  * @param collector
4906  *
4907  */
4908 uint32_t fbCollectorGetObservationDomain(
4909     fbCollector_t  *collector);
4910 
4911 /**
4912  * Enables or disables multi-session mode for a @ref fbCollector_t associated
4913  * with a UDP @ref fbListener_t.  The default setting is that multi-session
4914  * mode is disabled.
4915  *
4916  * When multi-session mode is enabled, libfixbuf invokes the `appinit`
4917  * callback (@ref fbListenerAppInit_fn) set on fbListenerAlloc() when a new
4918  * UDP connection occurs, allowing the callback to examine the peer address
4919  * and set a context for that UDP address.  In addition, the `appfree`
4920  * callback (@ref fbListenerAppFree_fn) is invoked when the @ref fbSession_t
4921  * for that collector times-out.
4922  *
4923  * Regardless of the multi-session mode setting, libfixbuf always calls the
4924  * `appinit` function when a UDP listener is created, passing NULL as the peer
4925  * address.
4926  *
4927  * The caller may use fbListenerGetCollector() to get the collector given a
4928  * listener.
4929  *
4930  * @param collector     pointer to collector associated with listener.
4931  * @param multi_session TRUE to enable multi-session, FALSE to disable
4932  */
4933 void fbCollectorSetUDPMultiSession(
4934     fbCollector_t *collector,
4935     gboolean       multi_session);
4936 
4937 
4938 #ifdef __cplusplus
4939 } /* extern "C" */
4940 #endif
4941 
4942 #endif /* _FB_PUBLIC_H_ */
4943