1 /**
2  * @file mediator_core.c
3  *
4  * Yaf mediator for filtering, DNS deduplication, and other mediator-like
5  * things
6  *
7  ** ------------------------------------------------------------------------
8  ** Copyright (C) 2012-2018 Carnegie Mellon University. All Rights Reserved.
9  ** ------------------------------------------------------------------------
10  * Authors: Emily Sarneso, Matt Coates <netsa-help@cert.org>
11  * ------------------------------------------------------------------------
12  * @OPENSOURCE_HEADER_START@
13  * Use of this (and related) source code is subject to the terms
14  * of the following licenses:
15  *
16  * GNU Public License (GPL) Rights pursuant to Version 2, June 1991
17  * Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
18  *
19  * This material is based upon work funded and supported by
20  * the Department of Defense under Contract FA8721-05-C-0003 with
21  * Carnegie Mellon University for the operation of the Software Engineering
22  * Institue, a federally funded research and development center. Any opinions,
23  * findings and conclusions or recommendations expressed in this
24  * material are those of the author(s) and do not
25  * necessarily reflect the views of the United States
26  * Department of Defense.
27  *
28  * NO WARRANTY
29  *
30  * THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE ENGINEERING INSTITUTE
31  * MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY
32  * MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED
33  * AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF
34  * FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS
35  * OBTAINED FROM THE USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY
36  * DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM
37  * PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
38  *
39  * This material has been approved for public release and unlimited
40  * distribution.
41  *
42  * Carnegie Mellon®, CERT® and CERT Coordination Center® are
43  * registered marks of Carnegie Mellon University.
44  *
45  * DM-0001877
46  *
47  * Carnegie Mellon University retains
48  * copyrights in all material produced under this contract. The U.S.
49  * Government retains a non-exclusive, royalty-free license to publish or
50  * reproduce these documents, or allow others to do so, for U.S.
51  * Government purposes only pursuant to the copyright license under the
52  * contract clause at 252.227.7013.
53  *
54  * Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
55  * Mellon University, its trustees, officers, employees, and agents from
56  * all claims or demands made against them (and any related losses,
57  * expenses, or attorney's fees) arising out of, or relating to Licensee's
58  * and/or its sub licensees' negligent use or willful misuse of or
59  * negligent conduct or willful misconduct regarding the Software,
60  * facilities, or other rights or assistance granted by Carnegie Mellon
61  * University under this License, including, but not limited to, any
62  * claims of product liability, personal injury, death, damage to
63  * property, or violation of any laws or regulations.
64  *
65  * @OPENSOURCE_HEADER_END@
66  * -----------------------------------------------------------
67  */
68 
69 #include <mediator/mediator_core.h>
70 #include <mediator/mediator_filter.h>
71 #include <mediator/mediator_util.h>
72 #include "mediator_stat.h"
73 #include "mediator_dns.h"
74 #include "mediator_dedup.h"
75 #include "mediator_print.h"
76 #include "mediator_ssl.h"
77 #include "infomodel.h"
78 
79 static fbTemplate_t *sm_sub_ssl_tmpl = NULL;
80 /* tpl_review: sizes OK, ie names OK, tpl name OK */
81 static fbInfoElementSpec_t md_main_template[] = {
82     { "flowStartMilliseconds",               8, 0 },
83     { "flowEndMilliseconds",                 8, 0 },
84     { "octetTotalCount",                     8, YTF_TOTAL },
85     { "reverseOctetTotalCount",              8, YTF_TOTAL | YTF_REV },
86     { "octetDeltaCount",                     8, YTF_DELTA },
87     { "reverseOctetDeltaCount",              8, YTF_REV | YTF_DELTA },
88     { "packetTotalCount",                    8, YTF_TOTAL },
89     { "reversePacketTotalCount",             8, YTF_TOTAL | YTF_REV },
90     { "packetDeltaCount",                    8, YTF_DELTA },
91     { "reversePacketDeltaCount",             8, YTF_REV | YTF_DELTA },
92     { "sourceIPv6Address",                   16, YTF_IP6 },
93     { "destinationIPv6Address",              16, YTF_IP6 },
94     { "sourceIPv4Address",                   4, YTF_IP4 },
95     { "destinationIPv4Address",              4, YTF_IP4 },
96     { "sourceTransportPort",                 2, 0 },
97     { "destinationTransportPort",            2, 0 },
98     { "flowAttributes",                      2, 0 },
99     { "reverseFlowAttributes",               2, YTF_REV },
100     { "protocolIdentifier",                  1, 0 },
101     { "flowEndReason",                       1, 0 },
102     { "silkAppLabel",                        2, 0 },
103     { "reverseFlowDeltaMilliseconds",        4, YTF_REV },
104     { "tcpSequenceNumber",                   4, YTF_TCP },
105     { "reverseTcpSequenceNumber",            4, YTF_TCP | YTF_REV },
106     { "initialTCPFlags",                     1, YTF_TCP },
107     { "unionTCPFlags",                       1, YTF_TCP },
108     { "reverseInitialTCPFlags",              1, YTF_TCP | YTF_REV },
109     { "reverseUnionTCPFlags",                1, YTF_TCP | YTF_REV },
110     /* MAC-specific information */
111     { "vlanId",                              2, 0 },
112     { "reverseVlanId",                       2, YTF_REV },
113     { "ingressInterface",                    4, YTF_DAGIF },
114     { "egressInterface",                     4, YTF_DAGIF },
115     { "ipClassOfService",                    1, 0 },
116     { "reverseIpClassOfService",             1, YTF_REV },
117     { "mplsTopLabelStackSection",            3, YTF_MPLS },
118     { "mplsLabelStackSection2",              3, YTF_MPLS },
119     { "mplsLabelStackSection3",              3, YTF_MPLS },
120     /* add an obs id */
121     { "paddingOctets",                       1, YTF_PAD },
122     { "observationDomainId",                 4, 0 },
123     { "yafFlowKeyHash",                      4, 0 },
124     { "nDPIL7Protocol",                      2, 0 },
125     { "nDPIL7SubProtocol",                   2, 0 },
126     { "subTemplateMultiList",                FB_IE_VARLEN, YTF_LIST },
127     FB_IESPEC_NULL
128 };
129 
130 /* tpl_review: sizes OK, ie names OK, tpl name OK */
131 static fbInfoElementSpec_t yaf_stats_option_spec[] = {
132     { "systemInitTimeMilliseconds",         8, 0 },
133     { "exportedFlowRecordTotalCount",       8, 0 },
134     { "packetTotalCount",                   8, 0 },
135     { "droppedPacketTotalCount",            8, 0 },
136     { "ignoredPacketTotalCount",            8, 0 },
137     { "notSentPacketTotalCount",            8, 0 },
138     { "expiredFragmentCount",               4, 0 },
139     { "assembledFragmentCount",             4, 0 },
140     { "flowTableFlushEventCount",           4, 0 },
141     { "flowTablePeakCount",                 4, 0 },
142     { "exporterIPv4Address",                4, 0 },
143     { "exportingProcessId",                 4, 0 },
144     { "meanFlowRate",                       4, 0 },
145     { "meanPacketRate",                     4, 0 },
146     FB_IESPEC_NULL
147 };
148 
149 static fbInfoElementSpec_t yaf_tombstone_option_spec[] = {
150     { "exporterConfiguredId",               2, 0 },
151     { "exporterUniqueId",                   2, 0 },
152     { "tombstoneId",                        4, 0 },
153     { "subTemplateList",                    FB_IE_VARLEN, 0 },
154     FB_IESPEC_NULL
155 };
156 
157 static fbInfoElementSpec_t yaf_tombstone_access_spec[] = {
158     { "exportingProcessId",                 4, 0 },
159     { "observationTimeSeconds",             4, 0 },
160     FB_IESPEC_NULL
161 };
162 
163 /* tpl_review: sizes OK, ie names OK, tpl name OK */
164 static fbInfoElementSpec_t yaf_entropy_spec[] = {
165     { "payloadEntropy",                     1, 0 },
166     { "reversePayloadEntropy",              1, YTF_REV },
167     FB_IESPEC_NULL
168 };
169 
170 /* tpl_review: sizes OK, ie names OK, tpl name OK */
171 static fbInfoElementSpec_t yaf_tcp_spec[] = {
172     /* TCP-specific information */
173     { "tcpSequenceNumber",                  4, 0 },
174     { "initialTCPFlags",                    1, 0 },
175     { "unionTCPFlags",                      1, 0 },
176     { "reverseInitialTCPFlags",             1, YTF_REV },
177     { "reverseUnionTCPFlags",               1, YTF_REV },
178     { "reverseTcpSequenceNumber",           4, YTF_REV },
179     FB_IESPEC_NULL
180 };
181 
182 /* tpl_review: sizes OK, ie names OK, tpl name OK */
183 static fbInfoElementSpec_t yaf_mptcp_spec[] = {
184     { "mptcpInitialDataSequenceNumber",     8, 0 },
185     { "mptcpReceiverToken",                 4, 0 },
186     { "mptcpMaximumSegmentSize",            2, 0 },
187     { "mptcpAddressID",                     1, 0 },
188     { "mptcpFlags",                         1, 0 },
189     FB_IESPEC_NULL
190 };
191 
192 /* tpl_review: sizes OK, ie names OK, tpl name OK */
193 /* MAC-specific information */
194 static fbInfoElementSpec_t yaf_mac_spec[] = {
195     { "sourceMacAddress",                   6, 0 },
196     { "destinationMacAddress",              6, 0 },
197     FB_IESPEC_NULL
198 };
199 
200 /* tpl_review: sizes OK, ie names OK, tpl name OK */
201 static fbInfoElementSpec_t yaf_p0f_spec[] = {
202     { "osName",                             FB_IE_VARLEN, 0 },
203     { "osVersion",                          FB_IE_VARLEN, 0 },
204     { "osFingerPrint",                      FB_IE_VARLEN, 0 },
205     { "reverseOsName",                      FB_IE_VARLEN, YTF_REV },
206     { "reverseOsVersion",                   FB_IE_VARLEN, YTF_REV },
207     { "reverseOsFingerPrint",               FB_IE_VARLEN, YTF_REV },
208     FB_IESPEC_NULL
209 };
210 
211 /* tpl_review: sizes OK, ie names OK, tpl name OK */
212 static fbInfoElementSpec_t yaf_fpexport_spec[] = {
213     { "firstPacketBanner",                  FB_IE_VARLEN, 0 },
214     { "secondPacketBanner",                 FB_IE_VARLEN, 0 },
215     { "reverseFirstPacketBanner",           FB_IE_VARLEN, YTF_REV },
216     FB_IESPEC_NULL
217 };
218 
219 /* tpl_review: sizes OK, ie names OK, tpl name OK */
220 /* Variable-length payload fields */
221 static fbInfoElementSpec_t yaf_payload_spec[] = {
222     { "payload",                            FB_IE_VARLEN, 0 },
223     { "reversePayload",                     FB_IE_VARLEN, YTF_REV },
224     FB_IESPEC_NULL
225 };
226 
227 /* tpl_review: FIXME: not found */
228 static fbInfoElementSpec_t yaf_singleBL_spec[] = {
229     {"basicList",       FB_IE_VARLEN, 0 },
230     FB_IESPEC_NULL
231 };
232 
233 /* tpl_review: sizes OK, ie names OK, tpl name OK */
234 static fbInfoElementSpec_t yaf_tftp_spec[] = {
235     {"tftpFilename",          FB_IE_VARLEN, 0 },
236     {"tftpMode",              FB_IE_VARLEN, 0 },
237     FB_IESPEC_NULL
238 };
239 
240 /* tpl_review: sizes OK, ie names OK, tpl name OK */
241 static fbInfoElementSpec_t yaf_flow_stats_spec[] = {
242     { "dataByteCount",                      8, 0 },
243     { "averageInterarrivalTime",            8, 0 },
244     { "standardDeviationInterarrivalTime",  8, 0 },
245     { "tcpUrgTotalCount",                   4, 0 },
246     { "smallPacketCount",                   4, 0 },
247     { "nonEmptyPacketCount",                4, 0 },
248     { "largePacketCount",                   4, 0 },
249     { "firstNonEmptyPacketSize",            2, 0 },
250     { "maxPacketSize",                      2, 0 },
251     { "standardDeviationPayloadLength",     2, 0 },
252     { "firstEightNonEmptyPacketDirections", 1, 0 },
253     { "paddingOctets",                      1, 1 },
254     { "reverseDataByteCount",               8, YTF_REV },
255     { "reverseAverageInterarrivalTime",     8, YTF_REV },
256     { "reverseStandardDeviationInterarrivalTime", 8, YTF_REV },
257     { "reverseTcpUrgTotalCount",            4, YTF_REV },
258     { "reverseSmallPacketCount",            4, YTF_REV },
259     { "reverseNonEmptyPacketCount",         4, YTF_REV },
260     { "reverseLargePacketCount",            4, YTF_REV },
261     { "reverseFirstNonEmptyPacketSize",     2, YTF_REV },
262     { "reverseMaxPacketSize",               2, YTF_REV },
263     { "reverseStandardDeviationPayloadLength", 2, YTF_REV },
264     { "paddingOctets",                      2, 1 },
265     FB_IESPEC_NULL
266 };
267 
268 /* tpl_review: sizes OK, ie names OK, tpl name OK */
269 static fbInfoElementSpec_t yaf_slp_spec[] = {
270     {"basicList",             FB_IE_VARLEN, 0 },
271     {"slpVersion",            1, 0 },
272     {"slpMessageType",        1, 0 },
273     {"paddingOctets",         6, 1 },
274     FB_IESPEC_NULL
275 };
276 
277 /* tpl_review: sizes OK, ie names OK, tpl name OK */
278 static fbInfoElementSpec_t yaf_http_spec[] = {
279     {"basicList",         FB_IE_VARLEN, 0 },
280     {"basicList",         FB_IE_VARLEN, 0 },
281     {"basicList",         FB_IE_VARLEN, 0 },
282     {"basicList",         FB_IE_VARLEN, 0 },
283     {"basicList",         FB_IE_VARLEN, 0 },
284     {"basicList",         FB_IE_VARLEN, 0 },
285     {"basicList",         FB_IE_VARLEN, 0 },
286     {"basicList",         FB_IE_VARLEN, 0 },
287     {"basicList",         FB_IE_VARLEN, 0 },
288     {"basicList",         FB_IE_VARLEN, 0 },
289     {"basicList",         FB_IE_VARLEN, 0 },
290     {"basicList",         FB_IE_VARLEN, 0 },
291     {"basicList",         FB_IE_VARLEN, 0 },
292     {"basicList",         FB_IE_VARLEN, 0 },
293     {"basicList",         FB_IE_VARLEN, 0 },
294     {"basicList",         FB_IE_VARLEN, 0 },
295     {"basicList",         FB_IE_VARLEN, 0 },
296     {"basicList",         FB_IE_VARLEN, 0 },
297     {"basicList",         FB_IE_VARLEN, 0 },
298     {"basicList",         FB_IE_VARLEN, 0 },
299     FB_IESPEC_NULL
300 };
301 /* tpl_review: sizes OK, ie names OK, tpl name OK */
302 static fbInfoElementSpec_t yaf_ftp_spec[] = {
303     {"basicList",         FB_IE_VARLEN, 0 },
304     {"basicList",         FB_IE_VARLEN, 0 },
305     {"basicList",         FB_IE_VARLEN, 0 },
306     {"basicList",         FB_IE_VARLEN, 0 },
307     {"basicList",         FB_IE_VARLEN, 0 },
308     FB_IESPEC_NULL
309 };
310 
311 /* tpl_review: sizes OK, ie names OK, tpl name OK */
312 static fbInfoElementSpec_t yaf_imap_spec[] = {
313     {"basicList",        FB_IE_VARLEN, 0 },
314     {"basicList",        FB_IE_VARLEN, 0 },
315     {"basicList",        FB_IE_VARLEN, 0 },
316     {"basicList",        FB_IE_VARLEN, 0 },
317     {"basicList",        FB_IE_VARLEN, 0 },
318     {"basicList",        FB_IE_VARLEN, 0 },
319     {"basicList",        FB_IE_VARLEN, 0 },
320     FB_IESPEC_NULL
321 };
322 
323 /* tpl_review: sizes OK, ie names OK, tpl name OK */
324 static fbInfoElementSpec_t yaf_rtsp_spec[] = {
325     {"basicList",         FB_IE_VARLEN, 0 },
326     {"basicList",         FB_IE_VARLEN, 0 },
327     {"basicList",         FB_IE_VARLEN, 0 },
328     {"basicList",         FB_IE_VARLEN, 0 },
329     {"basicList",         FB_IE_VARLEN, 0 },
330     {"basicList",         FB_IE_VARLEN, 0 },
331     {"basicList",         FB_IE_VARLEN, 0 },
332     {"basicList",         FB_IE_VARLEN, 0 },
333     {"basicList",         FB_IE_VARLEN, 0 },
334     {"basicList",         FB_IE_VARLEN, 0 },
335     {"basicList",         FB_IE_VARLEN, 0 },
336     {"basicList",         FB_IE_VARLEN, 0 },
337     FB_IESPEC_NULL
338 };
339 
340 /* tpl_review: sizes OK, ie names OK, tpl name OK */
341 static fbInfoElementSpec_t yaf_sip_spec[] = {
342     {"basicList",         FB_IE_VARLEN, 0 },
343     {"basicList",         FB_IE_VARLEN, 0 },
344     {"basicList",         FB_IE_VARLEN, 0 },
345     {"basicList",         FB_IE_VARLEN, 0 },
346     {"basicList",         FB_IE_VARLEN, 0 },
347     {"basicList",         FB_IE_VARLEN, 0 },
348     {"basicList",         FB_IE_VARLEN, 0 },
349     FB_IESPEC_NULL
350 };
351 
352 /* tpl_review: sizes OK, ie names OK, tpl name OK */
353 static fbInfoElementSpec_t yaf_smtp_spec[] = {
354     {"basicList",         FB_IE_VARLEN, 0 },
355     {"basicList",         FB_IE_VARLEN, 0 },
356     {"basicList",         FB_IE_VARLEN, 0 },
357     {"basicList",         FB_IE_VARLEN, 0 },
358     {"basicList",         FB_IE_VARLEN, 0 },
359     {"basicList",         FB_IE_VARLEN, 0 },
360     {"basicList",         FB_IE_VARLEN, 0 },
361     {"basicList",         FB_IE_VARLEN, 0 },
362     {"basicList",         FB_IE_VARLEN, 0 },
363     {"basicList",         FB_IE_VARLEN, 0 },
364     {"basicList",         FB_IE_VARLEN, 0 },
365     FB_IESPEC_NULL
366 };
367 
368 /* tpl_review: sizes OK, ie names OK, tpl name OK */
369 static fbInfoElementSpec_t yaf_nntp_spec[] = {
370     {"basicList",       FB_IE_VARLEN, 0 },
371     {"basicList",       FB_IE_VARLEN, 0 },
372     FB_IESPEC_NULL
373 };
374 
375 /* tpl_review: sizes OK, ie names OK, tpl name OK */
376 static fbInfoElementSpec_t yaf_dns_spec[] = {
377     {"subTemplateList",    FB_IE_VARLEN, 0 },
378     FB_IESPEC_NULL
379 };
380 /* tpl_review: sizes OK, ie names OK, tpl name OK */
381 static fbInfoElementSpec_t yaf_dnsQR_spec[] = {
382     {"subTemplateList",     FB_IE_VARLEN, 0 }, /*based on type of RR */
383     {"dnsQName",            FB_IE_VARLEN, 0 }, /*name - varfield*/
384     {"dnsTTL",              4, 0 },
385     {"dnsQRType",           2, 0 },  /*Type - uint8*/
386     {"dnsQueryResponse",    1, 0 },  /*Q or R - uint8*/
387     {"dnsAuthoritative",    1, 0 }, /* authoritative response (1)*/
388     {"dnsNXDomain",         1, 0 }, /* nxdomain (1) */
389     {"dnsRRSection",        1, 0 }, /*0, 1, 2 (ans, auth, add'l) */
390     {"dnsID",               2, 0 },
391     {"paddingOctets",       4, 1 },
392     FB_IESPEC_NULL
393 };
394 
395 /* tpl_review: sizes OK, ie names OK, tpl name OK */
396 static fbInfoElementSpec_t yaf_dnsA_spec[] = {
397     {"sourceIPv4Address",         4, 0 },
398     FB_IESPEC_NULL
399 };
400 
401 /* tpl_review: sizes OK, ie names OK, tpl name OK */
402 static fbInfoElementSpec_t yaf_dnsAAAA_spec[] = {
403     {"sourceIPv6Address",         16, 0 },
404     FB_IESPEC_NULL
405 };
406 
407 /* tpl_review: sizes OK, ie names OK, tpl name OK */
408 static fbInfoElementSpec_t yaf_dnsCNAME_spec[] = {
409     {"dnsCName",                  FB_IE_VARLEN, 0 },
410     FB_IESPEC_NULL
411 };
412 
413 /* tpl_review: sizes OK, ie names OK, tpl name OK */
414 static fbInfoElementSpec_t yaf_dnsMX_spec[] = {
415     {"dnsMXExchange",             FB_IE_VARLEN, 0 },
416     {"dnsMXPreference",           2, 0 },
417     {"paddingOctets",             6, 1 },
418     FB_IESPEC_NULL
419 };
420 
421 /* tpl_review: sizes OK, ie names OK, tpl name OK */
422 static fbInfoElementSpec_t yaf_dnsNS_spec[] = {
423     {"dnsNSDName",                FB_IE_VARLEN, 0 },
424     FB_IESPEC_NULL
425 };
426 
427 /* tpl_review: sizes OK, ie names OK, tpl name OK */
428 static fbInfoElementSpec_t yaf_dnsPTR_spec[] = {
429     {"dnsPTRDName",               FB_IE_VARLEN, 0 },
430     FB_IESPEC_NULL
431 };
432 
433 /* tpl_review: sizes OK, ie names OK, tpl name OK */
434 static fbInfoElementSpec_t yaf_dnsTXT_spec[] = {
435     {"dnsTXTData",                FB_IE_VARLEN, 0 },
436     FB_IESPEC_NULL
437 };
438 
439 /* tpl_review: sizes OK, ie names OK, tpl name OK */
440 static fbInfoElementSpec_t yaf_dnsSOA_spec[] = {
441     {"dnsSOAMName",               FB_IE_VARLEN, 0 },
442     {"dnsSOARName",               FB_IE_VARLEN, 0 },
443     {"dnsSOASerial",              4, 0 },
444     {"dnsSOARefresh",             4, 0 },
445     {"dnsSOARetry",               4, 0 },
446     {"dnsSOAExpire",              4, 0 },
447     {"dnsSOAMinimum",             4, 0 },
448     {"paddingOctets",             4, 1 },
449     FB_IESPEC_NULL
450 };
451 
452 /* tpl_review: sizes OK, ie names OK, tpl name OK */
453 static fbInfoElementSpec_t yaf_dnsSRV_spec[] = {
454     {"dnsSRVTarget",              FB_IE_VARLEN, 0 },
455     {"dnsSRVPriority",            2, 0 },
456     {"dnsSRVWeight",              2, 0 },
457     {"dnsSRVPort",                2, 0 },
458     {"paddingOctets",             2, 1 },
459     FB_IESPEC_NULL
460 };
461 
462 
463 /* tpl_review: sizes OK, ie names OK, tpl name OK */
464 static fbInfoElementSpec_t yaf_dnsDS_spec[] = {
465     {"dnsDigest",                 FB_IE_VARLEN, 0 },
466     {"dnsKeyTag",                 2, 0 },
467     {"dnsAlgorithm",              1, 0 },
468     {"dnsDigestType",             1, 0 },
469     {"paddingOctets",             4, 1 },
470     FB_IESPEC_NULL
471 };
472 
473 
474 /* tpl_review: sizes OK, ie names OK, tpl name OK */
475 static fbInfoElementSpec_t yaf_dnsRRSig_spec[] = {
476     {"dnsSigner",                 FB_IE_VARLEN, 0 },
477     {"dnsSignature",              FB_IE_VARLEN, 0 },
478     {"dnsSignatureInception",     4, 0 },
479     {"dnsSignatureExpiration",    4, 0 },
480     {"dnsTTL",                    4, 0 },
481     {"dnsKeyTag",                 2, 0 },
482     {"dnsTypeCovered",            2, 0 },
483     {"dnsAlgorithm",              1, 0 },
484     {"dnsLabels",                 1, 0 },
485     {"paddingOctets",             6, 1 },
486     FB_IESPEC_NULL
487 };
488 
489 /* tpl_review: sizes OK, ie names OK, tpl name OK */
490 static fbInfoElementSpec_t yaf_dnsNSEC_spec[] = {
491     {"dnsHashData",               FB_IE_VARLEN, 0 },
492     FB_IESPEC_NULL
493 };
494 
495 /* tpl_review: sizes OK, ie names OK, tpl name OK */
496 static fbInfoElementSpec_t yaf_dnsKey_spec[] = {
497     {"dnsPublicKey",              FB_IE_VARLEN, 0 },
498     {"dnsFlags",                  2, 0 },
499     {"protocolIdentifier",        1, 0 },
500     {"dnsAlgorithm",              1, 0 },
501     {"paddingOctets",             4, 1 },
502     FB_IESPEC_NULL
503 };
504 
505 /* tpl_review: sizes OK, ie names OK, tpl name OK */
506 static fbInfoElementSpec_t yaf_dnsNSEC3_spec[] = {
507     {"dnsSalt",                   FB_IE_VARLEN, 0 },
508     {"dnsHashData",               FB_IE_VARLEN, 0 },
509     {"dnsIterations",             2, 0 },
510     {"dnsAlgorithm",              1, 0 },
511     {"paddingOctets",             5, 1 },
512     FB_IESPEC_NULL
513 };
514 
515 
516 /* tpl_review: sizes OK, ie names OK, tpl name OK */
517 static fbInfoElementSpec_t yaf_ssl_spec[] = {
518     {"basicList",                 FB_IE_VARLEN, 0 }, /*list of ciphers 32bit */
519     {"sslServerCipher",           4, 0 }, /*cipher suite in server hello */
520     {"sslClientVersion",          1, 0 },
521     {"sslCompressionMethod",      1, 0 }, /*compression method in serv hello*/
522     {"paddingOctets",             2, 1 },
523     FB_IESPEC_NULL
524 };
525 
526 /* tpl_review: sizes OK, ie names OK, tpl name OK */
527 static fbInfoElementSpec_t yaf_newssl_spec[] = {
528     {"basicList",                 FB_IE_VARLEN, 0 }, /*list of ciphers 32bit */
529     {"sslServerCipher",           4, 0 }, /*cipher suite in server hello */
530     {"sslClientVersion",          1, 0 },
531     {"sslCompressionMethod",      1, 0 }, /*compression method in serv hello*/
532     {"sslRecordVersion",          2, 0 },
533     {"subTemplateList",           FB_IE_VARLEN, 0 }, /* list of certs */
534     {"sslServerName",             FB_IE_VARLEN, 0 },
535     FB_IESPEC_NULL
536 };
537 
538 /* tpl_review: sizes OK, ie names OK, tpl name OK */
539 static fbInfoElementSpec_t yaf_newssl_cert_spec[] = {
540     {"subTemplateList",             FB_IE_VARLEN, 0 },
541     {"subTemplateList",             FB_IE_VARLEN, 0 },
542     {"subTemplateList",             FB_IE_VARLEN, 0 },
543     {"sslCertSignature",            FB_IE_VARLEN, 0 },
544     {"sslCertSerialNumber",         FB_IE_VARLEN, 0 },
545     {"sslCertValidityNotBefore",    FB_IE_VARLEN, 0 },
546     {"sslCertValidityNotAfter",     FB_IE_VARLEN, 0 },
547     {"sslPublicKeyAlgorithm",       FB_IE_VARLEN, 0 },
548     {"sslPublicKeyLength",          2, 0 },
549     {"sslCertVersion",              1, 0 },
550     {"paddingOctets",               5, 1 },
551     {"sslCertificateHash",          FB_IE_VARLEN, 0 },
552     FB_IESPEC_NULL
553 };
554 
555 /* tpl_review: sizes OK, ie names OK, tpl name OK */
556 static fbInfoElementSpec_t yaf_subssl_spec[] = {
557     {"sslObjectValue",              FB_IE_VARLEN, 0 },
558     {"sslObjectType",               1, 0 },
559     {"paddingOctets",               7, 1 },
560     FB_IESPEC_NULL
561 };
562 
563 /* tpl_review: sizes OK, ie names OK, tpl name OK */
564 static fbInfoElementSpec_t yaf_ssl_cert_spec[] = {
565     {"sslCertSignature",            FB_IE_VARLEN, 0 },
566     {"sslCertIssuerCountryName",    FB_IE_VARLEN, 0 },
567     {"sslCertIssuerOrgName",        FB_IE_VARLEN, 0 },
568     {"sslCertIssuerOrgUnitName",    FB_IE_VARLEN, 0 },
569     {"sslCertIssuerZipCode",        FB_IE_VARLEN, 0 },
570     {"sslCertIssuerState",          FB_IE_VARLEN, 0 },
571     {"sslCertIssuerCommonName",     FB_IE_VARLEN, 0 },
572     {"sslCertIssuerLocalityName",   FB_IE_VARLEN, 0 },
573     {"sslCertIssuerStreetAddress",  FB_IE_VARLEN, 0 },
574     {"sslCertSubCountryName",       FB_IE_VARLEN, 0 },
575     {"sslCertSubOrgName",           FB_IE_VARLEN, 0 },
576     {"sslCertSubOrgUnitName",       FB_IE_VARLEN, 0 },
577     {"sslCertSubZipCode",           FB_IE_VARLEN, 0 },
578     {"sslCertSubState",             FB_IE_VARLEN, 0 },
579     {"sslCertSubCommonName",        FB_IE_VARLEN, 0 },
580     {"sslCertSubLocalityName",      FB_IE_VARLEN, 0 },
581     {"sslCertSubStreetAddress",     FB_IE_VARLEN, 0 },
582     {"sslCertVersion",              1, 0 },
583     FB_IESPEC_NULL
584 };
585 
586 /* tpl_review: sizes OK, ie names OK, tpl name OK */
587 static fbInfoElementSpec_t yaf_mysql_spec[] = {
588     {"subTemplateList",            FB_IE_VARLEN, 0 },
589     {"mysqlUsername",              FB_IE_VARLEN, 0 },
590     FB_IESPEC_NULL
591 };
592 
593 /* tpl_review: sizes OK, ie names OK, tpl name OK */
594 static fbInfoElementSpec_t yaf_mysql_txt_spec[] = {
595     {"mysqlCommandText",           FB_IE_VARLEN, 0 },
596     {"mysqlCommandCode",           1, 0 },
597     {"paddingOctets",              7, 1 },
598     FB_IESPEC_NULL
599 };
600 
601 /* tpl_review: sizes OK, ie names OK, tpl name OK */
602 static fbInfoElementSpec_t yaf_dhcp_fp_spec[] = {
603     {"dhcpFingerPrint",             FB_IE_VARLEN, 0 },
604     {"dhcpVendorCode",              FB_IE_VARLEN, 0 },
605     {"reverseDhcpFingerPrint",      FB_IE_VARLEN, YTF_REV },
606     {"reverseDhcpVendorCode",       FB_IE_VARLEN, YTF_REV },
607     FB_IESPEC_NULL
608 };
609 
610 /* tpl_review: sizes OK, ie names OK, tpl name OK */
611 static fbInfoElementSpec_t yaf_dhcp_options_spec[] = {
612     {"basicList",                   FB_IE_VARLEN, 0 },
613     {"dhcpVendorCode",              FB_IE_VARLEN, 0 },
614     {"basicList",                   FB_IE_VARLEN, YTF_REV},
615     {"reverseDhcpVendorCode",       FB_IE_VARLEN, YTF_REV },
616     FB_IESPEC_NULL
617 };
618 
619 /* tpl_review: sizes OK, ie names OK, tpl name OK */
620 static fbInfoElementSpec_t yaf_rtp_spec[] = {
621     {"rtpPayloadType",           1, 0 },
622     {"reverseRtpPayloadType",    1, 0 },
623     FB_IESPEC_NULL
624 };
625 
626 /* tpl_review: sizes OK, ie names OK, tpl name OK */
627 static fbInfoElementSpec_t yaf_dnp_rec_spec[] = {
628     {"dnp3SourceAddress",        2, 0 },
629     {"dnp3DestinationAddress",   2, 0 },
630     {"dnp3Function",             1, 0 },
631     {"paddingOctets",            3, 1 },
632     {"dnp3ObjectData",           FB_IE_VARLEN, 0 },
633     FB_IESPEC_NULL
634 };
635 
636 /* tpl_review: sizes OK, ie names OK, tpl name OK */
637 static fbInfoElementSpec_t yaf_dnp_spec[] = {
638     {"subTemplateList",     FB_IE_VARLEN, 0 },
639     FB_IESPEC_NULL
640 };
641 
642 
643 /* tpl_review: sizes OK, ie names OK, tpl name OK */
644 static fbInfoElementSpec_t md_dns_spec[] = {
645     /* Millisecond first seen and last seen (epoch) (native time) */
646     { "flowStartMilliseconds",              8, 0 },
647     { "flowEndMilliseconds",                8, MD_LAST_SEEN },
648     /* A-record IP */
649     { "sourceIPv4Address",                  4, MD_DNS_AREC },
650     /** Max TTL */
651     { "dnsTTL",                             4, MD_LAST_SEEN },
652     /* rrType */
653     { "dnsQRType",                          2, 0 },
654     /* how many times we saw it */
655     { "dnsHitCount",                        2, MD_LAST_SEEN },
656     { "paddingOctets",                      4, 1 },
657     /* rrData */
658     { "dnsQName",                           FB_IE_VARLEN, 0 },
659     { "dnsRName",                           FB_IE_VARLEN, MD_DNS_OREC },
660     { "observationDomainName",              FB_IE_VARLEN, 0 },
661     FB_IESPEC_NULL
662 };
663 
664 /* tpl_review: sizes OK, ie names OK, tpl name OK */
665 static fbInfoElementSpec_t md_dns_rr_spec[] = {
666     { "flowStartMilliseconds",              8, 0 },
667     { "sourceIPv6Address",                  16, YTF_IP6 | MD_DNSRR_FULL },
668     { "destinationIPv6Address",             16, YTF_IP6 | MD_DNSRR_FULL },
669     { "sourceIPv4Address",                  4, YTF_IP4 | MD_DNSRR_FULL },
670     { "destinationIPv4Address",             4, YTF_IP4 | MD_DNSRR_FULL },
671     { "dnsTTL",                             4, 0 },
672     { "observationDomainId",                4, 0 },
673     { "yafFlowKeyHash",                     4, 0 },
674     { "dnsQRType",                          2, 0 },
675     { "sourceTransportPort",                2, MD_DNSRR_FULL },
676     { "destinationTransportPort",           2, MD_DNSRR_FULL },
677     { "vlanId",                             2, MD_DNSRR_FULL },
678     { "dnsID",                              2, 0 },
679     { "protocolIdentifier",                 1, MD_DNSRR_FULL },
680     { "dnsQueryResponse",                   1, 0 },  /*Q or R - uint8*/
681     { "dnsAuthoritative",                   1, 0 }, /* auth response (1)*/
682     { "dnsNXDomain",                        1, 0 }, /* nxdomain (1) */
683     { "dnsRRSection",                       1, 0 }, /*(qry,ans,auth,add'l) */
684     { "paddingOctets",                      5, 1 },
685     { "dnsQName",                           FB_IE_VARLEN, 0 },
686     { "dnsRName",                           FB_IE_VARLEN, 0 },
687     FB_IESPEC_NULL
688 };
689 
690 /* tpl_review: sizes OK, ie names OK, tpl name OK */
691 static fbInfoElementSpec_t md_dedup_spec[] = {
692     /* Millisecond first seen and last seen (epoch) (native time) */
693     { "monitoringIntervalStartMilliSeconds", 8, 0 },
694     { "monitoringIntervalEndMilliSeconds",   8, 0 },
695     { "flowStartMilliseconds",              8, 0 },
696     { "observedDataTotalCount",             8, 0 },
697     { "sourceIPv6Address",                  16, 0 },
698     { "sourceIPv4Address",                  4, 0 },
699     { "yafFlowKeyHash",                     4, 0 },
700     { "observationDomainName",              FB_IE_VARLEN, 0 },
701     { "observedData",                       FB_IE_VARLEN, 0 },
702     { "sslCertSerialNumber",                FB_IE_VARLEN, MD_DEDUP_SSL },
703     { "sslCertIssuerCommonName",            FB_IE_VARLEN, MD_DEDUP_SSL },
704     { "sslCertSerialNumber",                FB_IE_VARLEN, MD_DEDUP_SSL },
705     { "sslCertIssuerCommonName",            FB_IE_VARLEN, MD_DEDUP_SSL },
706     FB_IESPEC_NULL
707 };
708 
709 /* tpl_review: sizes OK, ie names OK, tpl name OK */
710 static fbInfoElementSpec_t md_ssl_spec[] = {
711     { "flowStartMilliseconds",              8, 0 },
712     { "flowEndMilliseconds",                8, 0 },
713     { "observedDataTotalCount",             8, 0 },
714     { "sslCertSerialNumber",                FB_IE_VARLEN, 0 },
715     { "sslCertIssuerCommonName",            FB_IE_VARLEN, 0 },
716     { "observationDomainName",              FB_IE_VARLEN, 0 },
717     FB_IESPEC_NULL
718 };
719 
720 
721 
722 /**
723  * mdInfoModel
724  *
725  * create an appropriate info model  --- see mediator_CERT_IE.h
726  * ================================
727  * alloc the default (with IANA elements pre-populated) via fbInfoModelAlloc
728  * add in the CERT/NetSA added elements using infomodelAddGlobalElements
729  * need to add the FB_IE_INIT("silkAppLabel", 6871, 33, 2, FB_IE_F_ENDIAN)
730  * information element to the model that creates a complete info model
731  * for use through the rest of the app
732  * (fbInfoModel_t)
733  *
734  */
735 
mdInfoModel()736 fbInfoModel_t *mdInfoModel()
737 {
738 
739     static fbInfoModel_t *md_info_model = NULL;
740 
741     if (!md_info_model) {
742 
743         md_info_model = fbInfoModelAlloc();
744 
745         infomodelAddGlobalElements(md_info_model);
746 
747         if (user_elements) {
748             fbInfoModelAddElementArray(md_info_model, user_elements);
749         }
750     }
751 
752     return md_info_model;
753 }
754 
templateFree(void * tmpl_ctx,void * app_ctx)755 static void templateFree(
756     void *tmpl_ctx,
757     void *app_ctx)
758 {
759     g_slice_free(mdTmplContext_t, tmpl_ctx);
760 }
761 
762 
mdTemplateCallback(fbSession_t * session,uint16_t tid,fbTemplate_t * tmpl,void * app_ctx,void ** tmpl_ctx,fbTemplateCtxFree_fn * fn)763 static void mdTemplateCallback(
764     fbSession_t          *session,
765     uint16_t             tid,
766     fbTemplate_t         *tmpl,
767     void                 *app_ctx,
768     void                 **tmpl_ctx,
769     fbTemplateCtxFree_fn *fn)
770 {
771     /*uint16_t ntid = tid & 0xFF0F;*/
772     fbInfoModel_t *sm_model = mdInfoModel();
773     fbInfoElement_t *ie = NULL;
774     GError *err = NULL;
775     uint16_t ntid = 0;
776     mdTmplContext_t *myctx = NULL;
777 
778     /* We do this because the SSL Templates/Records have changed
779        between YAF releases and we don't want any read errors due
780        to typecasting the STMLs and STLs.  This is the proper way
781        to decode the data in IPFIX. */
782     if (tid == YAF_NEW_SSL_FLOW_TID) {
783         fbSessionAddTemplatePair(session, tid, SM_INTSSL_FLOW_TID);
784     } else if (tid == YAF_NEW_SSL_CERT_TID) {
785         fbSessionAddTemplatePair(session, tid, SM_INTCERT_FLOW_TID);
786     } else if (tid == MD_DEDUP_FULL) {
787         /* standard ssl dedup rec */
788         /* md_dedup_rec */
789         fbSessionAddTemplatePair(session, tid, tid);
790     } else if (tid == MD_SSL_TID) {
791         /* standard cert dedup rec */
792         /* md_ssl_spec */
793         fbSessionAddTemplatePair(session, tid, tid);
794     } else if (fbTemplateContainsElement(tmpl,
795                                          fbInfoModelGetElementByName(sm_model,
796                                          "observedDataTotalCount")))
797     {
798         /* this is a dedup record */
799         ntid = fbSessionAddTemplate(session, TRUE, tid, tmpl, &err);
800         if (ntid == 0) {
801             g_warning("Unable to add incoming template %02x to session %s",
802                       tid, err->message);
803         }
804 
805         myctx = g_slice_new0(mdTmplContext_t);
806         myctx->tid = ntid;
807         myctx->num_elem = fbTemplateCountElements(tmpl);
808         /* Get the last element in the template */
809         ie = fbTemplateGetIndexedIE(tmpl, (myctx->num_elem)-1);
810         /* get the id of the IE */
811         myctx->ie = ie->num;
812         *tmpl_ctx = myctx;
813         *fn = templateFree;
814         /* need to set this so internal template matches up with struct */
815     } else {
816         fbSessionAddTemplatePair(session, tid, tid);
817     }
818 
819     return;
820 }
821 
822 
823 #ifdef HAVE_SPREAD
mdAddSpreadTmpl(fbSession_t * session,fbInfoElementSpec_t * spec,uint16_t tid,gboolean rev,GError ** err)824 static fbTemplate_t *mdAddSpreadTmpl(
825     fbSession_t       *session,
826     fbInfoElementSpec_t *spec,
827     uint16_t           tid,
828     gboolean           rev,
829     GError            **err)
830 {
831 
832     fbInfoModel_t *model = mdInfoModel();
833     fbTemplate_t  *tmpl = NULL;
834     uint16_t      rtid = rev ? tid | YTF_REV : tid;
835 
836     tmpl = fbTemplateAlloc(model);
837 
838     if (!fbTemplateAppendSpecArray(tmpl, spec, 0xffffffff, err)) {
839         return NULL;
840     }
841 
842     if (!(fbSessionAddTemplate(session, TRUE, rtid, tmpl, err))) {
843         return NULL;
844     }
845 
846     if (!fbSessionAddTemplatesMulticast(session, md_config.out_spread.groups,
847                                         FALSE, rtid, tmpl, err))
848     {
849         return NULL;
850     }
851 
852     if (rev) {
853         tmpl = fbTemplateAlloc(model);
854 
855         if (!fbTemplateAppendSpecArray(tmpl, spec, 0, err)) {
856             return NULL;
857         }
858 
859         if (!fbSessionAddTemplatesMulticast(session,
860                                             md_config.out_spread.groups,
861                                             FALSE, tid, tmpl, err))
862         {
863             return NULL;
864         }
865     }
866 
867     return tmpl;
868 }
869 
870 /**
871  * mdInitSpreadExporterSession
872  *
873  *
874  *
875  **/
mdInitSpreadExporterSession(fbSession_t * session,gboolean dedup,GError ** err)876 fbSession_t *mdInitSpreadExporterSession(
877     fbSession_t      *session,
878     gboolean         dedup,
879     GError           **err)
880 {
881     fbTemplate_t *tmpl = NULL;
882 
883     if (!mdAddSpreadTmpl(session, md_main_template, YAF_SILK_FLOW_TID, FALSE,
884                          err))
885     {
886         return NULL;
887     }
888 
889     if (dedup) {
890         if (!mdAddSpreadTmpl(session, md_dns_spec, MD_DNS_FULL, FALSE, err)) {
891             return NULL;
892         }
893     }
894 
895     /* dns rr only template */
896     if (!mdAddSpreadTmpl(session, md_dns_rr_spec, MD_DNSRR, FALSE, err)) {
897         return NULL;
898     }
899 
900     /* dedup template */
901     if (!mdAddSpreadTmpl(session, md_dedup_spec, MD_DEDUP_FULL, FALSE, err)) {
902         return NULL;
903     }
904 
905     /* ssl dedup template */
906     if (!mdAddSpreadTmpl(session, md_ssl_spec, MD_SSL_TID, FALSE, err)) {
907         return NULL;
908     }
909 
910     /* add export template */
911     tmpl = fbTemplateAlloc(mdInfoModel());
912     if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec, 0, err)) {
913         return NULL;
914     }
915     if (!fbSessionAddTemplatesMulticast(session, md_config.out_spread.groups,
916                                         FALSE, MD_DNSRR, tmpl, err))
917     {
918         return NULL;
919     }
920 
921     /* Options Stats Template */
922     tmpl = mdAddSpreadTmpl(session, yaf_stats_option_spec,
923                            YAF_STAT_OPTN_FLOW_TID, FALSE, err);
924     if (!tmpl) {
925         return NULL;
926     }
927     fbTemplateSetOptionsScope(tmpl, 2);
928 
929     /* Options Tombstone Template */
930     tmpl = mdAddSpreadTmpl(session, yaf_tombstone_option_spec,
931                            YAF_TOMBSTONE_FLOW_TID, FALSE, err);
932     if (!tmpl) {
933         return NULL;
934     }
935     fbTemplateSetOptionsScope(tmpl, 2);
936     tmpl = mdAddSpreadTmpl(session, yaf_tombstone_access_spec,
937                            YAF_TOMBSTONE_ACCESS_TID, FALSE, err);
938     if (!tmpl) {
939         return NULL;
940     }
941 
942     /* flow stats template */
943     if (!mdAddSpreadTmpl(session, yaf_flow_stats_spec, YAF_STATS_FLOW_TID,
944                          TRUE, err))
945     {
946         return NULL;
947     }
948 
949     /* Entropy Template */
950     if (!mdAddSpreadTmpl(session, yaf_entropy_spec, YAF_ENTROPY_FLOW_TID,
951                          TRUE, err))
952     {
953         return NULL;
954     }
955 
956     /* TCP Template */
957     if (!mdAddSpreadTmpl(session, yaf_tcp_spec, YAF_TCP_FLOW_TID, TRUE, err)) {
958         return NULL;
959     }
960 
961     /* MPTCP Template */
962     if (!mdAddSpreadTmpl(session, yaf_mptcp_spec, YAF_MPTCP_FLOW_TID, FALSE, err)) {
963         return NULL;
964     }
965 
966     /* MAC Template */
967     if (!mdAddSpreadTmpl(session, yaf_mac_spec, YAF_MAC_FLOW_TID, FALSE, err)){
968         return NULL;
969     }
970 
971 
972     /* p0f Template */
973     if (!mdAddSpreadTmpl(session, yaf_p0f_spec,YAF_P0F_FLOW_TID, TRUE, err)) {
974         return NULL;
975     }
976 
977     /* dhcp Template */
978     if (!mdAddSpreadTmpl(session, yaf_dhcp_fp_spec, YAF_DHCP_FLOW_TID,
979                          TRUE, err))
980     {
981         return NULL;
982     }
983 
984     if (!mdAddSpreadTmpl(session, yaf_dhcp_options_spec, YAF_DHCP_OP_TID,
985                          TRUE, err))
986     {
987         return NULL;
988     }
989 
990     /* fpExport Template */
991     if (!mdAddSpreadTmpl(session, yaf_fpexport_spec,YAF_FPEXPORT_FLOW_TID,
992                          TRUE, err))
993     {
994         return NULL;
995     }
996 
997     /* Payload Template */
998     if (!mdAddSpreadTmpl(session, yaf_payload_spec,YAF_PAYLOAD_FLOW_TID, TRUE,
999                          err))
1000     {
1001         return NULL;
1002     }
1003 
1004     /* DPI TEMPLATES - HTTP*/
1005     if (!mdAddSpreadTmpl(session, yaf_http_spec,YAF_HTTP_FLOW_TID,FALSE, err)){
1006         return NULL;
1007     }
1008 
1009     /* IRC Template */
1010     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_IRC_FLOW_TID, FALSE,
1011                          err))
1012     {
1013         return NULL;
1014     }
1015 
1016     /* SSH Template */
1017     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_SSH_FLOW_TID, FALSE,
1018                          err))
1019     {
1020         return NULL;
1021     }
1022 
1023     /* POP3 Template */
1024     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_POP3_FLOW_TID, FALSE,
1025                          err))
1026     {
1027         return NULL;
1028     }
1029 
1030     /* TFTP Template */
1031     if (!mdAddSpreadTmpl(session, yaf_tftp_spec, YAF_TFTP_FLOW_TID, FALSE,
1032                          err))
1033     {
1034         return NULL;
1035     }
1036 
1037     /* SLP Template */
1038     if (!mdAddSpreadTmpl(session, yaf_slp_spec, YAF_SLP_FLOW_TID, FALSE,
1039                          err))
1040     {
1041         return NULL;
1042     }
1043 
1044     /* FTP Template */
1045     if (!mdAddSpreadTmpl(session, yaf_ftp_spec, YAF_FTP_FLOW_TID, FALSE, err))
1046     {
1047         return NULL;
1048     }
1049 
1050     /* IMAP Template */
1051     if (!mdAddSpreadTmpl(session, yaf_imap_spec, YAF_IMAP_FLOW_TID, FALSE,err))
1052     {
1053         return NULL;
1054     }
1055 
1056     /* RTSP Template */
1057     if (!mdAddSpreadTmpl(session, yaf_rtsp_spec, YAF_RTSP_FLOW_TID, FALSE,
1058                          err))
1059     {
1060         return NULL;
1061     }
1062 
1063     /* SIP Template */
1064     if (!mdAddSpreadTmpl(session, yaf_sip_spec, YAF_SIP_FLOW_TID, FALSE, err))
1065     {
1066         return NULL;
1067     }
1068 
1069     /* NNTP Template */
1070     if (!mdAddSpreadTmpl(session, yaf_nntp_spec, YAF_NNTP_FLOW_TID, FALSE,
1071                          err))
1072     {
1073         return NULL;
1074     }
1075 
1076     /* SMTP Template */
1077     if (!mdAddSpreadTmpl(session, yaf_smtp_spec, YAF_SMTP_FLOW_TID, FALSE,
1078                          err))
1079     {
1080         return NULL;
1081     }
1082 
1083     /* DNS Template */
1084     if (!mdAddSpreadTmpl(session, yaf_dns_spec, YAF_DNS_FLOW_TID, FALSE,
1085                          err))
1086     {
1087         return NULL;
1088     }
1089 
1090     /* DNS QR Template */
1091     if (!mdAddSpreadTmpl(session, yaf_dnsQR_spec, YAF_DNSQR_FLOW_TID, FALSE,
1092                          err))
1093     {
1094         return NULL;
1095     }
1096 
1097     /* DNS A Template */
1098     if (!mdAddSpreadTmpl(session, yaf_dnsA_spec, YAF_DNSA_FLOW_TID, FALSE,
1099                          err))
1100     {
1101         return NULL;
1102     }
1103 
1104     /* DNS AAAA Template */
1105     if (!mdAddSpreadTmpl(session, yaf_dnsAAAA_spec, YAF_DNSAAAA_FLOW_TID,FALSE,
1106                          err))
1107     {
1108         return NULL;
1109     }
1110 
1111     /* DNS CNAME Template */
1112     if (!mdAddSpreadTmpl(session, yaf_dnsCNAME_spec, YAF_DNSCN_FLOW_TID,
1113                          FALSE, err))
1114     {
1115         return NULL;
1116     }
1117 
1118     /* DNS MX Template */
1119     if (!mdAddSpreadTmpl(session, yaf_dnsMX_spec, YAF_DNSMX_FLOW_TID, FALSE,
1120                          err))
1121     {
1122         return NULL;
1123     }
1124 
1125     /* DNS NS Template */
1126     if (!mdAddSpreadTmpl(session, yaf_dnsNS_spec, YAF_DNSNS_FLOW_TID, FALSE,
1127                          err))
1128     {
1129         return NULL;
1130     }
1131 
1132     /* DNS PTR Template */
1133     if (!mdAddSpreadTmpl(session, yaf_dnsPTR_spec, YAF_DNSPTR_FLOW_TID, FALSE,
1134                          err))
1135     {
1136         return NULL;
1137     }
1138 
1139     /* DNS TXT Template */
1140     if (!mdAddSpreadTmpl(session, yaf_dnsTXT_spec, YAF_DNSTXT_FLOW_TID, FALSE,
1141                          err))
1142     {
1143         return NULL;
1144     }
1145 
1146     /* DNS SOA Template */
1147     if (!mdAddSpreadTmpl(session, yaf_dnsSOA_spec, YAF_DNSSOA_FLOW_TID, FALSE,
1148                          err))
1149     {
1150         return NULL;
1151     }
1152 
1153     /* DNS SRV Template */
1154     if (!mdAddSpreadTmpl(session, yaf_dnsSRV_spec, YAF_DNSSRV_FLOW_TID, FALSE,
1155                          err))
1156     {
1157         return NULL;
1158     }
1159 
1160     /* DNS DS Template */
1161     if (!mdAddSpreadTmpl(session, yaf_dnsDS_spec, YAF_DNSDS_FLOW_TID, FALSE,
1162                          err))
1163     {
1164         return NULL;
1165     }
1166 
1167     /* DNS RRSig Template */
1168     if (!mdAddSpreadTmpl(session, yaf_dnsRRSig_spec, YAF_DNSRRSIG_FLOW_TID,FALSE,
1169                          err))
1170     {
1171         return NULL;
1172     }
1173 
1174     /* DNS NSEC Template */
1175     if (!mdAddSpreadTmpl(session, yaf_dnsNSEC_spec, YAF_DNSNSEC_FLOW_TID,FALSE,
1176                          err))
1177     {
1178         return NULL;
1179     }
1180 
1181     /* DNS Key Template */
1182     if (!mdAddSpreadTmpl(session, yaf_dnsKey_spec, YAF_DNSKEY_FLOW_TID, FALSE,
1183                          err))
1184     {
1185         return NULL;
1186     }
1187 
1188     /* DNS NSEC3 Template */
1189     if (!mdAddSpreadTmpl(session, yaf_dnsNSEC3_spec, YAF_DNSNSEC3_FLOW_TID,
1190                          FALSE, err))
1191     {
1192         return NULL;
1193     }
1194 
1195     /* SSL Template */
1196     if (!mdAddSpreadTmpl(session, yaf_ssl_spec, YAF_SSL_FLOW_TID, FALSE, err))
1197     {
1198         return NULL;
1199     }
1200 
1201     /* SSL Cert Template */
1202     if (!mdAddSpreadTmpl(session, yaf_ssl_cert_spec, YAF_SSL_CERT_FLOW_TID, FALSE,
1203                          err))
1204     {
1205         return NULL;
1206     }
1207 
1208     /* New SSL Template */
1209     if (!mdAddSpreadTmpl(session, yaf_newssl_spec, YAF_NEW_SSL_FLOW_TID, FALSE,
1210                          err))
1211     {
1212         return NULL;
1213     }
1214 
1215     /* New SSL CERT Template */
1216     /* SSL Cert Template */
1217     if (!mdAddSpreadTmpl(session, yaf_newssl_cert_spec, YAF_NEW_SSL_CERT_TID,
1218                          FALSE, err))
1219     {
1220         return NULL;
1221     }
1222 
1223     /* SSL Sub Template */
1224     if (!mdAddSpreadTmpl(session, yaf_subssl_spec,
1225                          YAF_SSL_SUBCERT_TID, FALSE, err))
1226     {
1227         return NULL;
1228     }
1229 
1230     /* Full Cert SSL Template */
1231     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_FULL_CERT_TID, FALSE,
1232                          err))
1233     {
1234         return NULL;
1235     }
1236 
1237     /* MySQL Template */
1238     if (!mdAddSpreadTmpl(session, yaf_mysql_spec, YAF_MYSQL_FLOW_TID, FALSE,
1239                          err))
1240     {
1241         return NULL;
1242     }
1243 
1244     /* MYSQL TXT Template */
1245     if (!mdAddSpreadTmpl(session, yaf_mysql_txt_spec, YAF_MYSQLTXT_FLOW_TID,
1246                          FALSE, err))
1247     {
1248         return NULL;
1249     }
1250 
1251     /* DNP 3.0 */
1252     if (!mdAddSpreadTmpl(session, yaf_dnp_spec, YAF_DNP3_FLOW_TID, FALSE, err))
1253     {
1254         return NULL;
1255     }
1256 
1257     if (!mdAddSpreadTmpl(session, yaf_dnp_rec_spec, YAF_DNP3_REC_FLOW_TID,
1258                          FALSE, err))
1259     {
1260         return NULL;
1261     }
1262 
1263     /* Modbus */
1264     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_MODBUS_FLOW_TID,FALSE,
1265                          err))
1266     {
1267         return NULL;
1268     }
1269 
1270     /* ENIP */
1271     if (!mdAddSpreadTmpl(session, yaf_singleBL_spec, YAF_ENIP_FLOW_TID, FALSE,
1272                          err))
1273     {
1274         return NULL;
1275     }
1276 
1277     /** RTP */
1278     if (!mdAddSpreadTmpl(session, yaf_rtp_spec, YAF_RTP_FLOW_TID, FALSE, err))
1279     {
1280         return NULL;
1281     }
1282 
1283     return session;
1284 
1285 }
1286 #endif
1287 
1288 /**
1289  * mdAddTmpl
1290  *
1291  *
1292  */
mdAddTmpl(fbSession_t * session,fbInfoElementSpec_t * spec,uint16_t tid,gboolean rev,const gchar * name,const gchar * description,GError ** err)1293 static fbTemplate_t *mdAddTmpl(
1294     fbSession_t       *session,
1295     fbInfoElementSpec_t *spec,
1296     uint16_t           tid,
1297     gboolean           rev,
1298     const gchar *name,
1299     const gchar *description,
1300     GError            **err)
1301 {
1302 
1303     fbInfoModel_t *model = mdInfoModel();
1304     fbTemplate_t  *tmpl = NULL;
1305     uint16_t      rtid = rev ? tid | YTF_REV : tid;
1306 
1307     tmpl = fbTemplateAlloc(model);
1308 
1309     if (!fbTemplateAppendSpecArray(tmpl, spec, 0xffffffff, err)) {
1310         return NULL;
1311     }
1312 
1313     if (!(fbSessionAddTemplate(session, TRUE, rtid, tmpl, err))) {
1314         return NULL;
1315     }
1316 
1317 #if SM_ENABLE_METADATA_EXPORT
1318     if (!(fbSessionAddTemplateWithMetadata(session, FALSE, rtid, tmpl, name,description, err))) {
1319 #else
1320     if (!(fbSessionAddTemplate(session, FALSE, rtid, tmpl, err))) {
1321 #endif
1322         return NULL;
1323     }
1324 
1325     if (rev) {
1326         tmpl = fbTemplateAlloc(model);
1327 
1328         if (!fbTemplateAppendSpecArray(tmpl, spec, 0, err)) {
1329             return NULL;
1330         }
1331 
1332 #if SM_ENABLE_METADATA_EXPORT
1333         if (!(fbSessionAddTemplateWithMetadata(session, FALSE, tid, tmpl, name, description, err))) {
1334 #else
1335         if (!(fbSessionAddTemplate(session, FALSE, tid, tmpl, err))) {
1336 #endif
1337             return NULL;
1338         }
1339     }
1340 
1341     return tmpl;
1342 }
1343 
1344 
1345 /**
1346  * mdInitExporterSessionDNSDedupOnly
1347  *
1348  *
1349  */
1350 fbSession_t *mdInitExporterSessionDNSDedupOnly(
1351     fbSession_t     *session,
1352     GError          **err,
1353     uint8_t         stats,
1354     gboolean        metadata_export)
1355 {
1356     fbInfoModel_t      *model = mdInfoModel();
1357 
1358     /*Allocate the session */
1359     if (!session) {
1360         session = fbSessionAlloc(model);
1361     }
1362 #if SM_ENABLE_METADATA_EXPORT
1363     if (metadata_export) {
1364         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1365                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1366             return NULL;
1367         }
1368     }
1369 #endif
1370     if (!mdAddTmpl(session, md_dns_spec, MD_DNS_FULL, FALSE, "md_dns_dedup", NULL, err)) {
1371         return NULL;
1372     }
1373 
1374     if (stats != 1) {
1375         fbTemplate_t    *tmpl = NULL;
1376         /* Options Template */
1377         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1378                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1379         if (!tmpl) {
1380             return NULL;
1381         }
1382         fbTemplateSetOptionsScope(tmpl, 2);
1383 
1384         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1385                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1386         if (!tmpl) {
1387             return NULL;
1388         }
1389         fbTemplateSetOptionsScope(tmpl, 2);
1390         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1391                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1392                          "tombstone_access_record", NULL, err);
1393         if (!tmpl) {
1394             return NULL;
1395         }
1396     }
1397 
1398     return session;
1399 }
1400 
1401 /**
1402  * mdInitExporterSessionDNSRROnly
1403  *
1404  *
1405  */
1406 fbSession_t *mdInitExporterSessionDNSRROnly(
1407     fbSession_t      *session,
1408     GError           **err,
1409     uint8_t          stats,
1410     gboolean         metadata_export)
1411 {
1412     fbInfoModel_t    *model = mdInfoModel();
1413     fbTemplate_t     *tmpl = NULL;
1414 
1415     if (!session) {
1416         session = fbSessionAlloc(model);
1417     }
1418 #if SM_ENABLE_METADATA_EXPORT
1419     if (metadata_export) {
1420         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1421                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1422             return NULL;
1423         }
1424     }
1425 #endif
1426     tmpl = fbTemplateAlloc(model);
1427 
1428     if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec, 0xffffffff, err)) {
1429         return NULL;
1430     }
1431 
1432     if (!(fbSessionAddTemplate(session, TRUE, MD_DNSRR, tmpl, err))) {
1433         return NULL;
1434     }
1435 
1436     /* external template */
1437     tmpl = fbTemplateAlloc(model);
1438 
1439     if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec, 0, err)) {
1440         return NULL;
1441     }
1442 
1443 #if SM_ENABLE_METADATA_EXPORT
1444     if (!(fbSessionAddTemplateWithMetadata(session, FALSE, MD_DNSRR, tmpl, "md_dns_rr_external", NULL, err))) {
1445 #else
1446     if (!(fbSessionAddTemplate(session, FALSE, MD_DNSRR, tmpl, err))) {
1447 #endif
1448         return NULL;
1449     }
1450 
1451     if (stats != 1) {
1452         /* Options Template */
1453         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1454                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1455         if (!tmpl) {
1456             return NULL;
1457         }
1458         fbTemplateSetOptionsScope(tmpl, 2);
1459 
1460         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1461                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1462         if (!tmpl) {
1463             return NULL;
1464         }
1465         fbTemplateSetOptionsScope(tmpl, 2);
1466         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1467                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1468                          "tombstone_access_record", NULL, err);
1469     }
1470 
1471     return session;
1472 }
1473 
1474 
1475 fbSession_t *mdInitExporterSessionFlowOnly(
1476     fbSession_t      *session,
1477     GError           **err,
1478     uint8_t          stats,
1479     gboolean         metadata_export)
1480 {
1481     fbInfoModel_t   *model = mdInfoModel();
1482 
1483     if (!session) {
1484         session = fbSessionAlloc(model);
1485     }
1486 #if SM_ENABLE_METADATA_EXPORT
1487     if (metadata_export) {
1488         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1489                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1490             return NULL;
1491         }
1492     }
1493 #endif
1494     /* SiLK Template 4 Export*/
1495     if (!mdAddTmpl(session, md_main_template, YAF_SILK_FLOW_TID, FALSE,
1496                    "md_main_silk", NULL, err))
1497     {
1498         return NULL;
1499     }
1500 
1501     if (stats != 1) {
1502         fbTemplate_t    *tmpl = NULL;
1503         /* Options Template */
1504         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1505                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1506         if (!tmpl) {
1507             return NULL;
1508         }
1509         fbTemplateSetOptionsScope(tmpl, 2);
1510 
1511         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1512                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1513         if (!tmpl) {
1514             return NULL;
1515         }
1516         fbTemplateSetOptionsScope(tmpl, 2);
1517         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1518                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1519                          "tombstone_access_record", NULL, err);
1520     }
1521     return session;
1522 }
1523 
1524 
1525 fbSession_t *mdInitExporterSessionDedupOnly(
1526     fbSession_t      *session,
1527     GError           **err,
1528     uint8_t         stats,
1529     gboolean        metadata_export)
1530 {
1531 
1532     fbInfoModel_t   *model = mdInfoModel();
1533 
1534     if (!session) {
1535         session = fbSessionAlloc(model);
1536     }
1537 #if SM_ENABLE_METADATA_EXPORT
1538     if (metadata_export) {
1539         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1540                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1541             return NULL;
1542         }
1543     }
1544 #endif
1545     if (!mdAddTmpl(session, md_dedup_spec, MD_DEDUP_FULL, FALSE,
1546                    "md_dedup_full", NULL, err))
1547     {
1548         return NULL;
1549     }
1550 
1551     if (stats != 1) {
1552         fbTemplate_t    *tmpl = NULL;
1553         /* Options Template */
1554         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1555                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1556         if (!tmpl) {
1557             return NULL;
1558         }
1559         fbTemplateSetOptionsScope(tmpl, 2);
1560 
1561         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1562                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1563         if (!tmpl) {
1564             return NULL;
1565         }
1566         fbTemplateSetOptionsScope(tmpl, 2);
1567         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1568                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1569                          "tombstone_access_record", NULL, err);
1570     }
1571     return session;
1572 }
1573 
1574 fbSession_t *mdInitExporterSessionSSLDedupOnly(
1575     fbSession_t      *session,
1576     GError           **err,
1577     uint8_t          stats,
1578     gboolean         metadata_export)
1579 {
1580 
1581     fbInfoModel_t   *model = mdInfoModel();
1582 
1583     if (!session) {
1584         session = fbSessionAlloc(model);
1585     }
1586 #if SM_ENABLE_METADATA_EXPORT
1587     if (metadata_export) {
1588         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1589                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1590             return NULL;
1591         }
1592     }
1593 #endif
1594     /* SSL dedup spec 4 Export*/
1595     if (!mdAddTmpl(session, md_ssl_spec, MD_SSL_TID, FALSE,
1596                    "md_ssl_dedup", NULL, err))
1597     {
1598         return NULL;
1599     }
1600 
1601     if (!mdAddTmpl(session, yaf_newssl_cert_spec, YAF_NEW_SSL_CERT_TID,
1602                    FALSE, "yaf_ssl_cert", NULL, err))
1603     {
1604         return NULL;
1605     }
1606 
1607     /* SSL Sub Template */
1608     if (!mdAddTmpl(session, yaf_subssl_spec,
1609                    YAF_SSL_SUBCERT_TID, FALSE, "yaf_ssl_subcert", NULL, err))
1610     {
1611         return NULL;
1612     }
1613 
1614     if (stats != 1) {
1615         fbTemplate_t    *tmpl = NULL;
1616         /* Options Template */
1617         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1618                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1619         if (!tmpl) {
1620             return NULL;
1621         }
1622         fbTemplateSetOptionsScope(tmpl, 2);
1623         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1624                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1625         if (!tmpl) {
1626             return NULL;
1627         }
1628         fbTemplateSetOptionsScope(tmpl, 2);
1629         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1630                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1631                          "tombstone_access_record", NULL, err);
1632     }
1633     return session;
1634 }
1635 
1636 
1637 
1638 /**
1639  * mdInitExporterSession
1640  *
1641  *
1642  *
1643  **/
1644 fbSession_t *mdInitExporterSession(
1645     fbSession_t     *session,
1646     GError          **err,
1647     uint8_t         stats,
1648     gboolean        metadata_export)
1649 {
1650 
1651     fbTemplate_t     *tmpl = NULL;
1652     fbInfoModel_t    *model = mdInfoModel();
1653 
1654     /*Allocate the session */
1655     if (!session) {
1656         session = fbSessionAlloc(model);
1657     }
1658 
1659 #if SM_ENABLE_METADATA_EXPORT
1660     if (metadata_export) {
1661         if (!fbSessionEnableTypeMetadata(session, TRUE, err) ||
1662                 !fbSessionEnableTemplateMetadata(session, TRUE, err)) {
1663             return NULL;
1664         }
1665     }
1666 #endif
1667     /* SiLK Template 4 Export*/
1668     if (!mdAddTmpl(session, md_main_template, YAF_SILK_FLOW_TID, FALSE,
1669                          "md_main_silk", NULL, err))
1670     {
1671         return NULL;
1672     }
1673 
1674     /* dns dedup */
1675     if (!mdAddTmpl(session, md_dns_spec, MD_DNS_FULL, FALSE, "md_dns_full", NULL, err)) {
1676         return NULL;
1677     }
1678 
1679     /* dedup */
1680     if (!mdAddTmpl(session, md_dedup_spec, MD_DEDUP_FULL, FALSE, "md_dns_dedup_full", NULL, err)) {
1681         return NULL;
1682     }
1683 
1684     /* ssl dedup */
1685     if (!mdAddTmpl(session, md_ssl_spec, MD_SSL_TID, FALSE, "md_ssl_dedup", NULL, err)) {
1686         return NULL;
1687     }
1688 
1689     if (stats != 1) {
1690         /* Options Template */
1691         tmpl = mdAddTmpl(session, yaf_stats_option_spec,
1692                          YAF_STAT_OPTN_FLOW_TID, FALSE, "yaf_stats_options", NULL, err);
1693         if (!tmpl) {
1694             return NULL;
1695         }
1696         fbTemplateSetOptionsScope(tmpl, 2);
1697         tmpl = mdAddTmpl(session, yaf_tombstone_option_spec,
1698                          YAF_TOMBSTONE_FLOW_TID, FALSE, "tombstone_record", NULL, err);
1699         if (!tmpl) {
1700             return NULL;
1701         }
1702         fbTemplateSetOptionsScope(tmpl, 2);
1703         tmpl = mdAddTmpl(session, yaf_tombstone_access_spec,
1704                          YAF_TOMBSTONE_ACCESS_TID, FALSE,
1705                          "tombstone_access_record", NULL, err);
1706     }
1707 
1708     /* flow stats template */
1709     if (!mdAddTmpl(session, yaf_flow_stats_spec, YAF_STATS_FLOW_TID,
1710                          TRUE, "yaf_flow_stats", NULL, err))
1711     {
1712         return NULL;
1713     }
1714 
1715     /* Entropy Template */
1716     if (!mdAddTmpl(session, yaf_entropy_spec, YAF_ENTROPY_FLOW_TID,
1717                          TRUE, "yaf_entropy", NULL, err))
1718     {
1719         return NULL;
1720     }
1721 
1722     /* TCP Template */
1723     if (!mdAddTmpl(session, yaf_tcp_spec, YAF_TCP_FLOW_TID, TRUE, "yaf_tcp_flow", NULL, err)) {
1724         return NULL;
1725     }
1726 
1727     /* MPTCP Template */
1728     if (!mdAddTmpl(session, yaf_mptcp_spec, YAF_MPTCP_FLOW_TID, FALSE, "yaf_mptcp_flow", NULL, err)) {
1729         return NULL;
1730     }
1731 
1732     /* MAC Template */
1733     if (!mdAddTmpl(session, yaf_mac_spec, YAF_MAC_FLOW_TID, FALSE, "yaf_mac_flow", NULL, err)){
1734         return NULL;
1735     }
1736 
1737 
1738     /* p0f Template */
1739     if (!mdAddTmpl(session, yaf_p0f_spec,YAF_P0F_FLOW_TID, TRUE, "yaf_p0f_flow", NULL, err)) {
1740         return NULL;
1741     }
1742 
1743     /* dhcp Template */
1744     if (!mdAddTmpl(session, yaf_dhcp_fp_spec, YAF_DHCP_FLOW_TID,
1745                          TRUE, "yaf_dhcp_flow", NULL, err))
1746     {
1747         return NULL;
1748     }
1749 
1750     /*dhcp Options Template */
1751     if (!mdAddTmpl(session, yaf_dhcp_options_spec, YAF_DHCP_OP_TID,
1752                    TRUE, "yaf_dhcp_options", NULL, err))
1753     {
1754         return NULL;
1755     }
1756 
1757     /* fpExport Template */
1758     if (!mdAddTmpl(session, yaf_fpexport_spec,YAF_FPEXPORT_FLOW_TID,
1759                          TRUE, "yaf_fpexport_flow", NULL, err))
1760     {
1761         return NULL;
1762     }
1763 
1764     /* Payload Template */
1765     if (!mdAddTmpl(session, yaf_payload_spec,YAF_PAYLOAD_FLOW_TID, TRUE,
1766                          "yaf_payload_flow", NULL, err))
1767     {
1768         return NULL;
1769     }
1770 
1771     /* DPI TEMPLATES - HTTP*/
1772     if (!mdAddTmpl(session, yaf_http_spec,YAF_HTTP_FLOW_TID,FALSE, "yaf_http", NULL, err)){
1773         return NULL;
1774     }
1775 
1776     /* IRC Template */
1777     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_IRC_FLOW_TID, FALSE,
1778                          "yaf_irc", NULL, err))
1779     {
1780         return NULL;
1781     }
1782 
1783     /* SSH Template */
1784     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_SSH_FLOW_TID, FALSE,
1785                          "yaf_ssh", NULL, err))
1786     {
1787         return NULL;
1788     }
1789 
1790     /* POP3 Template */
1791     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_POP3_FLOW_TID, FALSE,
1792                          "yaf_pop3", NULL, err))
1793     {
1794         return NULL;
1795     }
1796 
1797     /* TFTP Template */
1798     if (!mdAddTmpl(session, yaf_tftp_spec, YAF_TFTP_FLOW_TID, FALSE,
1799                          "yaf_tftp", NULL, err))
1800     {
1801         return NULL;
1802     }
1803 
1804     /* SLP Template */
1805     if (!mdAddTmpl(session, yaf_slp_spec, YAF_SLP_FLOW_TID, FALSE,
1806                          "yaf_slp", NULL, err))
1807     {
1808         return NULL;
1809     }
1810 
1811     /* FTP Template */
1812     if (!mdAddTmpl(session, yaf_ftp_spec, YAF_FTP_FLOW_TID, FALSE, "yaf_ftp", NULL, err))
1813     {
1814         return NULL;
1815     }
1816 
1817     /* IMAP Template */
1818     if (!mdAddTmpl(session, yaf_imap_spec, YAF_IMAP_FLOW_TID, FALSE, "yaf_imap", NULL, err))
1819     {
1820         return NULL;
1821     }
1822 
1823     /* RTSP Template */
1824     if (!mdAddTmpl(session, yaf_rtsp_spec, YAF_RTSP_FLOW_TID, FALSE,
1825                          "yaf_rtsp", NULL, err))
1826     {
1827         return NULL;
1828     }
1829 
1830     /* SIP Template */
1831     if (!mdAddTmpl(session, yaf_sip_spec, YAF_SIP_FLOW_TID, FALSE, "yaf_sip", NULL, err))
1832     {
1833         return NULL;
1834     }
1835 
1836     /* NNTP Template */
1837     if (!mdAddTmpl(session, yaf_nntp_spec, YAF_NNTP_FLOW_TID, FALSE,
1838                          "yaf_nntp", NULL, err))
1839     {
1840         return NULL;
1841     }
1842 
1843     /* SMTP Template */
1844     if (!mdAddTmpl(session, yaf_smtp_spec, YAF_SMTP_FLOW_TID, FALSE,
1845                          "yaf_smtp", NULL, err))
1846     {
1847         return NULL;
1848     }
1849 
1850     /* DNS Template */
1851     if (!mdAddTmpl(session, yaf_dns_spec, YAF_DNS_FLOW_TID, FALSE,
1852                          "yaf_dns", NULL, err))
1853     {
1854         return NULL;
1855     }
1856 
1857     /* DNS QR Template */
1858     if (!mdAddTmpl(session, yaf_dnsQR_spec, YAF_DNSQR_FLOW_TID, FALSE,
1859                          "yaf_dns_qr", NULL, err))
1860     {
1861         return NULL;
1862     }
1863 
1864     /* DNS A Template */
1865     if (!mdAddTmpl(session, yaf_dnsA_spec, YAF_DNSA_FLOW_TID, FALSE,
1866                          "yaf_dns_a", NULL, err))
1867     {
1868         return NULL;
1869     }
1870 
1871     /* DNS AAAA Template */
1872     if (!mdAddTmpl(session, yaf_dnsAAAA_spec, YAF_DNSAAAA_FLOW_TID,FALSE,
1873                          "yaf_dns_aaaa", NULL, err))
1874     {
1875         return NULL;
1876     }
1877 
1878     /* DNS CNAME Template */
1879     if (!mdAddTmpl(session, yaf_dnsCNAME_spec, YAF_DNSCN_FLOW_TID,
1880                          FALSE, "yaf_dns_cname", NULL, err))
1881     {
1882         return NULL;
1883     }
1884 
1885     /* DNS MX Template */
1886     if (!mdAddTmpl(session, yaf_dnsMX_spec, YAF_DNSMX_FLOW_TID, FALSE,
1887                          "yaf_dns_mx", NULL, err))
1888     {
1889         return NULL;
1890     }
1891 
1892     /* DNS NS Template */
1893     if (!mdAddTmpl(session, yaf_dnsNS_spec, YAF_DNSNS_FLOW_TID, FALSE,
1894                          "yaf_dns_ns", NULL, err))
1895     {
1896         return NULL;
1897     }
1898 
1899     /* DNS PTR Template */
1900     if (!mdAddTmpl(session, yaf_dnsPTR_spec, YAF_DNSPTR_FLOW_TID, FALSE,
1901                          "yaf_dns_ptr", NULL, err))
1902     {
1903         return NULL;
1904     }
1905 
1906     /* DNS TXT Template */
1907     if (!mdAddTmpl(session, yaf_dnsTXT_spec, YAF_DNSTXT_FLOW_TID, FALSE,
1908                          "yaf_dns_txt", NULL, err))
1909     {
1910         return NULL;
1911     }
1912 
1913     /* DNS SOA Template */
1914     if (!mdAddTmpl(session, yaf_dnsSOA_spec, YAF_DNSSOA_FLOW_TID, FALSE,
1915                          "yaf_dns_soa", NULL, err))
1916     {
1917         return NULL;
1918     }
1919 
1920     /* DNS SRV Template */
1921     if (!mdAddTmpl(session, yaf_dnsSRV_spec, YAF_DNSSRV_FLOW_TID, FALSE,
1922                          "yaf_dns_srv", NULL, err))
1923     {
1924         return NULL;
1925     }
1926 
1927     /* DNS DS Template */
1928     if (!mdAddTmpl(session, yaf_dnsDS_spec, YAF_DNSDS_FLOW_TID, FALSE,
1929                          "yaf_dns_ds", NULL, err))
1930     {
1931         return NULL;
1932     }
1933 
1934     /* DNS RRSig Template */
1935     if (!mdAddTmpl(session, yaf_dnsRRSig_spec, YAF_DNSRRSIG_FLOW_TID,FALSE,
1936                          "yaf_dns_sig", NULL, err))
1937     {
1938         return NULL;
1939     }
1940 
1941     /* DNS NSEC Template */
1942     if (!mdAddTmpl(session, yaf_dnsNSEC_spec, YAF_DNSNSEC_FLOW_TID,FALSE,
1943                          "yaf_dns_nsec", NULL, err))
1944     {
1945         return NULL;
1946     }
1947 
1948     /* DNS Key Template */
1949     if (!mdAddTmpl(session, yaf_dnsKey_spec, YAF_DNSKEY_FLOW_TID, FALSE,
1950                          "yaf_dns_key", NULL, err))
1951     {
1952         return NULL;
1953     }
1954 
1955     /* DNS NSEC3 Template */
1956     if (!mdAddTmpl(session, yaf_dnsNSEC3_spec, YAF_DNSNSEC3_FLOW_TID,
1957                          FALSE, "yaf_dns_nsec3", NULL, err))
1958     {
1959         return NULL;
1960     }
1961 
1962     /* Full CERT SSL Template */
1963     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_FULL_CERT_TID, FALSE, "yaf_ssl_cert_full", NULL, err))
1964     {
1965         return NULL;
1966     }
1967 
1968     /* SSL Template */
1969     if (!mdAddTmpl(session, yaf_ssl_spec, YAF_SSL_FLOW_TID, FALSE, "yaf_ssl", NULL, err))
1970     {
1971         return NULL;
1972     }
1973 
1974     /* SSL Cert Template */
1975     if (!mdAddTmpl(session, yaf_ssl_cert_spec, YAF_SSL_CERT_FLOW_TID, FALSE,
1976                          "yaf_ssl_cert", NULL, err))
1977     {
1978         return NULL;
1979     }
1980 
1981     /* New SSL Template */
1982     if (!mdAddTmpl(session, yaf_newssl_spec, YAF_NEW_SSL_FLOW_TID, FALSE,
1983                    "yaf_new_ssl", NULL, err))
1984     {
1985         return NULL;
1986     }
1987 
1988     /* New SSL CERT Template */
1989     /* SSL Cert Template */
1990     if (!mdAddTmpl(session, yaf_newssl_cert_spec, YAF_NEW_SSL_CERT_TID,
1991                    FALSE, "yaf_new_ssl_cert", NULL, err))
1992     {
1993         return NULL;
1994     }
1995 
1996     /* SSL Sub Template */
1997     if (!mdAddTmpl(session, yaf_subssl_spec,
1998                    YAF_SSL_SUBCERT_TID, FALSE, "yaf_ssl_subcert", NULL, err))
1999     {
2000         return NULL;
2001     }
2002 
2003     /* MySQL Template */
2004     if (!mdAddTmpl(session, yaf_mysql_spec, YAF_MYSQL_FLOW_TID, FALSE,
2005                          "yaf_mysql", NULL, err))
2006     {
2007         return NULL;
2008     }
2009 
2010     /* MYSQL TXT Template */
2011     if (!mdAddTmpl(session, yaf_mysql_txt_spec, YAF_MYSQLTXT_FLOW_TID,
2012                          FALSE, "yaf_mysql_txt", NULL, err))
2013     {
2014         return NULL;
2015     }
2016 
2017     /* DNP 3.0 */
2018     if (!mdAddTmpl(session, yaf_dnp_spec, YAF_DNP3_FLOW_TID, FALSE, "yaf_dnp", NULL, err))
2019     {
2020         return NULL;
2021     }
2022 
2023     if (!mdAddTmpl(session, yaf_dnp_rec_spec, YAF_DNP3_REC_FLOW_TID,
2024                          FALSE, "yaf_dnp_rec", NULL, err))
2025     {
2026         return NULL;
2027     }
2028 
2029     /* Modbus */
2030     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_MODBUS_FLOW_TID,FALSE,
2031                          "yaf_modbus", NULL, err))
2032     {
2033         return NULL;
2034     }
2035 
2036     /* ENIP */
2037     if (!mdAddTmpl(session, yaf_singleBL_spec, YAF_ENIP_FLOW_TID, FALSE,
2038                          "yaf_enip", NULL, err))
2039     {
2040         return NULL;
2041     }
2042 
2043     /** RTP */
2044     if (!mdAddTmpl(session, yaf_rtp_spec, YAF_RTP_FLOW_TID, FALSE, "yaf_rtp", NULL, err))
2045     {
2046         return NULL;
2047     }
2048 
2049     return session;
2050 }
2051 
2052 /**
2053  * mdInitCollectorSession
2054  *
2055  *  =============================================
2056  * create a session (fbSession_t) and attach it to the info model via
2057  * fbSessionAlloc create a collector session and then pass that session
2058  * to the listener to finish building the collector
2059  *
2060  **/
2061 fbSession_t *mdInitCollectorSession(
2062     GError         **err)
2063 {
2064     fbInfoModel_t *model = mdInfoModel();
2065     fbTemplate_t *tmpl = NULL;
2066     fbTemplate_t *o_tmpl = NULL;
2067     fbTemplate_t *d_tmpl = NULL;
2068     fbTemplate_t *ds_tmpl = NULL;
2069     fbSession_t  *session = NULL;
2070 
2071 
2072     /* Allocate the session */
2073     session = fbSessionAlloc(model);
2074 
2075     tmpl = fbTemplateAlloc(model);
2076 
2077     if (!fbTemplateAppendSpecArray(tmpl, md_main_template, 0xffffffff, err)) {
2078         return NULL;
2079     }
2080     if (!fbSessionAddTemplate(session, TRUE, YAF_SILK_FLOW_TID, tmpl, err)) {
2081         return NULL;
2082     }
2083 
2084 
2085     o_tmpl = fbTemplateAlloc(model);
2086 
2087     if (!fbTemplateAppendSpecArray(o_tmpl, yaf_stats_option_spec, 0xffffffff,
2088                                    err))
2089     {
2090         return NULL;
2091     }
2092 
2093     if (!fbSessionAddTemplate(session, TRUE, YAF_STAT_OPTN_FLOW_TID, o_tmpl,
2094                               err))
2095     {
2096         return NULL;
2097     }
2098 
2099     d_tmpl = fbTemplateAlloc(model);
2100 
2101     if (!fbTemplateAppendSpecArray(d_tmpl, yaf_tombstone_option_spec, 0xffffffff,
2102                                    err))
2103     {
2104         return NULL;
2105     }
2106 
2107     if (!fbSessionAddTemplate(session, TRUE, YAF_TOMBSTONE_FLOW_TID, d_tmpl,
2108                               err))
2109     {
2110         return NULL;
2111     }
2112 
2113     ds_tmpl = fbTemplateAlloc(model);
2114 
2115     if (!fbTemplateAppendSpecArray(ds_tmpl, yaf_tombstone_access_spec, 0xffffffff,
2116                                    err))
2117     {
2118         return NULL;
2119     }
2120 
2121     if (!fbSessionAddTemplate(session, TRUE, YAF_TOMBSTONE_ACCESS_TID, ds_tmpl,
2122                               err))
2123     {
2124         return NULL;
2125     }
2126 
2127     /* read dns rr only template */
2128     tmpl = fbTemplateAlloc(model);
2129     if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec, 0xffffffff, err)) {
2130         return NULL;
2131     }
2132     if (!fbSessionAddTemplate(session, TRUE, MD_DNSRR, tmpl, err)) {
2133         return NULL;
2134     }
2135 
2136     /* dns dedup */
2137     tmpl = fbTemplateAlloc(model);
2138     if (!fbTemplateAppendSpecArray(tmpl, md_dns_spec, 0xffffffff, err)) {
2139         return NULL;
2140     }
2141 
2142     if (!fbSessionAddTemplate(session, TRUE, MD_DNS_FULL, tmpl, err)) {
2143         return NULL;
2144     }
2145 
2146 
2147     /* dedup */
2148     tmpl = fbTemplateAlloc(model);
2149     if (!fbTemplateAppendSpecArray(tmpl, md_dedup_spec, 0xffffffff, err)) {
2150         return NULL;
2151     }
2152     if (!fbSessionAddTemplate(session, TRUE, MD_DEDUP_FULL, tmpl, err)) {
2153         return NULL;
2154     }
2155 
2156     /* ssl dedup */
2157     tmpl = fbTemplateAlloc(model);
2158     if (!fbTemplateAppendSpecArray(tmpl, md_ssl_spec, 0, err)) {
2159         return NULL;
2160     }
2161 
2162     if (!fbSessionAddTemplate(session, TRUE, MD_SSL_TID, tmpl, err)) {
2163         return NULL;
2164     }
2165 
2166 
2167     /* ssl cert */
2168     tmpl = fbTemplateAlloc(model);
2169     if (!fbTemplateAppendSpecArray(tmpl, yaf_newssl_cert_spec, 0xffffffff, err)) {
2170         return NULL;
2171     }
2172 
2173     if (!fbSessionAddTemplate(session, TRUE, YAF_NEW_SSL_CERT_TID, tmpl, err)) {
2174         return NULL;
2175     }
2176 
2177     tmpl = fbTemplateAlloc(model);
2178     if (!fbTemplateAppendSpecArray(tmpl, yaf_newssl_cert_spec, 0xffffffff, err)) {
2179         return NULL;
2180     }
2181 
2182     if (!(fbSessionAddTemplate(session, TRUE, SM_INTCERT_FLOW_TID, tmpl, err))) {
2183         return NULL;
2184     }
2185 
2186     tmpl = fbTemplateAlloc(model);
2187     if (!fbTemplateAppendSpecArray(tmpl, yaf_newssl_spec, 0xffffffff, err)) {
2188         return NULL;
2189     }
2190 
2191     if (!(fbSessionAddTemplate(session, TRUE, SM_INTSSL_FLOW_TID, tmpl, err))) {
2192         return NULL;
2193     }
2194 
2195     /** we will want to add a template callback eventually */
2196     fbSessionAddNewTemplateCallback(session, mdTemplateCallback, NULL);
2197 
2198     return session;
2199 }
2200 
2201 
2202 
2203 
2204 
2205 /**
2206  * mdSetExportTemplate
2207  *
2208  * set the export template on the fbuf
2209  */
2210 gboolean mdSetExportTemplate(
2211     fBuf_t          *fbuf,
2212     uint16_t        tid,
2213     GError          **err)
2214 {
2215 
2216     fbSession_t *session = NULL;
2217     fbTemplate_t *tmpl = NULL;
2218     GString             *template_name = g_string_new("");
2219 
2220     if (fBufSetExportTemplate(fbuf, tid, err)) {
2221         g_string_free(template_name, TRUE);
2222         return TRUE;
2223     }
2224 
2225     if (!g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_TMPL)) {
2226         g_string_free(template_name, TRUE);
2227         return FALSE;
2228     }
2229 
2230     g_clear_error(err);
2231     session = fBufGetSession(fbuf);
2232     tmpl = fbTemplateAlloc(mdInfoModel());
2233 
2234     if (tid == YAF_STAT_OPTN_FLOW_TID) {
2235         if (!fbTemplateAppendSpecArray(tmpl, yaf_stats_option_spec,
2236                                        YAF_STAT_OPTN_FLOW_TID, err)) {
2237             g_string_free(template_name, TRUE);
2238             return FALSE;
2239         }
2240         fbTemplateSetOptionsScope(tmpl, 2);
2241     } else if (tid == YAF_TOMBSTONE_FLOW_TID) {
2242         g_string_append_printf(template_name, "tombstone_record"); /* TODO: check name */
2243         if (!fbTemplateAppendSpecArray(tmpl, yaf_tombstone_option_spec,
2244                                        YAF_TOMBSTONE_FLOW_TID, err)) {
2245             return FALSE;
2246         }
2247         fbTemplateSetOptionsScope(tmpl, 2);
2248     } else if (tid == YAF_TOMBSTONE_ACCESS_TID) {
2249         g_string_append_printf(template_name, "tombstone_access_record"); /* TODO: check name */
2250         if (!fbTemplateAppendSpecArray(tmpl, yaf_tombstone_access_spec,
2251                                        YAF_TOMBSTONE_ACCESS_TID, err)) {
2252             return FALSE;
2253         }
2254     } else if ((tid & 0xFFF0) == MD_DNS_OUT) {
2255 #if SM_ENABLE_METADATA_EXPORT
2256         g_string_append_printf(template_name, "md_dns");
2257         if (tid & MD_LAST_SEEN)
2258             g_string_append_printf(template_name, "_%s", MD_LAST_SEEN_NAME);
2259         if (tid & MD_DNS_AREC)
2260             g_string_append_printf(template_name, "_%s", MD_DNS_AREC_NAME);
2261         if (tid & MD_DNS_OREC)
2262             g_string_append_printf(template_name, "_%s", MD_DNS_OREC_NAME);
2263 #endif
2264         if (!fbTemplateAppendSpecArray(tmpl, md_dns_spec,
2265                                        (tid & (~MD_DNS_OUT)), err))
2266         {
2267             g_string_free(template_name, TRUE);
2268             return FALSE;
2269         }
2270     } else if ((tid & 0xF0F1) == MD_DNSRR) {
2271 #if SM_ENABLE_METADATA_EXPORT
2272         g_string_append_printf(template_name, "md_dnsrr");
2273         if (tid & YTF_IP6)
2274             g_string_append_printf(template_name, "_%s", YTF_IP6_NAME);
2275         if (tid & YTF_IP4)
2276             g_string_append_printf(template_name, "_%s", YTF_IP4_NAME);
2277         if (tid & MD_DNSRR_FULL)
2278             g_string_append_printf(template_name, "_%s", MD_DNSRR_FULL_NAME);
2279 #endif
2280         if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec,
2281                                        (tid & (~MD_DNSRR)), err))
2282         {
2283             g_string_free(template_name, TRUE);
2284             return FALSE;
2285         }
2286     } else if ((tid & 0xFFF8) == MD_DEDUP_TID) {
2287 #if SM_ENABLE_METADATA_EXPORT
2288         g_string_append_printf(template_name, "md_dedup");
2289         if (tid & MD_DEDUP_SSL)
2290             g_string_append_printf(template_name, "_%s", MD_DEDUP_SSL_NAME);
2291 #endif
2292         if (!fbTemplateAppendSpecArray(tmpl, md_dedup_spec,
2293                                        (tid & (~MD_DEDUP_TID)), err))
2294         {
2295             g_string_free(template_name, TRUE);
2296             return FALSE;
2297         }
2298     } else if (tid == MD_SSL_TID) {
2299 #if SM_ENABLE_METADATA_EXPORT
2300         g_string_append_printf(template_name, "md_ssl");
2301 #endif
2302         if (!fbTemplateAppendSpecArray(tmpl, md_ssl_spec, tid, err)) {
2303             g_string_free(template_name, TRUE);
2304             return FALSE;
2305         }
2306     } else {
2307 #if SM_ENABLE_METADATA_EXPORT
2308         g_string_append_printf(template_name, "md_main");
2309         if (tid & YTF_TOTAL)
2310             g_string_append_printf(template_name, "_%s", YTF_TOTAL_NAME);
2311         if (tid & YTF_REV)
2312             g_string_append_printf(template_name, "_%s", YTF_REV_NAME);
2313         if (tid & YTF_DELTA)
2314             g_string_append_printf(template_name, "_%s", YTF_DELTA_NAME);
2315         if (tid & YTF_IP6)
2316             g_string_append_printf(template_name, "_%s", YTF_IP6_NAME);
2317         if (tid & YTF_IP4)
2318             g_string_append_printf(template_name, "_%s", YTF_IP4_NAME);
2319         if (tid & YTF_TCP)
2320             g_string_append_printf(template_name, "_%s", YTF_TCP_NAME);
2321         if (tid & YTF_DAGIF)
2322             g_string_append_printf(template_name, "_%s", YTF_DAGIF_NAME);
2323         if (tid & YTF_MPLS)
2324             g_string_append_printf(template_name, "_%s", YTF_MPLS_NAME);
2325         if (tid & YTF_PAD)
2326             g_string_append_printf(template_name, "_%s", YTF_PAD_NAME);
2327         if (tid & YTF_LIST)
2328             g_string_append_printf(template_name, "_%s", YTF_LIST_NAME);
2329 #endif
2330         if (!fbTemplateAppendSpecArray(tmpl, md_main_template,
2331                                        (tid & (~YAF_SILK_FLOW_TID)), err))
2332         {
2333             g_string_free(template_name, TRUE);
2334             return FALSE;
2335         }
2336     }
2337 #if SM_ENABLE_METADATA_EXPORT
2338     if (!fbSessionAddTemplateWithMetadata(session, FALSE, tid, tmpl, template_name->str, NULL, err)) {
2339 #else
2340     if (!fbSessionAddTemplate(session, FALSE, tid, tmpl, err)) {
2341 #endif
2342         g_string_free(template_name, TRUE);
2343         return FALSE;
2344     }
2345 
2346     g_string_free(template_name, TRUE);
2347     return fBufSetExportTemplate(fbuf, tid, err);
2348 }
2349 
2350 
2351 #if HAVE_SPREAD
2352 /**
2353  * mdSetSpreadExportTemplate
2354  *
2355  * set the template on the fbuf and groups
2356  *
2357  */
2358 gboolean mdSetSpreadExportTemplate(
2359     fBuf_t           *fbuf,
2360     fbSpreadParams_t *sp,
2361     uint16_t         tid,
2362     char             **groups,
2363     int              num_groups,
2364     GError           **err)
2365 {
2366     fbSession_t *session = NULL;
2367     fbTemplate_t *tmpl = NULL;
2368 
2369     if (fBufSetExportTemplate(fbuf, tid, err)) {
2370         return TRUE;
2371     }
2372 
2373     if (!g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_TMPL)) {
2374         return FALSE;
2375     }
2376 
2377     g_clear_error(err);
2378 
2379     session = fBufGetSession(fbuf);
2380     tmpl = fbTemplateAlloc(mdInfoModel());
2381 
2382     if (tid == YAF_STAT_OPTN_FLOW_TID) {
2383         if (!fbTemplateAppendSpecArray(tmpl, yaf_stats_option_spec,
2384                                        YAF_STAT_OPTN_FLOW_TID, err)) {
2385             return FALSE;
2386         }
2387         fbTemplateSetOptionsScope(tmpl, 2);
2388     } else if (tid == YAF_TOMBSTONE_FLOW_TID) {
2389         if (!fbTemplateAppendSpecArray(tmpl, yaf_tombstone_option_spec,
2390                                        YAF_TOMBSTONE_FLOW_TID, err)) {
2391             return FALSE;
2392         }
2393         fbTemplateSetOptionsScope(tmpl, 2);
2394     } else if (tid == YAF_TOMBSTONE_ACCESS_TID) {
2395         if (!fbTemplateAppendSpecArray(tmpl, yaf_tombstone_access_spec,
2396                                        YAF_TOMBSTONE_ACCESS_TID, err)) {
2397             return FALSE;
2398         }
2399     } else if ((tid & 0xFFF0) == MD_DNS_OUT) {
2400         if (!fbTemplateAppendSpecArray(tmpl, md_dns_spec,
2401                                        (tid & (~MD_DNS_OUT)), err))
2402         {
2403             return FALSE;
2404         }
2405     } else if ((tid & 0xF0F1) == MD_DNSRR) {
2406         if (!fbTemplateAppendSpecArray(tmpl, md_dns_rr_spec,
2407                                        (tid & (~MD_DNSRR)), err))
2408         {
2409             return FALSE;
2410         }
2411     } else if ((tid & 0xFFF8) == MD_DEDUP_TID) {
2412         if (!fbTemplateAppendSpecArray(tmpl, md_dedup_spec,
2413                                        (tid & (~MD_DEDUP_TID)), err))
2414         {
2415             return FALSE;
2416         }
2417     } else if (tid == MD_SSL_TID) {
2418         if (!fbTemplateAppendSpecArray(tmpl, md_ssl_spec, tid, err)) {
2419             return FALSE;
2420         }
2421     } else {
2422 
2423         if (!fbTemplateAppendSpecArray(tmpl, md_main_template,
2424                                        (tid & (~YAF_SILK_FLOW_TID)), err))
2425         {
2426             return FALSE;
2427         }
2428     }
2429 
2430 
2431     if (!fbSessionAddTemplatesMulticast(session, sp->groups, FALSE, tid,
2432                                        tmpl, err))
2433     {
2434         return FALSE;
2435     }
2436 
2437     fBufSetSpreadExportGroup(fbuf, groups, num_groups, err);
2438 
2439     return fBufSetExportTemplate(fbuf, tid, err);
2440 
2441 }
2442 
2443 #endif
2444 
2445 
2446 
2447 
2448 
2449 /**
2450  * mdOptionsCheck
2451  *
2452  * check to see if the next record on the fbuf is an options record
2453  *
2454  */
2455 gboolean mdOptionsCheck(
2456     fBuf_t         **fbuf,
2457     uint16_t       *tid,
2458     fbTemplate_t   **tmpl,
2459     GError         **err)
2460 {
2461     fbInfoElementSpec_t tname;
2462 
2463     tname.name = "templateName";
2464 
2465     *tmpl = fBufNextCollectionTemplate(*fbuf, tid, err);
2466     if (*tmpl) {
2467         if (fbTemplateGetOptionsScope(*tmpl)) {
2468             /* options message */
2469             if (fbTemplateContainsElementByName(*tmpl, &tname)) {
2470                 /* ignore template metadata records */
2471                 g_set_error(err, MD_ERROR_DOMAIN, MD_ERROR_TMPL,
2472                             "Got a template stats message - ignore");
2473                 g_warning("got a template descritpion options record.");
2474                 *tid = 0;
2475             } else if (fbInfoModelTypeInfoRecord(*tmpl)) {
2476                 /* ignore template metadata records */
2477                 g_set_error(err, MD_ERROR_DOMAIN, MD_ERROR_TMPL,
2478                             "Got a info element type  message - ignore");
2479                 *tid = 0;
2480             }
2481             return TRUE;
2482         }
2483     } else {
2484         if ((g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_EOM)) ||
2485             (g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_NLREAD)) ||
2486             (g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_IPFIX)))
2487         {
2488             *tid = 0;
2489             return TRUE;
2490         } else {
2491             fBufFree(*fbuf);
2492             *fbuf = NULL;
2493             return FALSE;
2494         }
2495     }
2496 
2497     return FALSE;
2498 }
2499 
2500 
2501 gboolean mdIgnoreRecord(
2502     mdContext_t    *ctx,
2503     fBuf_t         *fbuf,
2504     uint16_t       tid,
2505     GError         **err)
2506 {
2507     gboolean       rc;
2508 
2509     if (!fBufSetInternalTemplate(fbuf, tid, err)) {
2510         /* log an error */
2511         return FALSE;
2512     }
2513 
2514     if(tid == YAF_STAT_OPTN_FLOW_TID){
2515         yaf_stats_option_t stats;
2516         size_t         stats_len = sizeof(stats);
2517         rc = fBufNext(fbuf, (uint8_t *)&stats, &stats_len, err);
2518     } else if(tid == YAF_TOMBSTONE_FLOW_TID){
2519         yaf_tombstone_option_t tombstone;
2520         size_t         tombstone_len = sizeof(tombstone);
2521 
2522         memset(&tombstone, 0, tombstone_len);
2523         rc = fBufNext(fbuf, (uint8_t *)&tombstone, &tombstone_len, err);
2524         fbSubTemplateListClear(&(tombstone.accessList));
2525     } else{
2526         /* TODO: raise an error */
2527         rc = FALSE;
2528     }
2529 
2530     if (FALSE == rc) {
2531         /* End of Set. */
2532         g_clear_error(err);
2533     }
2534 
2535     /* set internal template back to SiLK Flow */
2536     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2537     {
2538         return FALSE;
2539     }
2540 
2541     return TRUE;
2542 }
2543 
2544 /**
2545  * mdForwardOptions
2546  *
2547  * forward the options record to the exporters that
2548  * are configured to receive YAF stats
2549  *
2550  */
2551 gboolean mdForwardOptions(
2552     mdContext_t       *ctx,
2553     md_collect_node_t *collector,
2554     GError            **err,
2555     uint16_t          tid)
2556 {
2557     if(tid == YAF_STAT_OPTN_FLOW_TID) {
2558         return mdForwardStats(ctx, collector, err);
2559     }
2560     else if(tid == YAF_TOMBSTONE_FLOW_TID) {
2561         return mdForwardTombstone(ctx, collector, err);
2562     }
2563     else{
2564         /* TODO: print some error? */
2565         return FALSE;
2566     }
2567 }
2568 
2569 /**
2570  * mdForwardTombstone
2571  *
2572  * forward the tombstone record to the exporters that
2573  * are configured to receive YAF stats
2574  *
2575  */
2576 gboolean mdForwardTombstone(
2577     mdContext_t       *ctx,
2578     md_collect_node_t *collector,
2579     GError            **err)
2580 {
2581     fBuf_t         *fbuf = collector->fbuf;
2582     gboolean       rc;
2583     yaf_tombstone_option_t tombstone;
2584     yaf_tombstone_access_t     *accessListPtr;
2585     size_t         tombstone_len = sizeof(tombstone);
2586     md_export_node_t *cnode = NULL;
2587 
2588     if (!fBufSetInternalTemplate(fbuf, YAF_TOMBSTONE_FLOW_TID, err)) {
2589         /* log an error */
2590         return FALSE;
2591     }
2592 
2593     memset(&tombstone, 0, tombstone_len);
2594     rc = fBufNext(fbuf, (uint8_t *)&tombstone, &tombstone_len, err);
2595 
2596     if (FALSE == rc) {
2597         /* End of Set. */
2598         g_clear_error(err);
2599         goto end;
2600     }
2601 
2602     /*  We use no_stats for tombstone as well */
2603     if (ctx->cfg->no_stats) {
2604         goto end;
2605     }
2606 
2607     g_message("Received Tombstone record: exporterId: %d:%d, tombstoneId: %d",
2608             tombstone.exporterConfiguredId, tombstone.exporterUniqueId,
2609             tombstone.tombstoneId);
2610 
2611     accessListPtr = fbSubTemplateListAddNewElements(&(tombstone.accessList), 1);
2612     accessListPtr->exportingProcessId = 2;
2613     accessListPtr->observationTimeSeconds = (int)time(NULL);
2614 
2615     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2616         if (cnode->filter) {
2617             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2618                           cnode->and_filter, ctx->cfg->collector_id);
2619             if (!rc) continue;
2620         }
2621         if (!mdExporterWriteOptions(ctx->cfg, cnode->exp, (uint8_t *)&tombstone,
2622                                     sizeof(yaf_tombstone_option_t),
2623                                     YAF_TOMBSTONE_FLOW_TID, err)){
2624             return FALSE;
2625         }
2626     }
2627 
2628   end:
2629     /* free subTemplateList */
2630     fbSubTemplateListClear(&(tombstone.accessList));
2631 
2632     /* set internal template back to SiLK Flow */
2633     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2634     {
2635         return FALSE;
2636     }
2637 
2638     return TRUE;
2639 }
2640 
2641 /**
2642  * mdForwardStats
2643  *
2644  * forward the option stats record to the exporters that
2645  * are configured to receive YAF stats
2646  *
2647  */
2648 gboolean mdForwardStats(
2649     mdContext_t       *ctx,
2650     md_collect_node_t *collector,
2651     GError            **err)
2652 {
2653     fBuf_t         *fbuf = collector->fbuf;
2654     gboolean       rc;
2655     yaf_stats_option_t stats;
2656     size_t         stats_len = sizeof(stats);
2657     md_export_node_t *cnode = NULL;
2658     char           *colname = mdCollectorGetName(collector);
2659 
2660     ctx->stats->recvd_stats++;
2661     collector->stats->recvd_stats++;
2662 
2663     if (!fBufSetInternalTemplate(fbuf, YAF_STAT_OPTN_FLOW_TID, err)) {
2664         /* log an error */
2665         return FALSE;
2666     }
2667 
2668     rc = fBufNext(fbuf, (uint8_t *)&stats, &stats_len, err);
2669 
2670     if (FALSE == rc) {
2671         /* End of Set. */
2672         g_clear_error(err);
2673         goto end;
2674     }
2675 
2676     if (ctx->cfg->no_stats) {
2677         goto end;
2678     }
2679 
2680     mdLogStats(&stats, colname);
2681 
2682     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2683         if (cnode->filter) {
2684             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2685                           cnode->and_filter, ctx->cfg->collector_id);
2686             if (!rc) continue;
2687         }
2688         if (!mdExporterWriteOptions(ctx->cfg, cnode->exp, (uint8_t *)&stats,
2689                                     sizeof(yaf_stats_option_t),
2690                                     YAF_STAT_OPTN_FLOW_TID, err)){
2691             return FALSE;
2692         }
2693     }
2694 
2695   end:
2696     /* set internal template back to SiLK Flow */
2697     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2698     {
2699         return FALSE;
2700     }
2701 
2702     return TRUE;
2703 }
2704 
2705 /**
2706  * mdSendTombstoneRecord
2707  *
2708  * Send a tombstone record out to all exporters configured with stats on
2709  *
2710  */
2711 gboolean mdSendTombstoneRecord(
2712     mdContext_t     *ctx,
2713     GError          **err)
2714 {
2715     yaf_tombstone_option_t rec;
2716     gboolean            rc;
2717     md_export_node_t    *cnode = NULL;
2718     static uint32_t     tombstoneId = 0;
2719     yaf_tombstone_access_t *accessListPtr;
2720     fbTemplate_t        *tombstoneAccessTemplate;
2721 
2722     if (ctx->cfg->no_stats) {
2723         return TRUE;
2724     }
2725 
2726     memset(&rec, 0, sizeof(rec));
2727 
2728     rec.tombstoneId = tombstoneId++;
2729     rec.exporterConfiguredId = ctx->cfg->tombstone_configured_id;
2730     rec.exporterUniqueId = ctx->cfg->tombstone_unique_id;
2731 
2732     /* tombstoneAccessTemplate = fbSessionGetTemplate() */
2733     tombstoneAccessTemplate = fbTemplateAlloc(mdInfoModel());
2734     if (!fbTemplateAppendSpecArray(tombstoneAccessTemplate,
2735                                    yaf_tombstone_access_spec,
2736                                    0xffffffff, err)) {
2737         return FALSE;
2738     }
2739 
2740     accessListPtr = (yaf_tombstone_access_t *)fbSubTemplateListInit(
2741                                     &(rec.accessList), 0,
2742                                     YAF_TOMBSTONE_ACCESS_TID,
2743                                     tombstoneAccessTemplate, 1);
2744 
2745     accessListPtr->exportingProcessId = 2;
2746     accessListPtr->observationTimeSeconds = (int)time(NULL);
2747 
2748     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2749         if (cnode->filter) {
2750             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2751                           cnode->and_filter, ctx->cfg->collector_id);
2752             if (!rc) continue;
2753         }
2754         if (!mdExporterWriteOptions(ctx->cfg, cnode->exp, (uint8_t *)&rec,
2755                                     sizeof(yaf_tombstone_option_t),
2756                                     YAF_TOMBSTONE_FLOW_TID, err)){
2757             fbSubTemplateListClear(&(rec.accessList));
2758             return FALSE;
2759         }
2760     }
2761 
2762     g_message("Sent Tombstone record: exporterId: %d:%d, tombstoneId: %d",
2763             rec.exporterConfiguredId, rec.exporterUniqueId,
2764             rec.tombstoneId);
2765     fbSubTemplateListClear(&(rec.accessList));
2766 
2767     return TRUE;
2768 }
2769 
2770 /**
2771  * mdForwardDNSDedup
2772  *
2773  */
2774 gboolean mdForwardDNSDedup(
2775     mdContext_t *ctx,
2776     fBuf_t      *fbuf,
2777     GError      **err)
2778 {
2779 
2780     gboolean       rc;
2781     md_dns_t       dns;
2782     size_t         dns_len = sizeof(dns);
2783     md_export_node_t *cnode = NULL;
2784     uint16_t       tid;
2785 
2786     if (!fBufSetInternalTemplate(fbuf, MD_DNS_FULL, err)) {
2787         return FALSE;
2788     }
2789 
2790     rc = fBufNext(fbuf, (uint8_t *)&dns, &dns_len, err);
2791 
2792     if (FALSE == rc) {
2793         /* End of Set. */
2794         g_clear_error(err);
2795         goto end;
2796     }
2797 
2798 
2799     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
2800         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
2801         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
2802     }
2803 
2804     fBufGetCollectionTemplate(fbuf, &tid);
2805 
2806     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2807         if (cnode->filter) {
2808             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2809                           cnode->and_filter, ctx->cfg->collector_id);
2810             if (!rc) continue;
2811         }
2812         if (!mdExporterWriteRecord(ctx->cfg, cnode->exp, tid,
2813                                    (uint8_t *)&dns, dns_len, err)) {
2814             return FALSE;
2815         }
2816     }
2817 
2818   end:
2819     /* set internal template back to SiLK Flow */
2820     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2821     {
2822         return FALSE;
2823     }
2824 
2825     return TRUE;
2826 }
2827 
2828 
2829 
2830 /**
2831  * mdForwardDNSRR
2832  *
2833  * forward the dns rr-only record to the exporters
2834  * that are configured to receive them
2835  *
2836  */
2837 gboolean mdForwardDNSRR(
2838     mdContext_t *ctx,
2839     fBuf_t      *fbuf,
2840     GError      **err)
2841 {
2842 
2843     gboolean       rc;
2844     md_dns_rr_t      dnsrr;
2845     size_t         rr_len = sizeof(dnsrr);
2846     md_export_node_t *cnode = NULL;
2847     uint16_t       tid;
2848 
2849     if (!fBufSetInternalTemplate(fbuf, MD_DNSRR, err)) {
2850         return FALSE;
2851     }
2852 
2853     rc = fBufNext(fbuf, (uint8_t *)&dnsrr, &rr_len, err);
2854 
2855     if (FALSE == rc) {
2856         /* End of Set. */
2857         g_clear_error(err);
2858         goto end;
2859     }
2860 
2861     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
2862         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
2863         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
2864     }
2865 
2866     fBufGetCollectionTemplate(fbuf, &tid);
2867 
2868     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2869         if (cnode->filter) {
2870             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2871                           cnode->and_filter, ctx->cfg->collector_id);
2872             if (!rc) {
2873                 continue;
2874             }
2875         }
2876         if (!mdExporterWriteDNSRRRecord(ctx->cfg, cnode->exp, tid,
2877                                         (uint8_t *)&dnsrr, rr_len, err))
2878         {
2879             return FALSE;
2880         }
2881     }
2882 
2883   end:
2884 
2885     /* set internal template back to SiLK Flow */
2886     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2887     {
2888         return FALSE;
2889     }
2890 
2891     return TRUE;
2892 }
2893 /**
2894  * mdForwardDedupCustom
2895  *
2896  *
2897  */
2898 gboolean mdForwardDedupCustom(
2899     mdContext_t      *ctx,
2900     mdTmplContext_t  *tctx,
2901     fBuf_t           *fbuf,
2902     GError           **err)
2903 {
2904 
2905     gboolean       rc;
2906     md_dedup_t     dedup;
2907     md_dedup_old_t odedup;
2908     size_t         dedup_len = sizeof(dedup);
2909     size_t         odedup_len = sizeof(odedup);
2910     md_export_node_t *cnode = NULL;
2911     uint16_t       tid;
2912 
2913 
2914     if (!fBufSetInternalTemplate(fbuf, tctx->tid, err)) {
2915         return FALSE;
2916     }
2917 
2918     if (tctx->num_elem < 8) {
2919         rc = fBufNext(fbuf, (uint8_t *)&odedup, &odedup_len, err);
2920         if (FALSE == rc) {
2921             /* End of Set. */
2922             g_clear_error(err);
2923             goto end;
2924         }
2925         dedup.monitoringIntervalStartMilliSeconds = odedup.fseen;
2926         dedup.monitoringIntervalEndMilliSeconds = odedup.lseen;
2927         dedup.flowStartMilliseconds = 0;
2928         dedup.observedDataTotalCount = odedup.count;
2929         memcpy(dedup.sourceIPv6Address, odedup.sip6, 16);
2930         dedup.sourceIPv4Address = odedup.sip;
2931         dedup.yafFlowKeyHash = odedup.hash;
2932         dedup.observedData.buf = odedup.data.buf;
2933         dedup.observedData.len = odedup.data.len;
2934         dedup.mapname.buf = NULL;
2935         dedup.mapname.len = 0;
2936     } else {
2937         rc = fBufNext(fbuf, (uint8_t *)&dedup, &dedup_len, err);
2938 
2939         if (FALSE == rc) {
2940             /* End of Set. */
2941             g_clear_error(err);
2942             goto end;
2943         }
2944     }
2945 
2946     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
2947         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
2948         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
2949     }
2950 
2951     fBufGetCollectionTemplate(fbuf, &tid);
2952 
2953     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
2954         if (cnode->filter) {
2955             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
2956                           cnode->and_filter, ctx->cfg->collector_id);
2957             if (!rc) {
2958                 continue;
2959             }
2960         }
2961         if (cnode->dedup) {
2962             if (!md_dedup_write_dedup(ctx, cnode, &dedup, tctx->ie, err)) {
2963                 return FALSE;
2964             }
2965         } else {
2966             if (!mdExporterWriteDedupRecord(ctx->cfg, cnode, NULL,
2967                                             &dedup, "dedup", 0, tid, err))
2968             {
2969                 return FALSE;
2970             }
2971         }
2972     }
2973 
2974   end:
2975     /* set internal template back to SiLK Flow */
2976     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
2977     {
2978         return FALSE;
2979     }
2980 
2981     return TRUE;
2982 }
2983 
2984 
2985 
2986 
2987 /**
2988  * mdForwardDedup
2989  *
2990  */
2991 gboolean mdForwardDedup(
2992     mdContext_t *ctx,
2993     fBuf_t      *fbuf,
2994     GError      **err)
2995 {
2996     gboolean       rc;
2997     md_dedup_t     dedup;
2998     size_t         dedup_len = sizeof(dedup);
2999     md_export_node_t *cnode = NULL;
3000     uint16_t       tid;
3001 
3002     if (!fBufSetInternalTemplate(fbuf, MD_DEDUP_FULL, err)) {
3003         return FALSE;
3004     }
3005 
3006     rc = fBufNext(fbuf, (uint8_t *)&dedup, &dedup_len, err);
3007 
3008     if (FALSE == rc) {
3009         /* End of Set. */
3010         g_clear_error(err);
3011         goto end;
3012     }
3013 
3014     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
3015         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
3016         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
3017     }
3018 
3019     fBufGetCollectionTemplate(fbuf, &tid);
3020 
3021     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
3022         if (cnode->filter) {
3023             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
3024                           cnode->and_filter, ctx->cfg->collector_id);
3025             if (!rc) {
3026                 continue;
3027             }
3028         }
3029         if (cnode->dedup) {
3030             /* ssl is the only way that should make it here */
3031             if (!md_dedup_write_dedup(ctx, cnode, &dedup, 244,
3032                                       err)) {
3033                 return FALSE;
3034             }
3035         } else {
3036             if (!mdExporterWriteDedupRecord(ctx->cfg, cnode, NULL,
3037                                             &dedup, "dedup", 0, tid, err))
3038             {
3039                 return FALSE;
3040             }
3041         }
3042     }
3043 
3044   end:
3045     /* set internal template back to SiLK Flow */
3046     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
3047     {
3048         return FALSE;
3049     }
3050 
3051     return TRUE;
3052 }
3053 
3054 /**
3055  * mdForwardSSLDedup
3056  *
3057  */
3058 gboolean mdForwardSSLDedup(
3059     mdContext_t *ctx,
3060     fBuf_t      *fbuf,
3061     GError      **err)
3062 {
3063     gboolean       rc;
3064     md_ssl_t       ssl;
3065     size_t         ssl_len = sizeof(ssl);
3066     md_export_node_t *cnode = NULL;
3067 
3068     if (!fBufSetInternalTemplate(fbuf, MD_SSL_TID, err)) {
3069         return FALSE;
3070     }
3071 
3072     rc = fBufNext(fbuf, (uint8_t *)&ssl, &ssl_len, err);
3073 
3074     if (FALSE == rc) {
3075         /* End of Set. */
3076         g_clear_error(err);
3077         goto end;
3078     }
3079 
3080     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
3081         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
3082         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
3083     }
3084 
3085     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
3086         if (cnode->filter) {
3087             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
3088                           cnode->and_filter, ctx->cfg->collector_id);
3089             if (!rc) {
3090                 continue;
3091             }
3092         }
3093         if (!mdExporterWriteSSLDedupRecord(ctx->cfg, cnode->exp, MD_SSL_TID,
3094                                            (uint8_t *)&ssl, ssl_len, err))
3095         {
3096             return FALSE;
3097         }
3098     }
3099 
3100   end:
3101 
3102     /* set internal template back to SiLK Flow */
3103     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
3104     {
3105         return FALSE;
3106     }
3107 
3108     return TRUE;
3109 }
3110 
3111 /**
3112  * mdForwardSSLDedup
3113  *
3114  */
3115 gboolean mdForwardSSLCert(
3116     mdContext_t *ctx,
3117     fBuf_t      *fbuf,
3118     GError      **err)
3119 {
3120     gboolean       rc;
3121     yaf_newssl_cert_t cert;
3122     size_t         cert_len = sizeof(cert);
3123     md_export_node_t *cnode = NULL;
3124 
3125     if (!fBufSetInternalTemplate(fbuf, YAF_NEW_SSL_CERT_TID, err)) {
3126         return FALSE;
3127     }
3128 
3129     memset(&cert, 0, cert_len);
3130 
3131     rc = fBufNext(fbuf, (uint8_t *)&cert, &cert_len, err);
3132 
3133     if (FALSE == rc) {
3134         /* End of Set. */
3135         g_clear_error(err);
3136         goto end;
3137     }
3138 
3139     if (fBufGetExportTime(fbuf) > (ctx->cfg->ctime/1000)) {
3140         /* fbufgetexporttime returns time in seconds -  need ms */
3141         ctx->cfg->ctime = (uint64_t)fBufGetExportTime(fbuf);
3142         ctx->cfg->ctime = ctx->cfg->ctime * 1000;
3143     }
3144 
3145     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
3146         if (cnode->filter) {
3147             rc = mdFilter(cnode->filter, NULL, ctx->cfg->current_domain,
3148                           cnode->and_filter, ctx->cfg->collector_id);
3149             if (!rc) {
3150                 continue;
3151             }
3152         }
3153 
3154         md_ssl_export_ssl_cert(ctx, cnode, &cert, err);
3155     }
3156 
3157     mdCleanUpSSLCert(&cert);
3158 
3159   end:
3160     /* set internal template back to SiLK Flow */
3161     if (!fBufSetInternalTemplate(fbuf, YAF_SILK_FLOW_TID, err))
3162     {
3163         return FALSE;
3164     }
3165 
3166     return TRUE;
3167 }
3168 
3169 
3170 
3171 /**
3172  * mdConvertToSiLK
3173  *
3174  * convert a normal YAF record to SiLK record
3175  * put TCP info back in the normal IPFIX record
3176  *
3177  * @return the template id of the record
3178  */
3179 uint16_t mdConvertToSiLK(
3180     md_main_template_t        *rec,
3181     uint16_t           tid)
3182 {
3183     uint16_t     wtid = YAF_SILK_FLOW_TID;
3184 
3185     if (rec->reversePacketTotalCount || rec->reversePacketDeltaCount) {
3186         wtid |= YTF_REV;
3187     }
3188     if (rec->sourceIPv4Address == 0) {
3189         wtid |= YTF_IP6;
3190     } else {
3191         wtid |= YTF_IP4;
3192     }
3193 
3194     if (rec->protocolIdentifier == 6) {
3195         wtid |= YTF_TCP;
3196     }
3197 
3198     if (rec->ingressInterface || rec->egressInterface) {
3199         wtid |= YTF_DAGIF;
3200     }
3201 
3202     if (tid & YTF_MPLS) {
3203         wtid |= YTF_MPLS;
3204     }
3205 
3206     if (rec->packetDeltaCount) {
3207         wtid |= YTF_DELTA;
3208     } else {
3209         wtid |= YTF_TOTAL;
3210     }
3211 
3212 
3213     return wtid;
3214 }
3215 
3216 
3217 /**
3218  * mdDecodeAndClear
3219  *
3220  * Do the STML decode and clean up
3221  *
3222  */
3223 void mdDecodeAndClear(
3224     mdContext_t    *ctx,
3225     md_main_template_t     *rec)
3226 {
3227 
3228     mdFullFlow_t *md_flow;
3229 
3230     md_flow = g_slice_new0(mdFullFlow_t);
3231 
3232     md_flow->rec = rec;
3233 
3234     mdMainDecode(ctx, md_flow);
3235 
3236     mdCleanUP(md_flow);
3237 
3238     fbSubTemplateMultiListClear(&(rec->subTemplateMultiList));
3239 
3240     g_slice_free(mdFullFlow_t, md_flow);
3241 
3242 }
3243 
3244 /**
3245  * mdForwardFlow
3246  *
3247  * Forward a normal flow record to the exporters
3248  * that are configured to receive it
3249  *
3250  */
3251 gboolean mdForwardFlow(
3252     mdContext_t   *ctx,
3253     md_main_template_t    *rec,
3254     uint16_t       tid,
3255     GError         **err)
3256 {
3257     gboolean         rc;
3258     int              wf = 0;
3259     mdFullFlow_t     *md_flow;
3260     md_export_node_t *cnode = NULL;
3261 
3262     md_flow = g_slice_new0(mdFullFlow_t);
3263 
3264     md_flow->rec = rec;
3265 
3266     md_flow->rec->yafFlowKeyHash = md_util_flow_key_hash(rec);
3267 
3268     mdMainDecode(ctx, md_flow);
3269 
3270     md_flow->tid = tid;
3271 
3272     md_flow->rec->observationDomainId = ctx->cfg->current_domain;
3273 
3274     /* copy collector name */
3275     md_flow->collector_name = ctx->cfg->collector_name;
3276     md_flow->collector_id = ctx->cfg->collector_id;
3277     for (cnode = ctx->cfg->flowexit; cnode; cnode = cnode->next) {
3278 
3279         rc = TRUE;
3280         if (cnode->filter) {
3281             rc = mdFilter(cnode->filter, rec,
3282                           ctx->cfg->current_domain, cnode->and_filter,
3283                           ctx->cfg->collector_id);
3284         }
3285 
3286         if (rc) {
3287             if (cnode->dns_dedup && (md_flow->app_tid == YAF_DNS_FLOW_TID)) {
3288                 md_add_dns_node(ctx, cnode, md_flow);
3289             }
3290             if (cnode->ssl_dedup && ((md_flow->app_tid == SM_INTSSL_FLOW_TID)
3291                                      || md_flow->fullcert))
3292             {
3293                 md_ssl_add_node(ctx, cnode, md_flow);
3294             }
3295 
3296             if (cnode->dedup) {
3297                 if ((md_flow->app_tid == 0) && !md_flow->dhcpfp &&
3298                     !md_flow->p0f)
3299                 {
3300                     /* continue; */
3301                 } else {
3302                     md_dedup_lookup_node(ctx, cnode, md_flow, err);
3303                 }
3304                 /* continue; */
3305             }
3306 
3307             wf = mdExporterWriteFlow(ctx->cfg, cnode->exp, md_flow, err);
3308             if (wf < 0) {
3309                 rc = FALSE;
3310                 goto done;
3311             }
3312         }
3313 
3314         if (cnode->dns_dedup || cnode->dedup) {
3315             /* only flush queue every 50 flows */
3316             if ((ctx->stats->recvd_flows % 50) == 0) {
3317                 if (cnode->dns_dedup) {
3318                     if (!md_dns_flush_queue(cnode, ctx->cfg, err)) {
3319                         rc = FALSE;
3320                         goto done;
3321                     }
3322                 }
3323                 if (cnode->dedup) {
3324                     if (!md_dedup_flush_queue(cnode, ctx->cfg, err)) {
3325                         rc = FALSE;
3326                         goto done;
3327                     }
3328                 }
3329             }
3330         }
3331     }
3332 
3333     rc = TRUE;
3334 
3335   done:
3336     mdCleanUP(md_flow);
3337 
3338     fbSubTemplateMultiListClear(&(rec->subTemplateMultiList));
3339 
3340     g_slice_free(mdFullFlow_t, md_flow);
3341 
3342     return rc;
3343 
3344 }
3345 
3346 /**
3347  * mdMainDecode
3348  *
3349  * loop through the STML and store the pointers
3350  * to specific records in the mdFullFlow for quick
3351  * retrieval later
3352  *
3353  */
3354 void mdMainDecode(
3355     mdContext_t   *ctx,
3356     mdFullFlow_t  *md_flow)
3357 {
3358 
3359     fbSubTemplateMultiListEntry_t *stml = NULL;
3360 
3361     if (md_flow->rec->packetTotalCount == 0) {
3362         md_flow->rec->packetTotalCount = md_flow->rec->packetDeltaCount;
3363         md_flow->rec->reversePacketTotalCount = md_flow->rec->reversePacketDeltaCount;
3364     }
3365     if (md_flow->rec->octetTotalCount == 0) {
3366         md_flow->rec->octetTotalCount = md_flow->rec->octetDeltaCount;
3367         md_flow->rec->reverseOctetTotalCount = md_flow->rec->reverseOctetDeltaCount;
3368     }
3369 
3370     while ((stml =
3371             fbSubTemplateMultiListGetNextEntry(&(md_flow->rec->subTemplateMultiList), stml)))
3372     {
3373         switch ((stml->tmplID & YTF_BIF)) {
3374           case YAF_ENTROPY_FLOW_TID:
3375             md_flow->entropy =
3376                 (yaf_entropy_t *)FBSTMLNEXT(stml, md_flow->entropy);
3377             break;
3378           case YAF_TCP_FLOW_TID:
3379             {
3380                 yaf_tcp_t *tcp = NULL;
3381                 tcp = (yaf_tcp_t *)FBSTMLNEXT(stml, tcp);
3382                 md_flow->rec->tcpSequenceNumber = tcp->tcpSequenceNumber;
3383                 md_flow->rec->initialTCPFlags = tcp->initialTCPFlags;
3384                 md_flow->rec->unionTCPFlags = tcp->unionTCPFlags;
3385                 if ((stml->tmplID & YTF_REV)) {
3386                     md_flow->rec->reverseTcpSequenceNumber = tcp->reverseTcpSequenceNumber;
3387                     md_flow->rec->reverseInitialTCPFlags = tcp->reverseInitialTCPFlags;
3388                     md_flow->rec->reverseUnionTCPFlags = tcp->reverseUnionTCPFlags;
3389                 }
3390                 break;
3391             }
3392           case YAF_MAC_FLOW_TID:
3393             md_flow->mac = (yaf_mac_t *)FBSTMLNEXT(stml, md_flow->mac);
3394             break;
3395           case YAF_PAYLOAD_FLOW_TID:
3396             {
3397                 md_flow->pay = (yaf_payload_t *)FBSTMLNEXT(stml,
3398                                                              md_flow->pay);
3399             }
3400             break;
3401           case YAF_P0F_FLOW_TID:
3402             {
3403                 md_flow->p0f = (yaf_p0f_t *)FBSTMLNEXT(stml, md_flow->p0f);
3404             }
3405             break;
3406           case YAF_FPEXPORT_FLOW_TID:
3407             {
3408                 md_flow->fp =(yaf_fpexport_t *)FBSTMLNEXT(stml, md_flow->fp);
3409             }
3410             break;
3411           case YAF_MPTCP_FLOW_TID:
3412             {
3413                 md_flow->mptcp = (yaf_mptcp_t *)FBSTMLNEXT(stml, md_flow->mptcp);
3414             }
3415             break;
3416           case YAF_HTTP_FLOW_TID:
3417           case YAF_FTP_FLOW_TID:
3418           case YAF_IMAP_FLOW_TID:
3419           case YAF_SIP_FLOW_TID:
3420           case YAF_SMTP_FLOW_TID:
3421           case YAF_SSH_FLOW_TID:
3422           case YAF_NNTP_FLOW_TID:
3423           case YAF_RTSP_FLOW_TID:
3424             md_flow->app = (void *)FBSTMLNEXT(stml, md_flow->app);
3425             md_flow->app_tid = stml->tmplID;
3426             md_flow->app_elements = fbTemplateCountElements(stml->tmpl);
3427             break;
3428           case YAF_POP3_FLOW_TID:
3429           case YAF_IRC_FLOW_TID:
3430           case YAF_TFTP_FLOW_TID:
3431           case YAF_SLP_FLOW_TID:
3432           case YAF_SSL_FLOW_TID:
3433           case YAF_NEW_SSL_FLOW_TID:
3434           case SM_INTSSL_FLOW_TID:
3435           case YAF_MYSQL_FLOW_TID:
3436           case YAF_DNP3_FLOW_TID:
3437           case YAF_MODBUS_FLOW_TID:
3438           case YAF_ENIP_FLOW_TID:
3439           case YAF_RTP_FLOW_TID:
3440             md_flow->app = (void *)FBSTMLNEXT(stml, md_flow->app);
3441             md_flow->app_tid = stml->tmplID;
3442             md_flow->cert = (fbSubTemplateMultiListEntry_t *)stml;
3443             break;
3444           case YAF_SSL_CERT_FLOW_TID:
3445             md_flow->cert = (fbSubTemplateMultiListEntry_t *)stml;
3446             break;
3447           case YAF_DNS_FLOW_TID:
3448             {
3449                 yaf_dns_t *dnsflow = NULL;
3450                 yaf_dnsQR_t *dnsqrflow = NULL;
3451                 md_flow->app = (void *)FBSTMLNEXT(stml, md_flow->app);
3452                 md_flow->app_tid = stml->tmplID;
3453                 dnsflow = (yaf_dns_t *)md_flow->app;
3454                 dnsqrflow = FBSTLNEXT(&(dnsflow->dnsQRList), dnsqrflow);
3455                 if (dnsqrflow) {
3456                     if (dnsqrflow->dnsQueryResponse || dnsqrflow->dnsNXDomain) {
3457                         /* if the first one is a response & it's UDP_FORCE,
3458                            reversify flow key hash */
3459                         if (md_flow->rec->flowEndReason == UDP_FORCE) {
3460                             md_flow->rec->yafFlowKeyHash = md_util_rev_flow_key_hash(md_flow->rec);
3461                         }
3462                     }
3463                     ctx->stats->dns++;
3464                 }
3465                 if (md_flow->rec->flowEndReason == UDP_FORCE) {
3466                     ctx->stats->uniflows++;
3467                 }
3468             }
3469             break;
3470           case YAF_DHCP_FLOW_TID:
3471           case YAF_DHCP_OP_TID:
3472             md_flow->dhcpfp = NULL;
3473             /*md_flow->dhcpfp = (yfDHCP_FP_Flow_t *)FBSTMLNEXT(stml, md_flow->dhcpfp);*/
3474             md_flow->dhcpfp = (fbSubTemplateMultiListEntry_t *)stml;
3475             md_flow->app_tid = stml->tmplID;
3476             break;
3477           case YAF_STATS_FLOW_TID:
3478             md_flow->stats = NULL;
3479             md_flow->stats = (yaf_flow_stats_t *)FBSTMLNEXT(stml,
3480                                                                md_flow->stats);
3481             break;
3482           case YAF_FULL_CERT_TID:
3483             {
3484                 int i = 0;
3485                 fbVarfield_t *ct = NULL;
3486 
3487                 if (!sm_sub_ssl_tmpl) {
3488                     fbInfoModel_t *model = mdInfoModel();
3489                     sm_sub_ssl_tmpl = fbTemplateAlloc(model);
3490                     if (!fbTemplateAppendSpecArray(sm_sub_ssl_tmpl,
3491                                                    yaf_subssl_spec, 0xffffffff, &(ctx->err))) {
3492                         g_warning("error creating template for ssl cert decode %s", ctx->err->message);
3493                         break;
3494                     }
3495                 }
3496 
3497                 md_flow->fullcert = NULL;
3498                 md_flow->fullcert = (yfSSLFullCert_t *)FBSTMLNEXT(stml, md_flow->fullcert);
3499                 md_flow->sslcerts = g_new0(yaf_newssl_cert_t*,
3500                                            (md_flow->fullcert->cert.numElements+1));
3501                 if (md_flow->app_tid == 0) {
3502                     md_flow->app_tid = stml->tmplID;
3503                 }
3504                 while ((ct = (fbVarfield_t *)fbBasicListGetNextPtr(&(md_flow->fullcert->cert), ct))) {
3505                     md_flow->sslcerts[i] = md_ssl_cert_decode(ct->buf, ct->len, sm_sub_ssl_tmpl);
3506                     i++;
3507                 }
3508                 break;
3509             }
3510           default:
3511             g_debug("Received Unknown Template ID %02x in STML", stml->tmplID);
3512             break;
3513         }
3514     }
3515 }
3516 
3517 
3518 /**
3519  * mdCleanUP
3520  *
3521  * clean up after the messy dynamic lists...
3522  *
3523  */
3524 void mdCleanUP(
3525     mdFullFlow_t  *md_flow)
3526 {
3527     fbBasicList_t *bl = NULL;
3528     int           loop;
3529 
3530     switch (md_flow->app_tid & YTF_BIF) {
3531       case YAF_HTTP_FLOW_TID:
3532       case YAF_IMAP_FLOW_TID:
3533       case YAF_SSH_FLOW_TID:
3534       case YAF_RTSP_FLOW_TID:
3535       case YAF_SMTP_FLOW_TID:
3536       case YAF_SIP_FLOW_TID:
3537       case YAF_FTP_FLOW_TID:
3538       case YAF_NNTP_FLOW_TID:
3539         bl = (fbBasicList_t *)md_flow->app;
3540         for (loop = 0; loop < md_flow->app_elements; loop++) {
3541             fbBasicListClear(bl);
3542             bl++;
3543         }
3544         break;
3545       case YAF_POP3_FLOW_TID:
3546         {
3547             yfPOP3Flow_t *rec = (yfPOP3Flow_t *)md_flow->app;
3548             fbBasicListClear(&(rec->pop3msg));
3549             break;
3550         }
3551       case YAF_MODBUS_FLOW_TID:
3552         {
3553             yfModbusFlow_t *rec = (yfModbusFlow_t *)md_flow->app;
3554             fbBasicListClear(&(rec->mbmsg));
3555             break;
3556         }
3557       case YAF_ENIP_FLOW_TID:
3558         {
3559             yfEnIPFlow_t *rec = (yfEnIPFlow_t *)md_flow->app;
3560             fbBasicListClear(&(rec->enipmsg));
3561             break;
3562         }
3563       case YAF_IRC_FLOW_TID:
3564         {
3565             yfIRCFlow_t *rec = (yfIRCFlow_t *)md_flow->app;
3566             fbBasicListClear(&(rec->ircMsg));
3567             break;
3568         }
3569       case YAF_SLP_FLOW_TID:
3570         {
3571             yaf_slp_t *rec = (yaf_slp_t *)md_flow->app;
3572             fbBasicListClear(&(rec->slpString));
3573             break;
3574         }
3575       case YAF_SSL_FLOW_TID:
3576         {
3577             yaf_ssl_t *rec = (yaf_ssl_t *)md_flow->app;
3578             fbBasicListClear(&(rec->sslCipherList));
3579             break;
3580         }
3581       case SM_INTSSL_FLOW_TID:
3582         {
3583             yaf_newssl_t *rec = (yaf_newssl_t *)md_flow->app;
3584             yaf_newssl_cert_t *cert = NULL;
3585             while ((cert = fbSubTemplateListGetNextPtr(&(rec->sslCertList),
3586                                                        cert)))
3587             {
3588                 fbSubTemplateListClear(&(cert->issuer));
3589                 fbSubTemplateListClear(&(cert->subject));
3590                 fbSubTemplateListClear(&(cert->extension));
3591             }
3592             fbSubTemplateListClear(&(rec->sslCertList));
3593             fbBasicListClear(&(rec->sslCipherList));
3594         }
3595         break;
3596       case YAF_MYSQL_FLOW_TID:
3597         {
3598             yaf_mysql_t *rec = (yaf_mysql_t *)md_flow->app;
3599             fbSubTemplateListClear(&(rec->mysqlList));
3600             break;
3601         }
3602       case YAF_DNS_FLOW_TID:
3603         {
3604             yaf_dns_t *rec = (yaf_dns_t *)md_flow->app;
3605             yaf_dnsQR_t *dns = NULL;
3606             while ((dns = fbSubTemplateListGetNextPtr(&(rec->dnsQRList), dns))) {
3607                 fbSubTemplateListClear(&(dns->dnsRRList));
3608             }
3609 
3610             fbSubTemplateListClear(&(rec->dnsQRList));
3611             break;
3612         }
3613       case YAF_DHCP_OP_TID:
3614         {
3615             yaf_dhcp_options_t *dhcp = NULL;
3616             dhcp = (yaf_dhcp_options_t*)FBSTMLNEXT(md_flow->dhcpfp, dhcp);
3617             fbBasicListClear(&(dhcp->options));
3618             if (md_flow->app_tid & YTF_REV) {
3619                 fbBasicListClear(&(dhcp->revOptions));
3620             }
3621             break;
3622         }
3623       default:
3624         break;
3625     }
3626 
3627     if (md_flow->fullcert) {
3628         yaf_newssl_cert_t *cert;
3629         int i = 0;
3630         while ((cert = md_flow->sslcerts[i])) {
3631             fbSubTemplateListClear(&(cert->issuer));
3632             fbSubTemplateListClear(&(cert->subject));
3633             fbSubTemplateListClear(&(cert->extension));
3634             g_slice_free(yaf_newssl_cert_t, cert);
3635             i++;
3636         }
3637         g_free(md_flow->sslcerts);
3638         fbBasicListClear(&(md_flow->fullcert->cert));
3639     }
3640 
3641 }
3642 
3643 void mdCleanUpSSLCert(
3644     yaf_newssl_cert_t *cert)
3645 {
3646     fbSubTemplateListClear(&(cert->issuer));
3647     fbSubTemplateListClear(&(cert->subject));
3648     fbSubTemplateListClear(&(cert->extension));
3649 }
3650 
3651 
3652 /**
3653  * mdCreateFieldList
3654  *
3655  * add custom field to field list
3656  *
3657  */
3658 mdFieldList_t *mdCreateFieldList(
3659     mdAcceptFilterField_t    field)
3660 {
3661     mdFieldList_t *item = NULL;
3662 
3663     item = mdNewFieldList();
3664 
3665     item->field = field;
3666 
3667     switch (field) {
3668       case FLOWKEYHASH:
3669         item->print_fn = mdPrintFlowKeyHash;
3670         break;
3671       case SIP_ANY:
3672         item->print_fn = mdPrintSIP;
3673         break;
3674       case DIP_ANY:
3675         item->print_fn = mdPrintDIP;
3676         break;
3677       case SIP_INT:
3678         item->print_fn = mdPrintSIPINT;
3679         break;
3680       case DIP_INT:
3681         item->print_fn = mdPrintDIPINT;
3682         break;
3683       case STIMEMS:
3684         item->print_fn = mdPrintSTIMEMS;
3685 
3686         break;
3687       case ETIMEMS:
3688         item->print_fn = mdPrintETIMEMS;
3689         break;
3690       case SPORT:
3691         item->print_fn = mdPrintSPort;
3692         break;
3693       case DPORT:
3694         item->print_fn = mdPrintDPort;
3695         break;
3696       case PROTOCOL:
3697         item->print_fn = mdPrintProto;
3698         break;
3699       case APPLICATION:
3700         item->print_fn = mdPrintApp;
3701         break;
3702       case OBDOMAIN:
3703         item->print_fn = mdPrintOBDomain;
3704         break;
3705       case VLAN:
3706         item->print_fn = mdPrintVLAN;
3707         break;
3708       case VLANINT:
3709         item->print_fn = mdPrintVLANINT;
3710         break;
3711       case DURATION:
3712         item->print_fn = mdPrintDuration;
3713         break;
3714       case STIME:
3715         item->print_fn = mdPrintSTIME;
3716         break;
3717       case ENDTIME:
3718         item->print_fn = mdPrintETIME;
3719         break;
3720       case RTT:
3721         item->print_fn = mdPrintRTT;
3722         break;
3723       case PKTS:
3724         item->print_fn = mdPrintPackets;
3725         break;
3726       case RPKTS:
3727         item->print_fn = mdPrintRPackets;
3728         break;
3729       case BYTES:
3730         item->print_fn = mdPrintBytes;
3731         break;
3732       case RBYTES:
3733         item->print_fn = mdPrintRBytes;
3734         break;
3735       case IFLAGS:
3736         item->print_fn = mdPrintIFlags;
3737         break;
3738       case RIFLAGS:
3739         item->print_fn = mdPrintRIFlags;
3740         break;
3741       case UFLAGS:
3742         item->print_fn = mdPrintUFlags;
3743         break;
3744       case RUFLAGS:
3745         item->print_fn = mdPrintRUFlags;
3746         break;
3747       case ATTRIBUTES:
3748         item->print_fn = mdPrintAttributes;
3749         break;
3750       case RATTRIBUTES:
3751         item->print_fn = mdPrintRAttributes;
3752         break;
3753       case MAC:
3754         item->print_fn = mdPrintMAC;
3755         break;
3756       case DSTMAC:
3757         item->print_fn = mdPrintDSTMAC;
3758         break;
3759       case TCPSEQ:
3760         item->print_fn = mdPrintTCPSeq;
3761         break;
3762       case RTCPSEQ:
3763         item->print_fn = mdPrintRTCPSeq;
3764         break;
3765       case ENTROPY:
3766         item->print_fn = mdPrintEntropy;
3767         break;
3768       case RENTROPY:
3769         item->print_fn = mdPrintREntropy;
3770         break;
3771       case END:
3772         item->print_fn = mdPrintEnd;
3773         break;
3774       case DHCPFP:
3775         item->print_fn = mdPrintDHCPFP;
3776         break;
3777       case RDHCPFP:
3778         item->print_fn = mdPrintRDHCPFP;
3779         break;
3780       case DHCPVC:
3781         item->print_fn = mdPrintDHCPVC;
3782         break;
3783       case RDHCPVC:
3784         item->print_fn = mdPrintRDHCPVC;
3785         break;
3786       case OSNAME:
3787         item->print_fn = mdPrintOSNAME;
3788         break;
3789       case OSVERSION:
3790         item->print_fn = mdPrintOSVersion;
3791         break;
3792       case ROSNAME:
3793         item->print_fn = mdPrintROSNAME;
3794         break;
3795       case ROSVERSION:
3796         item->print_fn = mdPrintROSVersion;
3797         break;
3798       case FINGERPRINT:
3799         item->print_fn = mdPrintOSFingerprint;
3800         break;
3801       case RFINGERPRINT:
3802         item->print_fn = mdPrintROSFingerprint;
3803         break;
3804       case INGRESS:
3805         item->print_fn = mdPrintIngress;
3806         break;
3807       case EGRESS:
3808         item->print_fn = mdPrintEgress;
3809         break;
3810       case DATABYTES:
3811         item->print_fn = mdPrintDataBytes;
3812         break;
3813       case RDATABYTES:
3814         item->print_fn = mdPrintRDataBytes;
3815         break;
3816       case ITIME:
3817         item->print_fn = mdPrintITime;
3818         break;
3819       case RITIME:
3820         item->print_fn = mdPrintRITime;
3821         break;
3822       case STDITIME:
3823         item->print_fn = mdPrintSTDITime;
3824         break;
3825       case RSTDITIME:
3826         item->print_fn = mdPrintRSTDITime;
3827         break;
3828       case TCPURG:
3829         item->print_fn = mdPrintTCPURG;
3830         break;
3831       case RTCPURG:
3832         item->print_fn = mdPrintRTCPURG;
3833         break;
3834       case SMALLPKTS:
3835         item->print_fn = mdPrintSmallPkts;
3836 
3837         break;
3838       case RSMALLPKTS:
3839         item->print_fn = mdPrintRSmallPkts;
3840         break;
3841       case LARGEPKTS:
3842         item->print_fn = mdPrintLargePkts;
3843         break;
3844       case RLARGEPKTS:
3845         item->print_fn = mdPrintRLargePkts;
3846         break;
3847       case NONEMPTYPKTS:
3848         item->print_fn = mdPrintNonEmptyPkts;
3849         break;
3850       case RNONEMPTYPKTS:
3851         item->print_fn = mdPrintRNonEmptyPkts;
3852         break;
3853       case MAXSIZE:
3854         item->print_fn = mdPrintMaxPacketSize;
3855         break;
3856       case RMAXSIZE:
3857         item->print_fn = mdPrintRMaxPacketSize;
3858         break;
3859       case STDPAYLEN:
3860         item->print_fn = mdPrintSTDPayLen;
3861         break;
3862       case RSTDPAYLEN:
3863         item->print_fn = mdPrintRSTDPayLen;
3864         break;
3865       case FIRSTEIGHT:
3866         item->print_fn = mdPrintFirstEight;
3867         break;
3868       case TOS:
3869         item->print_fn = mdPrintTOS;
3870         break;
3871       case RTOS:
3872         item->print_fn = mdPrintRTOS;
3873         break;
3874       case MPLS1:
3875         item->print_fn = mdPrintMPLS1;
3876         break;
3877       case MPLS2:
3878         item->print_fn = mdPrintMPLS2;
3879         break;
3880       case MPLS3:
3881         item->print_fn = mdPrintMPLS3;
3882         break;
3883       case COLLECTOR:
3884         item->print_fn = mdPrintCollectorName;
3885         break;
3886       case FIRSTNONEMPTY:
3887         item->print_fn = mdPrintFirstNonEmpty;
3888         break;
3889       case RFIRSTNONEMPTY:
3890         item->print_fn = mdPrintRFirstNonEmpty;
3891         break;
3892       case MPTCPSEQ:
3893         item->print_fn = mdPrintMPTCPSeq;
3894         break;
3895       case MPTCPTOKEN:
3896         item->print_fn = mdPrintMPTCPToken;
3897         break;
3898       case MPTCPMSS:
3899         item->print_fn = mdPrintMPTCPMss;
3900         break;
3901       case MPTCPID:
3902         item->print_fn = mdPrintMPTCPId;
3903         break;
3904       case MPTCPFLAGS:
3905         item->print_fn = mdPrintMPTCPFlags;
3906         break;
3907       case NONE_FIELD:
3908         item->print_fn = mdPrintNone;
3909         break;
3910       case PAYLOAD:
3911         item->print_fn = mdPrintPayload;
3912         break;
3913       case RPAYLOAD:
3914         item->print_fn = mdPrintRPayload;
3915         break;
3916       case DHCPOPTIONS:
3917         item->print_fn = mdPrintDHCPOptions;
3918         break;
3919       case RDHCPOPTIONS:
3920         item->print_fn = mdPrintRevDHCPOptions;
3921         break;
3922       case NDPI_MASTER:
3923         item->print_fn = mdPrintNDPIMaster;
3924         break;
3925       case NDPI_SUB:
3926         item->print_fn = mdPrintNDPISub;
3927         break;
3928       default:
3929         return NULL;
3930     }
3931 
3932     return item;
3933 }
3934 
3935 
3936 
3937 /**
3938  * mdSetFieldListDecorator
3939  *
3940  * create custom printer for CSV
3941  *
3942  */
3943 void mdSetFieldListDecoratorCustom(
3944     mdFieldList_t *list,
3945     char          delimiter)
3946 
3947 {
3948     mdFieldList_t *item = NULL;
3949 
3950     for (item = list; item; item = item->next) {
3951         if (item->decorator) {
3952             /* decorator already set */
3953             return;
3954         }
3955         switch (item->field) {
3956           case FLOWKEYHASH:
3957             item->decorator = g_string_new("%u");
3958             break;
3959           case SIP_ANY:
3960             item->decorator = g_string_new("%s");
3961             break;
3962           case DIP_ANY:
3963             item->decorator = g_string_new("%s");
3964             break;
3965           case SIP_INT:
3966             item->decorator = g_string_new("%u");
3967             break;
3968           case DIP_INT:
3969             item->decorator = g_string_new("%u");
3970             break;
3971           case STIMEMS:
3972             item->decorator = g_string_new("%"PRIu64"");
3973             break;
3974           case ETIMEMS:
3975             item->decorator = g_string_new("%"PRIu64"");
3976             break;
3977           case SPORT:
3978             item->decorator = g_string_new("%d");
3979             break;
3980           case DPORT:
3981             item->decorator = g_string_new("%d");
3982             break;
3983           case PROTOCOL:
3984             item->decorator = g_string_new("%d");
3985             break;
3986           case NDPI_MASTER:
3987           case NDPI_SUB:
3988           case APPLICATION:
3989             item->decorator = g_string_new("%d");
3990             break;
3991           case OBDOMAIN:
3992             item->decorator = g_string_new("%u");
3993             break;
3994           case VLAN:
3995             item->decorator = g_string_new("%03x");
3996             break;
3997           case VLANINT:
3998             item->decorator = g_string_new("%u");
3999             break;
4000           case DURATION:
4001             item->decorator = g_string_new("%.3f");
4002             break;
4003           case STIME:
4004             item->decorator = g_string_new("%s");
4005             break;
4006           case ENDTIME:
4007             item->decorator = g_string_new("%s");
4008             break;
4009           case RTT:
4010             item->decorator =   g_string_new("%.3f");
4011             break;
4012           case PKTS:
4013             item->decorator = g_string_new("%"PRIu64"");
4014             break;
4015           case RPKTS:
4016             item->decorator =  g_string_new("%"PRIu64"");
4017             break;
4018           case BYTES:
4019             item->decorator = g_string_new("%"PRIu64"");
4020             break;
4021           case RBYTES:
4022             item->decorator =  g_string_new("%"PRIu64"");
4023             break;
4024           case IFLAGS:
4025             item->decorator = g_string_new("%s");
4026             break;
4027           case RIFLAGS:
4028             item->decorator = g_string_new("%s");
4029             break;
4030           case UFLAGS:
4031             item->decorator = g_string_new("%s");
4032             break;
4033           case RUFLAGS:
4034             item->decorator = g_string_new("%s");
4035             break;
4036           case ATTRIBUTES:
4037             item->decorator = g_string_new("%02x");
4038             break;
4039           case RATTRIBUTES:
4040             item->decorator =  g_string_new("%02x");
4041             break;
4042           case MAC:
4043             item->decorator =  g_string_new("%s");
4044             break;
4045           case DSTMAC:
4046             item->decorator =  g_string_new("%s");
4047             break;
4048           case TCPSEQ:
4049             item->decorator = g_string_new("%08x");
4050             break;
4051           case RTCPSEQ:
4052             item->decorator = g_string_new("%08x");
4053             break;
4054           case ENTROPY:
4055             item->decorator =  g_string_new("%u");
4056             break;
4057           case RENTROPY:
4058             item->decorator = g_string_new("%u");
4059             break;
4060           case END:
4061             item->decorator = g_string_new("%s");
4062             break;
4063           case DHCPFP:
4064             item->decorator = g_string_new("%s");
4065             break;
4066           case RDHCPFP:
4067             item->decorator = g_string_new("%s");
4068             break;
4069           case DHCPVC:
4070             item->decorator = g_string_new("%s");
4071             break;
4072           case RDHCPVC:
4073             item->decorator = g_string_new("%s");
4074             break;
4075           case DHCPOPTIONS:
4076             item->decorator = g_string_new("%s");
4077             break;
4078           case RDHCPOPTIONS:
4079             item->decorator = g_string_new("%s");
4080             break;
4081           case OSNAME:
4082             item->decorator = g_string_new("%s");
4083             break;
4084           case OSVERSION:
4085             item->decorator = g_string_new("%s");
4086             break;
4087           case ROSNAME:
4088             item->decorator = g_string_new("%s");
4089             break;
4090           case ROSVERSION:
4091             item->decorator = g_string_new("%s");
4092             break;
4093           case FINGERPRINT:
4094             item->decorator = g_string_new("%s");
4095             break;
4096           case RFINGERPRINT:
4097             item->decorator = g_string_new("%s");
4098             break;
4099           case INGRESS:
4100             item->decorator = g_string_new("%u");
4101             break;
4102           case EGRESS:
4103             item->decorator = g_string_new("%u");
4104             break;
4105           case DATABYTES:
4106             item->decorator = g_string_new("%"PRIu64"");
4107             break;
4108           case RDATABYTES:
4109             item->decorator = g_string_new("%"PRIu64"");
4110             break;
4111           case ITIME:
4112             item->decorator = g_string_new("%.3f");
4113             break;
4114           case RITIME:
4115             item->decorator = g_string_new("%.3f");
4116             break;
4117           case STDITIME:
4118             item->decorator = g_string_new("%.3f");
4119             break;
4120           case RSTDITIME:
4121             item->decorator = g_string_new("%.3f");
4122             break;
4123           case TCPURG:
4124             item->decorator = g_string_new("%u");
4125             break;
4126           case RTCPURG:
4127             item->decorator = g_string_new("%u");
4128             break;
4129           case SMALLPKTS:
4130             item->decorator = g_string_new("%u");
4131             break;
4132           case RSMALLPKTS:
4133             item->decorator = g_string_new("%u");
4134             break;
4135           case LARGEPKTS:
4136             item->decorator = g_string_new("%u");
4137             break;
4138           case RLARGEPKTS:
4139             item->decorator = g_string_new("%u");
4140             break;
4141           case NONEMPTYPKTS:
4142             item->decorator = g_string_new("%u");
4143             break;
4144           case RNONEMPTYPKTS:
4145             item->decorator = g_string_new("%u");
4146             break;
4147           case MAXSIZE:
4148             item->decorator = g_string_new("%d");
4149             break;
4150           case RMAXSIZE:
4151             item->decorator = g_string_new("%d");
4152             break;
4153           case STDPAYLEN:
4154             item->decorator = g_string_new("%d");
4155             break;
4156           case RSTDPAYLEN:
4157             item->decorator = g_string_new("%d");
4158             break;
4159           case FIRSTEIGHT:
4160             item->decorator = g_string_new("%02x");
4161             break;
4162           case TOS:
4163             item->decorator = g_string_new("%02x");
4164             break;
4165           case RTOS:
4166             item->decorator = g_string_new("%02x");
4167             break;
4168           case MPLS1:
4169             item->decorator = g_string_new("%d");
4170             break;
4171           case MPLS2:
4172             item->decorator = g_string_new("%d");
4173             break;
4174           case MPLS3:
4175             item->decorator = g_string_new("%d");
4176             break;
4177           case COLLECTOR:
4178             item->decorator = g_string_new("%s");
4179             break;
4180           case FIRSTNONEMPTY:
4181             item->decorator = g_string_new("%d");
4182             break;
4183           case RFIRSTNONEMPTY:
4184             item->decorator = g_string_new("%d");
4185             break;
4186           case MPTCPSEQ:
4187             item->decorator = g_string_new("%"PRIu64"");
4188             break;
4189           case MPTCPTOKEN:
4190             item->decorator = g_string_new("%u");
4191             break;
4192           case MPTCPMSS:
4193             item->decorator = g_string_new("%d");
4194             break;
4195           case MPTCPID:
4196             item->decorator = g_string_new("%d");
4197             break;
4198           case MPTCPFLAGS:
4199             item->decorator = g_string_new("%02x");
4200             break;
4201           case NONE_FIELD:
4202             item->decorator = g_string_new("");
4203             break;
4204           case PAYLOAD:
4205           case RPAYLOAD:
4206             item->decorator = g_string_new("");
4207             break;
4208           default:
4209             return;
4210         }
4211 
4212         g_string_append_c(item->decorator, delimiter);
4213     }
4214 
4215 }
4216 
4217 /**
4218  * mdSetFieldListDecoratorJSON
4219  *
4220  * create the custom printer for JSON
4221  *
4222  */
4223 void mdSetFieldListDecoratorJSON(
4224     mdFieldList_t *list)
4225 
4226 {
4227     mdFieldList_t *item = NULL;
4228 
4229     for (item = list; item; item = item->next) {
4230         if (item->decorator) {
4231             /* decorator already set */
4232             return;
4233         }
4234         switch (item->field) {
4235           case FLOWKEYHASH:
4236             item->decorator = g_string_new("\"yafFlowKeyHash\":%u,");
4237             break;
4238           case SIP_ANY:
4239             item->decorator = g_string_new("\"sourceIPv4Address\":\"%s\",");
4240             break;
4241           case DIP_ANY:
4242             item->decorator = g_string_new("\"destinationIPv4Address\":\"%s\",");
4243             break;
4244           case SIP_INT:
4245             item->decorator = g_string_new("\"sourceIPv4Address\":%u,");
4246             break;
4247           case DIP_INT:
4248             item->decorator = g_string_new("\"destinationIPv4Address\":%u,");
4249             break;
4250           case STIMEMS:
4251             item->decorator = g_string_new("\"flowStartMilliseconds\":\"%"PRIu64"\",");
4252             break;
4253           case ETIMEMS:
4254             item->decorator = g_string_new("\"flowEndMilliseconds\":\"%"PRIu64"\",");
4255             break;
4256           case SPORT:
4257             item->decorator = g_string_new("\"sourceTransportPort\":%d,");
4258             break;
4259           case DPORT:
4260             item->decorator = g_string_new("\"destinationTransportPort\":%d,");
4261             break;
4262           case PROTOCOL:
4263             item->decorator = g_string_new("\"protocolIdentifier\":%d,");
4264             break;
4265           case APPLICATION:
4266             item->decorator = g_string_new("\"silkAppLabel\":%d,");
4267             break;
4268           case OBDOMAIN:
4269             item->decorator = g_string_new("\"observationDomainId\":%u,");
4270             break;
4271           case VLAN:
4272             item->decorator = g_string_new("\"vlanId\":\"0x%03x\",");
4273             break;
4274           case VLANINT:
4275             item->decorator = g_string_new("\"vlanId\":%u,");
4276             break;
4277           case DURATION:
4278             item->decorator = g_string_new("\"flowDurationMilliseconds\":%.3f,");
4279             break;
4280           case STIME:
4281             item->decorator = g_string_new("\"flowStartMilliseconds\":\"%s\",");
4282             break;
4283           case ENDTIME:
4284             item->decorator = g_string_new("\"flowEndMilliseconds\":\"%s\",");
4285             break;
4286           case RTT:
4287             item->decorator =  g_string_new("\"reverseFlowDeltaMilliseconds\":%.3f,");
4288             break;
4289           case PKTS:
4290             item->decorator = g_string_new("\"packetTotalCount\":%"PRIu64",");
4291             break;
4292           case RPKTS:
4293             item->decorator =  g_string_new("\"reversePacketTotalCount\":%"PRIu64",");
4294             break;
4295           case BYTES:
4296             item->decorator = g_string_new("\"octetTotalCount\":%"PRIu64",");
4297             break;
4298           case RBYTES:
4299             item->decorator =  g_string_new("\"reverseOctetTotalCount\":%"PRIu64",");
4300             break;
4301           case IFLAGS:
4302             item->decorator = g_string_new("\"initialTCPFlags\":\"%s\",");
4303             break;
4304           case RIFLAGS:
4305             item->decorator = g_string_new("\"reverseInitialTCPFlags\":\"%s\",");
4306             break;
4307           case UFLAGS:
4308             item->decorator = g_string_new("\"unionTCPFlags\":\"%s\",");
4309             break;
4310           case RUFLAGS:
4311             item->decorator = g_string_new("\"reverseUnionTCPFlags\":\"%s\",");
4312             break;
4313           case ATTRIBUTES:
4314             item->decorator = g_string_new("\"flowAttributes\":\"%02x\",");
4315             break;
4316           case RATTRIBUTES:
4317             item->decorator =  g_string_new("\"reverseFlowAttributes\":\"%02x\",");
4318             break;
4319           case MAC:
4320             item->decorator =  g_string_new("\"sourceMacAddress\":\"%s\",");
4321             break;
4322           case DSTMAC:
4323             item->decorator =  g_string_new("\"destinationMacAddress\":\"%s\",");
4324             break;
4325           case TCPSEQ:
4326             item->decorator = g_string_new("\"tcpSequenceNumber\":\"0x%08x\",");
4327             break;
4328           case RTCPSEQ:
4329             item->decorator = g_string_new("\"reverseTcpSequenceNumber\":\"0x%08x\",");
4330             break;
4331           case ENTROPY:
4332             item->decorator =  g_string_new("\"payloadEntropy\":%u,");
4333             break;
4334           case RENTROPY:
4335             item->decorator = g_string_new("\"reversePayloadEntropy\":%u,");
4336             break;
4337           case END:
4338             item->decorator = g_string_new("\"flowEndReason\":\"%s\",");
4339             break;
4340           case DHCPFP:
4341             item->decorator = g_string_new("\"dhcpFingerPrint\":\"%s\",");
4342             break;
4343           case RDHCPFP:
4344             item->decorator = g_string_new("\"reverseDhcpFingerPrint\":\"%s\",");
4345             break;
4346           case DHCPVC:
4347             item->decorator = g_string_new("\"dhcpVendorCode\":\"%s\",");
4348             break;
4349           case RDHCPVC:
4350             item->decorator = g_string_new("\"reverseDhcpVendorCode\":\"%s\",");
4351             break;
4352           case DHCPOPTIONS:
4353             item->decorator = g_string_new("\"dhcpOptionsList\":[%s],");
4354             break;
4355           case RDHCPOPTIONS:
4356             item->decorator = g_string_new("\"reverseDhcpOptionsList\":[%s],");
4357             break;
4358           case OSNAME:
4359             item->decorator = g_string_new("\"osName\":\"%s\",");
4360             break;
4361           case OSVERSION:
4362             item->decorator = g_string_new("\"osVersion\":\"%s\",");
4363             break;
4364           case ROSNAME:
4365             item->decorator = g_string_new("\"reverseOsName\":\"%s\",");
4366             break;
4367           case ROSVERSION:
4368             item->decorator = g_string_new("\"reverseOsVersion\":\"%s\",");
4369             break;
4370           case FINGERPRINT:
4371             item->decorator = g_string_new("\"osFingerPrint\":\"%s\",");
4372             break;
4373           case RFINGERPRINT:
4374             item->decorator = g_string_new("\"reverseOsFingerPrint\":\"%s\",");
4375             break;
4376           case INGRESS:
4377             item->decorator = g_string_new("\"ingressInterface\":%u,");
4378             break;
4379           case EGRESS:
4380             item->decorator = g_string_new("\"egressInterface\":%u,");
4381             break;
4382           case DATABYTES:
4383             item->decorator = g_string_new("\"dataByteCount\":%"PRIu64",");
4384             break;
4385           case RDATABYTES:
4386             item->decorator = g_string_new("\"reverseDataByteCount\":%"PRIu64",");
4387             break;
4388           case ITIME:
4389             item->decorator = g_string_new("\"averageInterarrivalTime\":%.3f,");
4390             break;
4391           case RITIME:
4392             item->decorator = g_string_new("\"reverseAverageInterArrivalTime\":%.3f,");
4393             break;
4394           case STDITIME:
4395             item->decorator = g_string_new("\"standardDeviationInterarrivalTime\":%.3f,");
4396             break;
4397           case RSTDITIME:
4398             item->decorator = g_string_new("\"reverseStandardDeviationInterarrivalTime\":%.3f,");
4399             break;
4400           case TCPURG:
4401             item->decorator = g_string_new("\"tcpUrgentCount\":%u,");
4402             break;
4403           case RTCPURG:
4404             item->decorator = g_string_new("\"reverseTcpUrgentCount\":%u,");
4405             break;
4406           case SMALLPKTS:
4407             item->decorator = g_string_new("\"smallPacketCount\":%u,");
4408             break;
4409           case RSMALLPKTS:
4410             item->decorator = g_string_new("\"reverseSmallPacketCount\":%u,");
4411             break;
4412           case LARGEPKTS:
4413             item->decorator = g_string_new("\"largePacketCount\":%u,");
4414             break;
4415           case RLARGEPKTS:
4416             item->decorator = g_string_new("\"reverseLargePacketCount\":%u,");
4417             break;
4418           case NONEMPTYPKTS:
4419             item->decorator = g_string_new("\"nonEmptyPacketCount\":%u,");
4420             break;
4421           case RNONEMPTYPKTS:
4422             item->decorator = g_string_new("\"reverseNonEmptyPacketCount\":%u,");
4423             break;
4424           case MAXSIZE:
4425             item->decorator = g_string_new("\"maxPacketSize\":%d,");
4426             break;
4427           case RMAXSIZE:
4428             item->decorator = g_string_new("\"reverseMaxPacketSize\":%d,");
4429             break;
4430           case STDPAYLEN:
4431             item->decorator = g_string_new("\"standardDeviationPayloadLength\":%d,");
4432             break;
4433           case RSTDPAYLEN:
4434             item->decorator = g_string_new("\"reverseStandardDeviationPayloadLength\":%d,");
4435             break;
4436           case FIRSTEIGHT:
4437             item->decorator = g_string_new("\"firstEightNonEmptyPacketDirections\":\"%02x\",");
4438             break;
4439           case TOS:
4440             item->decorator = g_string_new("\"ipClassOfService\":\"0x%02x\",");
4441             break;
4442           case RTOS:
4443             item->decorator = g_string_new("\"reverseIpClassOfService\":\"0x%02x\",");
4444             break;
4445           case MPLS1:
4446             item->decorator = g_string_new("\"mplsTopLabelStackSection\":%d,");
4447             break;
4448           case MPLS2:
4449             item->decorator = g_string_new("\"mplsTopLabelStackSection2\":%d,");
4450             break;
4451           case MPLS3:
4452             item->decorator = g_string_new("\"mplsTopLabelStackSection3\":%d,");
4453             break;
4454           case COLLECTOR:
4455             item->decorator = g_string_new("\"collectorName\":\"%s\",");
4456             break;
4457           case FIRSTNONEMPTY:
4458             item->decorator = g_string_new("\"firstNonEmptyPacketSize\":%d,");
4459             break;
4460           case RFIRSTNONEMPTY:
4461             item->decorator = g_string_new("\"reverseFirstNonEmptyPacketSize\":%d,");
4462             break;
4463           case MPTCPSEQ:
4464             item->decorator = g_string_new("\"mptcpInitialDataSequenceNumber\":%"PRIu64",");
4465             break;
4466           case MPTCPTOKEN:
4467             item->decorator = g_string_new("\"mptcpReceiverToken\":%u,");
4468             break;
4469           case MPTCPMSS:
4470             item->decorator = g_string_new("\"mptcpMaximumSegmentSize\":%d,");
4471             break;
4472           case MPTCPID:
4473             item->decorator = g_string_new("\"mptcpAddressID\":%d,");
4474             break;
4475           case MPTCPFLAGS:
4476             item->decorator = g_string_new("\"mptcpFlags\":\"%02x\",");
4477             break;
4478           case PAYLOAD:
4479             item->print_fn = mdPrintPayloadJSON;
4480             item->decorator = g_string_new("\"payload\":\"%s\",");
4481             break;
4482           case RPAYLOAD:
4483             item->print_fn = mdPrintRPayloadJSON;
4484             item->decorator = g_string_new("\"reversePayload\":\"%s\",");
4485             break;
4486           case NDPI_MASTER:
4487             item->decorator = g_string_new("\"nDPIL7Protocol\":%d,");
4488             break;
4489           case NDPI_SUB:
4490             item->decorator = g_string_new("\"nDPIL7SubProtocol\":%d,");
4491             break;
4492           case NONE_FIELD:
4493             item->decorator = NULL;
4494             break;
4495           default:
4496             break;
4497         }
4498     }
4499 }
4500 
4501 
4502 /**
4503  * mdSetFieldListDecoratorBasic
4504  *
4505  * create basic printer for CSV
4506  *
4507  */
4508 void mdSetFieldListDecoratorBasic(
4509     mdFieldList_t *list,
4510     char          delimiter)
4511 
4512 {
4513     mdFieldList_t *item = NULL;
4514 
4515 
4516     for (item = list; item; item = item->next) {
4517         if (item->decorator) {
4518             /* decorator already set */
4519             return;
4520         }
4521         switch (item->field) {
4522           case SIP_ANY:
4523             item->decorator = g_string_new("%40s");
4524             break;
4525           case DIP_ANY:
4526             item->decorator = g_string_new("%40s");
4527             break;
4528           case SPORT:
4529             item->decorator = g_string_new("%5d");
4530             break;
4531           case DPORT:
4532             item->decorator = g_string_new("%5d");
4533             break;
4534           case PROTOCOL:
4535             item->decorator = g_string_new("%3d");
4536             break;
4537           case NDPI_MASTER:
4538           case NDPI_SUB:
4539           case APPLICATION:
4540             item->decorator = g_string_new("%5d");
4541             break;
4542           case VLAN:
4543             item->decorator = g_string_new("%03x");
4544             break;
4545           case DURATION:
4546             item->decorator = g_string_new("%8.3f");
4547             break;
4548           case STIME:
4549             item->decorator = g_string_new("%s");
4550             break;
4551           case ENDTIME:
4552             item->decorator = g_string_new("%s");
4553             break;
4554           case RTT:
4555             item->decorator =   g_string_new("%8.3f");
4556             break;
4557           case PKTS:
4558             item->decorator = g_string_new("%8"PRIu64"");
4559             break;
4560           case RPKTS:
4561             item->decorator =  g_string_new("%8"PRIu64"");
4562             break;
4563           case BYTES:
4564             item->decorator = g_string_new("%8"PRIu64"");
4565             break;
4566           case RBYTES:
4567             item->decorator =  g_string_new("%8"PRIu64"");
4568             break;
4569           case IFLAGS:
4570             item->decorator = g_string_new("%8s");
4571             break;
4572           case RIFLAGS:
4573             item->decorator = g_string_new("%8s");
4574             break;
4575           case UFLAGS:
4576             item->decorator = g_string_new("%8s");
4577             break;
4578           case RUFLAGS:
4579             item->decorator = g_string_new("%8s");
4580             break;
4581           case ATTRIBUTES:
4582             item->decorator = g_string_new("%02x");
4583             break;
4584           case RATTRIBUTES:
4585             item->decorator =  g_string_new("%02x");
4586             break;
4587           case MAC:
4588             item->decorator =  g_string_new("%s");
4589             break;
4590           case DSTMAC:
4591             item->decorator =  g_string_new("%s");
4592             break;
4593           case TCPSEQ:
4594             item->decorator = g_string_new("%08x");
4595             break;
4596           case RTCPSEQ:
4597             item->decorator = g_string_new("%08x");
4598             break;
4599           case ENTROPY:
4600             item->decorator =  g_string_new("%3u");
4601             break;
4602           case RENTROPY:
4603             item->decorator = g_string_new("%3u");
4604             break;
4605           case END:
4606             item->decorator = g_string_new("%6s");
4607             break;
4608           case INGRESS:
4609             item->decorator = g_string_new("%5u");
4610             break;
4611           case EGRESS:
4612             item->decorator = g_string_new("%5u");
4613             break;
4614           case TOS:
4615             item->decorator = g_string_new(" %02x");
4616             break;
4617           case RTOS:
4618             item->decorator = g_string_new("%02x");
4619             break;
4620           case COLLECTOR:
4621             /* collector is last field so no delimiter, add newline */
4622             item->decorator = g_string_new("%s\n");
4623             continue;
4624           case PAYLOAD:
4625           case RPAYLOAD:
4626             item->decorator = g_string_new("");
4627             continue;
4628           default:
4629             g_warning("Invalid field for Basic Flow Print.");
4630             break;
4631         }
4632 
4633         g_string_append_c(item->decorator, delimiter);
4634     }
4635 
4636 }
4637 
4638 
4639 mdFieldList_t *mdCreateBasicFlowList(
4640     gboolean payload)
4641 {
4642     mdFieldList_t *start = NULL;
4643     mdFieldList_t *item = NULL;
4644     mdFieldList_t *cur = NULL;
4645 
4646     start = mdCreateFieldList(STIME);
4647     cur = start;
4648     item = mdCreateFieldList(ENDTIME);
4649     cur->next = item;
4650     cur = item;
4651     item = mdCreateFieldList(DURATION);
4652     cur->next = item;
4653     cur = item;
4654     item = mdCreateFieldList(RTT);
4655     cur->next = item;
4656     cur = item;
4657     item = mdCreateFieldList(PROTOCOL);
4658     cur->next = item;
4659     cur = item;
4660     item = mdCreateFieldList(SIP_ANY);
4661     cur->next = item;
4662     cur = item;
4663     item = mdCreateFieldList(SPORT);
4664     cur->next = item;
4665     cur = item;
4666     item = mdCreateFieldList(PKTS);
4667     cur->next = item;
4668     cur = item;
4669     item = mdCreateFieldList(BYTES);
4670     cur->next = item;
4671     cur = item;
4672     item = mdCreateFieldList(ATTRIBUTES);
4673     cur->next = item;
4674     cur = item;
4675     item = mdCreateFieldList(MAC);
4676     cur->next = item;
4677     cur = item;
4678     item = mdCreateFieldList(DIP_ANY);
4679     cur->next = item;
4680     cur = item;
4681     item = mdCreateFieldList(DPORT);
4682     cur->next = item;
4683     cur = item;
4684     item = mdCreateFieldList(RPKTS);
4685     cur->next = item;
4686     cur = item;
4687     item = mdCreateFieldList(RBYTES);
4688     cur->next = item;
4689     cur = item;
4690     item = mdCreateFieldList(RATTRIBUTES);
4691     cur->next = item;
4692     cur = item;
4693     item = mdCreateFieldList(DSTMAC);
4694     cur->next = item;
4695     cur = item;
4696     item = mdCreateFieldList(IFLAGS);
4697     cur->next = item;
4698     cur = item;
4699     item = mdCreateFieldList(UFLAGS);
4700     cur->next = item;
4701     cur = item;
4702     item = mdCreateFieldList(RIFLAGS);
4703     cur->next = item;
4704     cur = item;
4705     item = mdCreateFieldList(RUFLAGS);
4706     cur->next = item;
4707     cur = item;
4708     item = mdCreateFieldList(TCPSEQ);
4709     cur->next = item;
4710     cur = item;
4711     item = mdCreateFieldList(RTCPSEQ);
4712     cur->next = item;
4713     cur = item;
4714     item = mdCreateFieldList(INGRESS);
4715     cur->next = item;
4716     cur = item;
4717     item = mdCreateFieldList(EGRESS);
4718     cur->next = item;
4719     cur = item;
4720     item = mdCreateFieldList(VLAN);
4721     cur->next = item;
4722     cur = item;
4723     item = mdCreateFieldList(APPLICATION);
4724     cur->next = item;
4725     cur = item;
4726     item = mdCreateFieldList(TOS);
4727     cur->next = item;
4728     cur = item;
4729     item = mdCreateFieldList(END);
4730     cur->next = item;
4731     cur = item;
4732     item = mdCreateFieldList(COLLECTOR);
4733     cur->next = item;
4734     cur = item;
4735     if (payload) {
4736         item = mdCreateFieldList(PAYLOAD);
4737         cur->next = item;
4738         cur = item;
4739         item = mdCreateFieldList(RPAYLOAD);
4740         cur->next = item;
4741         cur = item;
4742     }
4743 
4744     return start;
4745 }
4746 
4747 mdFieldList_t *mdCreateIndexFlowList(
4748                                      )
4749 {
4750     mdFieldList_t *start = NULL;
4751     mdFieldList_t *item = NULL;
4752     mdFieldList_t *cur = NULL;
4753 
4754     start = mdCreateFieldList(STIME);
4755     cur = start;
4756     item = mdCreateFieldList(PROTOCOL);
4757     cur->next = item;
4758     cur = item;
4759     item = mdCreateFieldList(SIP_ANY);
4760     cur->next = item;
4761     cur = item;
4762     item = mdCreateFieldList(SPORT);
4763     cur->next = item;
4764     cur = item;
4765     item = mdCreateFieldList(DIP_ANY);
4766     cur->next = item;
4767     cur = item;
4768     item = mdCreateFieldList(DPORT);
4769     cur->next = item;
4770     cur = item;
4771     item = mdCreateFieldList(VLAN);
4772     cur->next = item;
4773     cur = item;
4774     item = mdCreateFieldList(OBDOMAIN);
4775     cur->next = item;
4776     cur = item;
4777 
4778     return start;
4779 }
4780 
4781 /**
4782  *  Function: attachHeadToSLL
4783  *  Description: attach a new entry to the front of a singly linked list
4784  *  Params: **head - double pointer to the current head.  *head will point
4785  *                to that new element at the end of this function
4786  *          *newEntry - a pointer to the previously allocated entry to be added
4787  *  Return: NONE
4788  */
4789 void attachHeadToSLL(
4790     mdSLL_t **head,
4791     mdSLL_t  *newEntry)
4792 {
4793     assert(head);
4794     assert(newEntry);
4795 
4796     /*  works even if *head starts out null, being no elements attach
4797      *  the new entry to the head */
4798     newEntry->next = *head;
4799     /*  reassign the head pointer to the new entry */
4800     *head = newEntry;
4801 }
4802 
4803 /**
4804  *  Function: detachHeadOfSLL
4805  *  Description: remove the head entry from a singly linked list, set
4806  *      the head pointer to the next one in the list, and return the
4807  *      old head
4808  *  Params: **head - double pointer to the head node of the list.  After
4809  *                      this function, (*head) will point to the
4810  *                      new head (*(originalhead)->next)
4811  *          **toRemove - double pointer to use to return the old head
4812  *  Return: NONE
4813  */
4814 void detachHeadOfSLL(
4815     mdSLL_t **head,
4816     mdSLL_t **toRemove)
4817 {
4818     assert(toRemove);
4819     assert(head);
4820     assert(*head);
4821 
4822     /*  set the outgoing pointer to point to the head listing */
4823     *toRemove = *head;
4824     /*  move the head pointer down one */
4825     *head = (*head)->next;
4826 }
4827