1 /*
2 ** Copyright (C) 2008-2020 by Carnegie Mellon University.
3 **
4 ** @OPENSOURCE_LICENSE_START@
5 ** See license information in ../../LICENSE.txt
6 ** @OPENSOURCE_LICENSE_END@
7 */
8 
9 /**
10 **  @file
11 **
12 **  skplugin.h
13 **
14 **
15 **    The SKPLUGIN library defines the layer between the application
16 **    that want to make use of a plugin and the plugin code that
17 **    implements some functionality.
18 **
19 */
20 #ifndef _SKPLUGIN_H
21 #define _SKPLUGIN_H
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #include <silk/silk.h>
27 
28 RCSIDENTVAR(rcsID_SKPLUGIN_H, "$SiLK: skplugin.h ef14e54179be 2020-04-14 21:57:45Z mthomas $");
29 
30 #include <silk/silk_types.h>
31 #include <silk/utils.h>         /* need "struct option" */
32 
33 /*
34 **
35 **    The plugin author will need to use the API specified in the
36 **    "PLUG-IN INTERFACE" section of this file.  In general, these
37 **    functions all begin with "skpin".
38 **
39 **    There are two APIs that the plugin author can use.  One is the
40 **    simple API that makes defining new fields relatively easy.  The
41 **    other is an advanced API that gives one finer control.  Both of
42 **    these APIs are similar to the APIs used when registering plugins
43 **    from PySiLK.  You may find it useful to read the silkpython(3)
44 **    manual page.
45 **
46 **    The application author will need to use the API specified in the
47 **    "APPLICATION INTERFACE section of this file.  In general, these
48 **    functions all begin with "skPlugin".
49 **
50 **    The top of this file specifies macros and typedefs that are
51 **    common to both APIs.
52 **
53 */
54 
55 
56 /**
57  *    Return value from most skplugin functions
58  */
59 typedef enum {
60     /** all is well */
61     SKPLUGIN_OK,
62 
63     /** result passes filter */
64     SKPLUGIN_FILTER_PASS,
65 
66     /** result passes filter immediately. Do not check any more plugin
67      * filter or transform functions */
68     SKPLUGIN_FILTER_PASS_NOW,
69 
70     /** result fails filter */
71     SKPLUGIN_FILTER_FAIL,
72 
73     /** result is marked as neither pass nor fail.  Do not check any
74      * more plugin filter or transform functions */
75     SKPLUGIN_FILTER_IGNORE,
76 
77     /** all is not well */
78     SKPLUGIN_ERR,
79 
80     /** serious corruption possible, abort now */
81     SKPLUGIN_ERR_FATAL,
82 
83     /** plugin could not be loaded due to system errors */
84     SKPLUGIN_ERR_SYSTEM,
85 
86     /** plugin did not register options because app did not support the
87      * function mask  */
88     SKPLUGIN_ERR_DID_NOT_REGISTER,
89 
90     /** version of library is too new for plugin */
91     SKPLUGIN_ERR_VERSION_TOO_NEW
92 
93 } skplugin_err_t;
94 
95 
96 /**
97  *    Types of command-line switches (NO_ARG, REQUIRED_ARG,
98  *    OPTIONAL_ARG, from utils.h
99  */
100 typedef int skplugin_arg_mode_t;
101 
102 
103 /**
104  *    The plugin interface uses a common API regardless of the type of
105  *    application.  The following bitfields specify functionality that an
106  *    application requires from its plugins.  Plugins can use these
107  *    bitfields when registering options.
108  */
109 typedef int skplugin_fn_mask_t;
110 
111 #define SKPLUGIN_FN_ANY             (0)
112 #define SKPLUGIN_FN_REC_TO_BIN      (1)
113 #define SKPLUGIN_FN_ADD_REC_TO_BIN  (1 << 1)
114 #define SKPLUGIN_FN_BIN_TO_TEXT     (1 << 2)
115 #define SKPLUGIN_FN_REC_TO_TEXT     (1 << 3)
116 #define SKPLUGIN_FN_MERGE           (1 << 4)
117 #define SKPLUGIN_FN_COMPARE         (1 << 5)
118 #define SKPLUGIN_FN_INITIAL         (1 << 6)
119 #define SKPLUGIN_FN_FILTER          (1 << 7)
120 #define SKPLUGIN_FN_TRANSFORM       (1 << 8)
121 #define SKPLUGIN_FN_BIN_BYTES       (1 << 9)
122 #define SKPLUGIN_FN_COLUMN_WIDTH    (1 << 10)
123 
124 /* Plugin required fields for particular apps */
125 #define SKPLUGIN_APP_CUT            SKPLUGIN_FN_REC_TO_TEXT
126 #define SKPLUGIN_APP_SORT           SKPLUGIN_FN_REC_TO_BIN
127 #define SKPLUGIN_APP_GROUP          SKPLUGIN_FN_REC_TO_BIN
128 #define SKPLUGIN_APP_UNIQ_FIELD     (SKPLUGIN_FN_REC_TO_BIN     \
129                                      | SKPLUGIN_FN_BIN_TO_TEXT)
130 #define SKPLUGIN_APP_UNIQ_VALUE     (SKPLUGIN_FN_ADD_REC_TO_BIN \
131                                      | SKPLUGIN_FN_BIN_TO_TEXT  \
132                                      | SKPLUGIN_FN_MERGE)
133 #define SKPLUGIN_APP_STATS_FIELD    (SKPLUGIN_FN_REC_TO_BIN     \
134                                      | SKPLUGIN_FN_BIN_TO_TEXT)
135 #define SKPLUGIN_APP_STATS_VALUE    (SKPLUGIN_FN_ADD_REC_TO_BIN \
136                                      | SKPLUGIN_FN_BIN_TO_TEXT  \
137                                      | SKPLUGIN_FN_MERGE        \
138                                      | SKPLUGIN_FN_COMPARE)
139 #define SKPLUGIN_APP_FILTER         SKPLUGIN_FN_FILTER
140 #define SKPLUGIN_APP_TRANSFORM      SKPLUGIN_FN_TRANSFORM
141 
142 /** filter identifier */
143 struct skp_filter_st;
144 typedef struct skp_filter_st skplugin_filter_t;
145 
146 /** transformer identifier */
147 struct skp_transform_st;
148 typedef struct skp_transform_st skplugin_transform_t;
149 
150 /** field identifier */
151 struct skp_field_st;
152 typedef struct skp_field_st skplugin_field_t;
153 
154 
155 /********************************************************************
156  *
157  *    PLUG-IN INTERFACE
158  *
159  ********************************************************************
160  *
161  *    The following defines, typedefs, and functions are meant to be
162  *    used/called by the plugin code.
163  *
164  ********************************************************************/
165 
166 /*******************************/
167 /*** Plugin entry point type ***/
168 /*******************************/
169 
170 /**
171  *    The name of the "entry port" function that plugins export.
172  *
173  *    The "entry point" of the plugin is the single function the
174  *    plugin must define and export, and which is found by dlsym(3).
175  *    All other functions and global variables in the plugin should be
176  *    static, unless the plugin consists of more than one file.
177  */
178 #define SKPLUGIN_SETUP_FN skplugin_init
179 #define TO_STR(a) _TO_STR(a)
180 #define _TO_STR(a) #a
181 #define SKPLUGIN_SETUP_FN_NAME TO_STR(SKPLUGIN_SETUP_FN)
182 
183 /**
184  *    Function prototype for the setup function that plugins export.
185  *    'data' is an opaque type determined by the value 'version'.  In
186  *    the current version (1.0), the 'data' is not used, and NULL will
187  *    be passed as the 'data' argument.
188  */
189 skplugin_err_t
190 SKPLUGIN_SETUP_FN(
191     uint16_t            major_version,
192     uint16_t            minor_version,
193     void               *data);
194 
195 /**
196  *     Compares the version number of the plugin api supported by the
197  *     plugin with the version reported by the application.  If
198  *     sk_msg_fn_t is non-null, will print version mismatches via the
199  *     error function.  Returns SKPLUGIN_OK if the versions "match",
200  *     or a value that can be returned from the setup function (either
201  *     SKPLUGIN_ERR or SKPLUGIN_ERR_VERSION_TOO_NEW).
202  */
203 skplugin_err_t
204 skpinSimpleCheckVersion(
205     uint16_t            protocol_major,
206     uint16_t            protocol_minor,
207     uint16_t            plugin_major,
208     uint16_t            plugin_minor,
209     sk_msg_fn_t         errfn);
210 
211 
212 /*** SIMPLE FIELD REGISTRATION FUNCTIONS ***/
213 
214 /*****************************************************************/
215 /*** Callback function types for simple registration functions ***/
216 /*****************************************************************/
217 
218 /**
219  *    Integer-based field callback.  Given an rwRec, should return an
220  *    unsigned integer to associate with that record.  Used in
221  *    skpinRegIntField, skpinRegTextField, skpinRegStringListField,
222  *    skpinRegIntAggregator, skpinRegIntSumAggregator,
223  *    skpinRegIntMinAggregator, and skpinRegIntMaxAggregator.
224  */
225 typedef uint64_t
226 (*skplugin_int_field_fn_t)(
227     const rwRec        *rec);
228 
229 /**
230  *    IPv4 address field callback.  Given an rwRec, should return an
231  *    IPv4 address as a uint32_t (in host byte order) to associate
232  *    with that record.  Used in skpinRegIPv4Field.
233  */
234 typedef uint32_t
235 (*skplugin_ipv4_field_fn_t)(
236     const rwRec        *rec);
237 
238 /**
239  *    IP address field callback.  Given an rwRec, should fill in the
240  *    given skipaddr_t with an IP address to associate with that
241  *    record.  Used in skpinRegIPAddressField.
242  */
243 typedef void
244 (*skplugin_ip_field_fn_t)(
245     skipaddr_t         *dest,
246     const rwRec        *rec);
247 
248 /**
249  *    Text field callback.  Converts a uint64_t value to a text value
250  *    in 'dest'.  The size of the 'dest' buffer is given by 'width'.
251  *    The text value must be null-terminated.  Used in
252  *    skpinRegTextField.
253  */
254 typedef void
255 (*skplugin_text_field_fn_t)(
256     char               *dest,
257     size_t              width,
258     uint64_t            val);
259 
260 /**
261  *    Integer aggregation function callback.  Given a 'current' value,
262  *    "adds" or "merges" the 'operand', and returns the new value.
263  *    Used in skpinRegIntAggregator.
264  */
265 typedef uint64_t
266 (*skplugin_int_agg_fn_t)(
267     uint64_t            current,
268     uint64_t            operand);
269 
270 
271 /*******************************************/
272 /*** Simple field registration functions ***/
273 /*******************************************/
274 
275 /**
276  *   Registers a field whose value is an integer.
277  *
278  *   The field's name (and title) will be 'name'.  'min' is the
279  *   minimum integer value for the field.  'max' is the maximum value
280  *   of the field.  If 'max' is set to 0, 'max' is defaulted to
281  *   UINT64_MAX.  'rec_to_int' is a function that takes an rwRec, and
282  *   returns the integer associated with it.  'width' is the column
283  *   width of the field to use when printing the value.  If 'width' is
284  *   set to 0, 'width' is defaulted to the textual width of 'max'.
285  */
286 skplugin_err_t
287 skpinRegIntField(
288     const char                 *name,
289     uint64_t                    min,
290     uint64_t                    max,
291     skplugin_int_field_fn_t     rec_to_int,
292     size_t                      width);
293 
294 /**
295  *   Registers a field whose value is an IPv4 address.
296  *
297  *   The field's name (and title) will be 'name'.  'rec_to_ipv4' is a
298  *   function that takes an rwRec, and returns the IPv4 address
299  *   associated with it as a uint32_t in host byte order.  'width' is
300  *   the column width of the field to use when printing the value.  If
301  *   'width' is set to 0, 'width' is defaulted to 15.
302  */
303 skplugin_err_t
304 skpinRegIPv4Field(
305     const char                 *name,
306     skplugin_ipv4_field_fn_t    rec_to_ipv4,
307     size_t                      width);
308 
309 /**
310  *   Registers a field whose value is an IP address.
311  *
312  *   The field's name (and title) will be 'name'.  'rec_to_ipaddr' is
313  *   a function that takes an rwRec, and fills in an IP address
314  *   associated with it as a skipaddr_t.  'width' is the column width
315  *   of the field to use when printing the value.  If 'width' is set
316  *   to 0, 'width' is defaulted to 39 (15 if not SiLK is not compiled
317  *   with IPv6 support.
318  */
319 skplugin_err_t
320 skpinRegIPAddressField(
321     const char             *name,
322     skplugin_ip_field_fn_t  rec_to_ipaddr,
323     size_t                  width);
324 
325 /**
326  *   Registers a field whose value is text.
327  *
328  *   The field's name (and title) will be 'name'.  The field's text
329  *   value is based on an intermediate integer value.  'min' is the
330  *   minimum integer value for the field.  'max' is the maximum value
331  *   of the field.  If 'max' is set to 0, 'max' is defaulted to
332  *   UINT64_MAX.  'value_fn' is a function that takes an rwRec, and
333  *   returns the integer associated with it.  'text_fn' is a function
334  *   that takes a buffer, width, and integer, and fills the buffer
335  *   with the text value associated with that integer, where the width
336  *   is the size of the buffer.  'width' is the column width of the
337  *   field to use when printing the value.
338  */
339 skplugin_err_t
340 skpinRegTextField(
341     const char                 *name,
342     uint64_t                    min,
343     uint64_t                    max,
344     skplugin_int_field_fn_t     value_fn,
345     skplugin_text_field_fn_t    text_fn,
346     size_t                      width);
347 
348 /**
349  *   Registers a field whose value is one of a list of strings.
350  *
351  *   The field's name (and title) will be 'name'.  'list' is a static
352  *   list of strings.  The list should either be NULL-terminated, or
353  *   'entries' should have a non-zero value.  'entries' should be the
354  *   number of entries in 'list'.  If 'entries' is zero, the list is
355  *   assumed to be NULL-terminated.  'rec_to_index' is a function that
356  *   takes an rwRec, and returns an index into 'list'.  If the index
357  *   value is greater than the number of entries in 'list',
358  *   'default_value' will be used instead.  'default_value' may be
359  *   NULL.  'width' is the column width of the field to use when
360  *   printing the value.  If 'width' is set to 0, 'width' is defaulted
361  *   to the width of the largest string in 'list' and 'default_value'.
362  */
363 skplugin_err_t
364 skpinRegStringListField(
365     const char                 *name,
366     const char                **list,
367     size_t                      entries,
368     const char                 *default_value,
369     skplugin_int_field_fn_t     rec_to_index,
370     size_t                      width);
371 
372 /**
373  *   Registers an aggregate value field that maintains a running
374  *   unsigned integer sum.
375  *
376  *   The field's name (and title) will be 'name'.  The maximum value
377  *   of the field is 'max'.  If 'max' is zero, the maximum value is
378  *   assumed to be UINT64_MAX.  'rec_to_int' is a function that takes
379  *   an rwRec, and returns an integer value associated with that
380  *   record.  'width' is the column width of the field to use when
381  *   printing the value.  If 'width' is set to 0, 'width' is defaulted
382  *   to the textual width of 'max'.
383  */
384 skplugin_err_t
385 skpinRegIntSumAggregator(
386     const char                 *name,
387     uint64_t                    max,
388     skplugin_int_field_fn_t     rec_to_int,
389     size_t                      width);
390 
391 /**
392  *   Registers an aggregate value field that keeps track of a minimum
393  *   unsigned integer value.
394  *
395  *   The field's name (and title) will be 'name'.  The maximum value
396  *   of the field is 'max'.  If 'max' is zero, the maximum value is
397  *   assumed to be UINT64_MAX.  'rec_to_int' is a function that takes
398  *   an rwRec, and returns an integer value associated with that
399  *   record.  'width' is the column width of the field to use when
400  *   printing the value.  If 'width' is set to 0, 'width' is defaulted
401  *   to the textual width of 'max'.
402  */
403 skplugin_err_t
404 skpinRegIntMinAggregator(
405     const char                 *name,
406     uint64_t                    max,
407     skplugin_int_field_fn_t     rec_to_int,
408     size_t                      width);
409 
410 /**
411  *   Registers an aggregate value field that keeps track of a maximum
412  *   unsigned integer value.
413  *
414  *   The field's name (and title) will be 'name'.  The maximum value
415  *   of the field is 'max'.  If 'max' is zero, the maximum value is
416  *   assumed to be UINT64_MAX.  'rec_to_int' is a function that takes
417  *   an rwRec, and returns an integer value associated with that
418  *   record.  'width' is the column width of the field to use when
419  *   printing the value.  If 'width' is set to 0, 'width' is defaulted
420  *   to the textual width of 'max'.
421  */
422 skplugin_err_t
423 skpinRegIntMaxAggregator(
424     const char                 *name,
425     uint64_t                    max,
426     skplugin_int_field_fn_t     rec_to_int,
427     size_t                      width);
428 
429 /**
430  *   Registers an unsigned integer aggregate value field.
431  *
432  *   The field's name (and title) will be 'name'.  The maximum value
433  *   of the field is 'max'.  If 'max' is zero, the maximum value is
434  *   assumed to be UINT64_MAX.  'rec_to_int' is a function that takes
435  *   an rwRec, and returns an integer value associated with that
436  *   record.  'agg' is the aggregation function, which takes the
437  *   current value of the field and a value returned by 'rec_to_int',
438  *   and returns the new value of the field.  'initial' should be the
439  *   initial value of the field.  'width' is the column width of the
440  *   field to use when printing the value.  If 'width' is set to 0,
441  *   'width' is defaulted to the textual width of 'max'.
442  */
443 skplugin_err_t
444 skpinRegIntAggregator(
445     const char                 *name,
446     uint64_t                    max,
447     skplugin_int_field_fn_t     rec_to_int,
448     skplugin_int_agg_fn_t       agg,
449     uint64_t                    initial,
450     size_t                      width);
451 
452 
453 /*** LOW LEVEL PLUGIN FUNCTIONALITY ***/
454 
455 /*******************************************/
456 /*** Callback function types for plugins ***/
457 /*******************************************/
458 
459 /**
460  * In all the following function prototypes, 'cbdata' is callback data
461  * provided by the plugin at callback registration time.  'extra' are
462  * extra arguments as defined in Extra Arguments above.
463  */
464 
465 /**
466  *    Type defininition for non-function-specific plugin cleanup
467  *    functions.  Registered by skpinRegCleanup().  Called by
468  *    skPluginRunCleanup().
469  */
470 typedef void
471 (*skplugin_cleanup_fn_t)(
472     void);
473 
474 
475 /**
476  *    Argument processing callback: Called to process a plugin
477  *    command-line argument (switch).  Registered by
478  *    skpinRegOption2().
479  *
480  *    In cases where the plugin is only active when a command line
481  *    argument is present, part of this function's duties will be to
482  *    call skpinRegFilter() or skpinRegTransformer().
483  */
484 typedef skplugin_err_t
485 (*skplugin_option_fn_t)(
486     const char         *opt_arg,
487     void               *opt_cbdata);
488 
489 
490 /**
491  *    Option help callback.  Meant to output option help to the given
492  *    file handle.  Registered by skpinRegOption2().  Called by
493  *    skPluginOptionsUsage().
494  *
495  *    There are two fields of interest in the struct option structure:
496  *    'name' contains the 'option_name' used when the function was
497  *    registered, and 'has_arg' contains the 'mode' that was used.
498  */
499 typedef void
500 (*skplugin_help_fn_t)(
501     FILE                   *fh,
502     const struct option    *option,
503     void                   *opt_cbdata);
504 
505 
506 /**
507  *    Basic callback: used for any startup/shutdown code.  Called by
508  *    skPluginRunInititialize() or skPluginRunCleanup().
509  *
510  *    skplugin_callbacks_t.init
511  *    skplugin_callbacks_t.cleanup
512  */
513 typedef skplugin_err_t
514 (*skplugin_callback_fn_t)(
515     void               *cbdata);
516 
517 /**
518  *    Filter callback to filter a record 'rec'.  If the function
519  *    returns SKPLUGIN_FILTER_PASS, the record is accepted.  If it
520  *    returns SKPLUGIN_FILTER_FAIL, it is rejected.  Registered by
521  *    skpinRegFilter().  Called by skPluginRunFilterFn()
522  *
523  *    skplugin_callbacks_t.filter
524  */
525 typedef skplugin_err_t
526 (*skplugin_filter_fn_t)(
527     const rwRec        *rec,
528     void               *cbdata,
529     void              **extra);
530 
531 /**
532  *    Transform callback.  Modifies 'rec' in place.  Registered by
533  *    skpinRegTransformer().  Called by skPluginRunTransformFn()
534  *
535  *    skplugin_callbacks_t.transform
536  */
537 typedef skplugin_err_t
538 (*skplugin_transform_fn_t)(
539     rwRec              *rec,
540     void               *cbdata,
541     void              **extra);
542 
543 /**
544  *    Record to text callback.  Fills in 'dest' given 'rec'.  The
545  *    function should write no more than 'width' characters into
546  *    'dest'.  The value should be NUL-terminated.  Registered by
547  *    skpinRegField().  Called by skPluginFieldRunRecToTextFn().
548  *
549  *    skplugin_callbacks_t.rec_to_text
550  */
551 typedef skplugin_err_t
552 (*skplugin_text_fn_t)(
553     const rwRec        *rec,
554     char               *dest,
555     size_t              width,
556     void               *cbdata,
557     void              **extra);
558 
559 /**
560  *    Record to binary callback.  Fills in 'dest' given 'rec'.
561  *    Registered by skpinRegField().  When used in an aggregate
562  *    definition, 'dest' is presumed to contain the current binary
563  *    value, which should be modified or replaced by the function.
564  *    The function may assume that the 'dest' is large enough to hold
565  *    'field_bin_width' bytes.
566  *
567  *    skplugin_callbacks_t.rec_to_bin
568  *    skplugin_callbacks_t.add_rec_to_bin
569  */
570 typedef skplugin_err_t
571 (*skplugin_bin_fn_t)(
572     const rwRec        *rec,
573     uint8_t            *dest,
574     void               *cbdata,
575     void              **extra);
576 
577 /**
578  *    Binary to text callback.  Just like record to text callback, but
579  *    converts data from a binary value (as produced by a
580  *    skplugin_bin_fn_t) to text.
581  *
582  *    skplugin_callbacks_t.bin_to_text
583  */
584 typedef skplugin_err_t
585 (*skplugin_bin_to_text_fn_t)(
586     const uint8_t      *bin,
587     char               *dest,
588     size_t              width,
589     void               *cbdata);
590 
591 /**
592  *    Binary value merge callback.  This function takes two binary
593  *    values (as produced by a skplugin_bin_fn_t) in dest and src and
594  *    merges them into dest.
595  *
596  *    skplugin_callbacks_t.bin_merge
597  */
598 typedef skplugin_err_t
599 (*skplugin_bin_merge_fn_t)(
600     uint8_t            *dest,
601     const uint8_t      *src,
602     void               *cbdata);
603 
604 /**
605  *    Binary value comparison function.  Compares two binary values
606  *    (as produced by a skplugin_bin_fn_t) in value_a and value_b and
607  *    places a integer less than, equal to, or greater than zero in
608  *    cmp depending on whether value_a is less than, equal, or greater
609  *    than value_b.
610  *
611  *    skplugin_callbacks_t.bin_compare
612  */
613 typedef skplugin_err_t
614 (*skplugin_bin_cmp_fn_t)(
615     int                *cmp,
616     const uint8_t      *value_a,
617     const uint8_t      *value_b,
618     void               *cbdata);
619 
620 
621 /******************************************/
622 /*** Struct for registration functions  ***/
623 /******************************************/
624 
625 /**
626  *    skplugin_callbacks_t is used as the 'regdata' argument to the
627  *    skpinRegFilter(), skpinRegTransformer(), and skpinRegField()
628  *    functions.  Its members are described in detail in the
629  *    description of those functions.
630  */
631 struct skplugin_callbacks_st {
632     skplugin_callback_fn_t     init;
633     skplugin_callback_fn_t     cleanup;
634     size_t                     column_width;
635     size_t                     bin_bytes;
636     skplugin_text_fn_t         rec_to_text;
637     skplugin_bin_fn_t          rec_to_bin;
638     skplugin_bin_fn_t          add_rec_to_bin;
639     skplugin_bin_to_text_fn_t  bin_to_text;
640     skplugin_bin_merge_fn_t    bin_merge;
641     skplugin_bin_cmp_fn_t      bin_compare;
642     skplugin_filter_fn_t       filter;
643     skplugin_transform_fn_t    transform;
644     const uint8_t             *initial;
645     const char               **extra;
646 };
647 typedef struct skplugin_callbacks_st skplugin_callbacks_t;
648 
649 
650 /************************/
651 /*** Plugin functions ***/
652 /************************/
653 
654 /* This set of functions are meant to be called by the plugins
655  * themselves. */
656 
657 
658 /**
659  *    The following function registers an option (switch) for
660  *    command-line processing.
661  *
662  *    'option_name' is the command line switch to create.
663  *
664  *    'mode' determines whether the switch takes an argument.  It
665  *    should be one of NO_ARG, OPTIONAL_ARG, or REQUIRED_ARG.
666  *
667  *    'option_help' is the usage string to print when the user
668  *    requests --help.  This will be used if 'option_help_fn' is NULL.
669  *    This argument may be NULL.
670  *
671  *    'option_help_fn' is a function which optionally prints a help
672  *    message for the option.  This argument may be NULL.
673  *
674  *    'opt' is a callback function.  'opt(opt_arg, cbdata)' will be
675  *    called back when the 'option_name' is seen as an option.  If no
676  *    argument is given to the switch, 'opt_arg' will be NULL.
677  *
678  *    'opt_cbdata' will be passed back unchanged to the plugin as a
679  *    parameter in the 'opt' and 'option_help_fn' callback functions.
680  *
681  *    'num_entries' is the number of function type combinations that
682  *    will be supplied after the 'num_entries' argument.
683  *
684  *    Each of the entries after num_entries should be an function
685  *    combination of type skplugin_fn_mask_t.  As long as the
686  *    application supports one of the function combinations in this
687  *    list, the registration should succeed.
688  *
689  *    If the application does not support any of the function
690  *    combinations, this function will return
691  *    SKPLUGIN_ERR_DID_NOT_REGISTER.
692  */
693 skplugin_err_t
694 skpinRegOption2(
695     const char             *option_name,
696     skplugin_arg_mode_t     mode,
697     const char             *option_help,
698     skplugin_help_fn_t      option_help_fn,
699     skplugin_option_fn_t    opt,
700     void                   *opt_cbdata,
701     int                     num_entries,
702     ...);
703 
704 /**
705  *  DEPRECATED.  Replace with
706  *
707  *    skpinRegOption2(option_name, mode, option_help, NULL, opt, data,
708  *                    1, fn_mask);
709  *
710  *    To be removed in SiLK 4.
711  */
712 skplugin_err_t
713 skpinRegOption(
714     skplugin_fn_mask_t      fn_mask,
715     const char             *option_name,
716     skplugin_arg_mode_t     mode,
717     const char             *option_help,
718     skplugin_option_fn_t    opt,
719     void                   *opt_cbdata);
720 
721 /**
722  *  DEPRECATED.  Replace with
723  *
724  *    skpinRegOption2(option_name, mode, NULL, option_help_fn, opt, data,
725  *                    1, fn_mask);
726  *
727  *    To be removed in SiLK 4.
728  */
729 skplugin_err_t
730 skpinRegOptionWithHelpFn(
731     skplugin_fn_mask_t      fn_mask,
732     const char             *option_name,
733     skplugin_arg_mode_t     mode,
734     skplugin_help_fn_t      option_help_fn,
735     skplugin_option_fn_t    opt,
736     void                   *opt_cbdata);
737 
738 
739 /**
740  *    Register a new filter predicate to pass or fail records.
741  *
742  *    Registering a filter predicate in an application that does not
743  *    support filtering results in skpinRegFilter() setting
744  *    'return_filter', if provided, to NULL and returning SKPLUGIN_OK.
745  *
746  *    If 'return_filter' is not NULL, the function will set it to the
747  *    newly created filter.
748  *
749  *    'cbdata' will be passed back unchanged to the plugin as a
750  *    parameter in the various callback functions.
751  *
752  *    'regdata' is a struct of type skplugin_callbacks_t, which should
753  *    be filled out as follows:
754  *
755  *      'init(cbdata)' is called for all registered filter predicates.
756  *      It is called after argument processing and before processing
757  *      of records.  It may be NULL.
758  *
759  *      'filter(record, cbdata)' is called for each record.  If
760  *      'filter()' returns SKPLUGIN_FILTER_PASS, the record is
761  *      accepted; if it returns SKPLUGIN_FILTER_FAIL, the record is
762  *      rejected.
763  *
764  *      'cleanup(cbdata)' is called after all records have been
765  *      processed.  It may be NULL.
766  *
767  *    If 'regdata' or the 'filter' member of 'regdata' is NULL,
768  *    skpinRegFilter() sets 'return_filter', if provided, to NULL and
769  *    returns SKPLUGIN_ERR.
770  */
771 skplugin_err_t
772 skpinRegFilter(
773     skplugin_filter_t             **return_filter,
774     const skplugin_callbacks_t     *regdata,
775     void                           *cbdata);
776 
777 
778 /**
779  *    Register a new transformer function to apply to all records.
780  *
781  *    Registering a transformer function in an application that does
782  *    not support transforms results in skpinRegTransformer() setting
783  *    'return_transformer', if provided, to NULL and returning
784  *    SKPLUGIN_OK.
785  *
786  *    If 'return_transformer' is not NULL, the function will set it to
787  *    the newly created transformer.
788  *
789  *    'cbdata' will be passed back unchanged to the plugin as a
790  *    parameter in the various callback functions.
791  *
792  *    'regdata' is a struct of type skplugin_callbacks_t, which should
793  *    be filled out as follows:
794  *
795  *      'init(cbdata)' is called for all registered transformers.  It
796  *      is called after argument processing and before processing of
797  *      records.  It may be NULL.
798  *
799  *      'transform(rec, cbdata)' is called for each record.  Any
800  *      changes made by 'transform()' are seen by the application.
801  *
802  *      'cleanup(cbdata)' is called after all records have been
803  *      processed.  It may be NULL.
804  *
805  *    If 'regdata' or the 'transform' member of 'regdata' is NULL,
806  *    skpinRegTransformer() sets 'return_transformer', if provided, to
807  *    NULL and returns SKPLUGIN_ERR.
808  */
809 skplugin_err_t
810 skpinRegTransformer(
811     skplugin_transform_t          **return_transformer,
812     const skplugin_callbacks_t     *regdata,
813     void                           *cbdata);
814 
815 
816 /**
817  *    Register a new derived field for record processing.
818  *
819  *    Registering a field in an application that does not work in terms
820  *    of fields results in skpinRegField() setting 'return_field', if
821  *    provided, to NULL and returning SKPLUGIN_OK.
822  *
823  *    'return_field' is a handle to the newly created field.  (Can be
824  *    NULL.)
825  *
826  *    'name' is the string that is the primary name of the field, and
827  *    by default will be the value returned by skPluginFieldTitle() to
828  *    the application.
829  *
830  *    'description' is a textual description of the field.  If
831  *    provided, it will be returned by skPluginFieldDescription().
832  *
833  *    'regdata' is a struct of type skplugin_callbacks_t, which should
834  *    be filled out as follows:
835  *
836  *      'column_width' is the number of characters (not including
837  *      trailing NUL) required to hold a string representation of the
838  *      longest value of the field.  This value can be zero if not
839  *      used, or if it will be set later using skpinSetFieldWidths().
840  *
841  *      'bin_bytes' is the number of bytes required to hold a binary
842  *      representation of a value of the field.  This value can be
843  *      zero if not used, or if it will be set later using
844  *      skpinSetFieldWidths().
845  *
846  *      The application will call 'init(cbdata)' when the application
847  *      has decided this field will be used, before processing data.
848  *      It may be NULL.
849  *
850  *      'cleanup(cbdata)' is called after all records have been
851  *      processed.  It may be NULL.
852  *
853  *      'rec_to_text' is a callback function of type
854  *      skplugin_text_fn_t.  'rec_to_text(rec, dst, width, cbdata)' is
855  *      called to fetch the textual value for a field given the SiLK
856  *      Flow record 'rec'.  'rec_to_text()' should write no more than
857  *      'column_width' bytes into 'dst'.  The parameter 'width'
858  *      specifies the size of 'dst', which may be equal to
859  *      'column_width'.
860  *
861  *      'rec_to_bin' is a callback function of type skplugin_bin_fn_t.
862  *      'rec_to_bin(rec, dst, cbdata)' is called to fetch the binary
863  *      value for this field given the SiLK Flow record 'rec'.
864  *      'rec_to_bin' should write exactly 'bin_bytes' bytes into
865  *      'dst'.  If an application requires a rec-to-binary function
866  *      but 'rec_to_bin' is NULL and 'rec_to_text' is present,
867  *      'rec_to_text' will be used instead, and 'column_width' will be
868  *      used as the width for binary values (zeroing out the
869  *      destination area before it is written to).
870  *
871  *      'add_rec_to_bin' is a callback function of type
872  *      skplugin_bin_fn_t.  'rec_to_bin(rec, dst, cbdata)' is called
873  *      to add to the binary value in 'dst' based on the SiLK Flow
874  *      record given in 'rec'.  'rec_to_bin' should write exactly
875  *      'bin_bytes' bytes into 'dst'.  This function is only used for
876  *      aggregate value fields.
877  *
878  *      'bin_to_text(bin, dst, width, cbdata)' is called to get a
879  *      textual representation of the value in 'bin', where 'bin' was
880  *      set by a call to 'rec_to_bin' or 'add_rec_to_bin'.  The
881  *      'bin_to_text' callback should write no more than 'width'
882  *      characters into 'dst'.
883  *
884  *      'bin_merge(dst, src, cbdata)' is called to merge (or add) the
885  *      binary aggregate values of 'src' and 'dst' into 'dst'.
886  *      Whereas 'add_rec_to_bin' combines a Flow record's field's
887  *      value and a bin, 'bin_merge' combines the values of two bins.
888  *
889  *      'bin_compare(val, a, b, cbdata)' is called to compare the
890  *      binary aggregate values 'a' and 'b'.  It must set 'val' to an
891  *      integer indicating whether 'a' is less than, equal to, or
892  *      greater than 'b'.  If this function is NULL, memcmp() will be
893  *      used on the binary values instead.
894  *
895  *      'initial' represents the inital value of the binary aggregate
896  *      value.  It should contain be exactly 'bin_bytes' bytes.  If
897  *      not given, the field will be initialzed to all NULs.
898  *
899  *      'extra' is a NULL-terminated constant array of strings
900  *      representing "extra arguments".  Read the EXTRA ARGUMENTS
901  *      section for information on these arguments.  It may be NULL.
902  *
903  *    NOTE: When sorting, the binary values provided by 'rec_to_bin()
904  *    will be sorted using memcmp().  If the plugin wants to enforce a
905  *    specific ordering, it should be sure to produce values that will
906  *    sort correctly.
907  *
908  *    If 'name' or 'regdata' is NULL, skpinRegField() sets
909  *    'return_field', if provided, to NULL and returns SKPLUGIN_ERR.
910  */
911 skplugin_err_t
912 skpinRegField(
913     skplugin_field_t              **return_field,
914     const char                     *name,
915     const char                     *description,
916     const skplugin_callbacks_t     *regdata,
917     void                           *cbdata);
918 
919 /**
920  *    Set the textual and binary widths for a field.  Meant to be used
921  *    within an 'init' function.
922  */
923 skplugin_err_t
924 skpinSetFieldWidths(
925     skplugin_field_t   *field,
926     size_t              field_width_text,
927     size_t              field_width_bin);
928 
929 /**
930  *    Adds an alias (name) for a field.  Returns SKPLUGIN_ERR if the
931  *    name already exists, SKPLUGIN_OK otherwise.
932  */
933 skplugin_err_t
934 skpinAddFieldAlias(
935     skplugin_field_t   *field,
936     const char         *alias);
937 
938 /**
939  *    Sets the title for a field.
940  */
941 skplugin_err_t
942 skpinSetFieldTitle(
943     skplugin_field_t   *field,
944     const char         *title);
945 
946 /**
947  *    Register a cleanup function for the plugin.  This will be called
948  *    by skPluginRunCleanup() after all the function-specific cleanups
949  *    are called.
950  */
951 skplugin_err_t
952 skpinRegCleanup(
953     skplugin_cleanup_fn_t   cleanup);
954 
955 
956 /**
957  *    Declare that this plugin is not thread safe.  This function
958  *    should only be called when the plugin is active; otherwise the
959  *    mere presence of the plug-in will prevent rwfilter from running
960  *    with multiple threads.
961  */
962 void
963 skpinSetThreadNonSafe(
964     void);
965 
966 
967 /**
968  *      Create an skstream_t object using the specified 'content_type'
969  *      and 'filename', open it, and fill the location pointed to by
970  *      'stream' with the object.  If the application has called
971  *      skPluginSetOpenInputFunction(), that function will be used if
972  *      it is non-null.
973  *  Inputs:
974  *      location in which to return address of skstream_t object
975  *      content_type of the filename
976  *      name of file to open
977  *  Outputs:
978  *      Returns 0 if stream was successfully opened and should be
979  *      used.  Returns -1 on error.  Returns 1 if the plug-in should
980  *      ignore the file.
981  *  Side Effects:
982  *      'stream' is filled with address of skstream_t object.
983  */
984 int
985 skpinOpenDataInputStream(
986     skstream_t        **stream,
987     skcontent_t         content_type,
988     const char         *filename);
989 
990 
991 
992 /********************************************************************
993  *
994  *    APPLICATION INTERFACE
995  *
996  ********************************************************************
997  *
998  *    The following defines, typedefs, and functions are meant to be
999  *    used/called by the application code which is loading and using
1000  *    plugins.
1001  *
1002  ********************************************************************/
1003 
1004 
1005 /**
1006  *    Version check result type
1007  */
1008 typedef enum {
1009     SKPLUGIN_VERSION_OK,
1010     SKPLUGIN_VERSION_OLD,
1011     SKPLUGIN_VERSION_TOO_NEW
1012 } skplugin_version_result_t;
1013 
1014 
1015 /**
1016  *  SK_PLUGIN_ADD_SUFFIX(name)
1017  *
1018  *    Adds the appropriate suffix to 'name' to get the file name that
1019  *    skplugin should attempt to dlopen().  'name' should be a string;
1020  *    we rely on CPP concatenation to add the suffix.
1021  */
1022 #define SK_PLUGIN_ADD_SUFFIX(file_basename) (file_basename SK_PLUGIN_SUFFIX)
1023 
1024 /**
1025  *   The current major version of the skplugin interface.
1026  */
1027 #define SKPLUGIN_INTERFACE_VERSION_MAJOR 1
1028 
1029 /**
1030  *   The current minor version of the skplugin interface.
1031  */
1032 #define SKPLUGIN_INTERFACE_VERSION_MINOR 0
1033 
1034 /**
1035  *    Name of envar that if set will enable debugging output
1036  */
1037 #define SKPLUGIN_DEBUG_ENVAR "SILK_PLUGIN_DEBUG"
1038 
1039 /**
1040  *   Version number check
1041  */
1042 #define SKPLUGIN_VERSION_CHECK(protocol_major, protocol_minor,          \
1043                                plugin_major, plugin_minor)              \
1044     ((plugin_major < protocol_major) ? SKPLUGIN_VERSION_TOO_NEW :       \
1045      ((plugin_major > protocol_major) ? SKPLUGIN_VERSION_OLD :          \
1046       ((plugin_minor > protocol_minor) ? SKPLUGIN_VERSION_OLD :         \
1047        SKPLUGIN_VERSION_OK)))
1048 
1049 /**
1050  *    field iterator
1051  */
1052 typedef struct skplugin_field_iter_st {
1053     sk_dll_iter_t      list_iter;
1054     skplugin_fn_mask_t fn_mask;
1055     unsigned           all_fields : 1;
1056 } skplugin_field_iter_t;
1057 
1058 
1059 /**
1060  *    Type signature of the function that skpinOpenDataInputStream()
1061  *    will call.
1062  */
1063 typedef int (*open_data_input_fn_t)(
1064     skstream_t        **stream,
1065     skcontent_t         content_type,
1066     const char         *filename);
1067 
1068 /**
1069  *    The type of the setup function that plugins export.  'pi_data'
1070  *    is an opaque type determined by the values 'major_version' and
1071  *    'minor_version'.  In the current version (1), the 'pi_data' is
1072  *    not used, and NULL will be passed as the 'pi_data' argument.
1073  */
1074 typedef skplugin_err_t (*skplugin_setup_fn_t)(
1075     uint16_t  major_version,
1076     uint16_t  minor_version,
1077     void     *pi_data);
1078 
1079 
1080 /**
1081  *    This is used to initialize the skplugin library.  'num_entries'
1082  *    is the number of function masks that will be passed to this
1083  *    function.  Each function mask should indicate a type of
1084  *    plugin functionality the application wants.
1085  */
1086 void
1087 skPluginSetup(
1088     int                 num_entries,
1089     ...);
1090 
1091 /**
1092  *    Unloads all plugins and frees all plugin data.  Does not call
1093  *    the 'cleanup' functions that the plugins have registered.  The
1094  *    'cleanup' functions are called by skPluginRunCleanup().
1095  */
1096 void
1097 skPluginTeardown(
1098     void);
1099 
1100 /**
1101  *    Loads the plugin represented by the filename 'name'.  If
1102  *    complain_on_error is non-zero, error messages will be written to
1103  *    the error stream.
1104  */
1105 skplugin_err_t
1106 skPluginLoadPlugin(
1107     const char         *name,
1108     int                 complain_on_error);
1109 
1110 /**
1111  *    Uses 'setup_fn' as a plugin entry point, and treats the result
1112  *    as a loaded plugin.
1113  */
1114 skplugin_err_t
1115 skPluginAddAsPlugin(
1116     const char             *name,
1117     skplugin_setup_fn_t     setup_fn);
1118 
1119 /**
1120  *    Print, to 'fh', the usage information for the options which the
1121  *    plugins have registered through calls to skpinRegOption2().
1122  */
1123 skplugin_err_t
1124 skPluginOptionsUsage(
1125     FILE               *fh);
1126 
1127 /**
1128  *    Sets the function that skpinOpenDataInputStream() should use for
1129  *    opening files to 'open_fn'.
1130  *
1131  *    If this function is not called or called with a NULL parameter,
1132  *    the sequence of functions skStreamCreate(), skStreamBind(),
1133  *    skStreamOpen() is called.
1134  */
1135 void
1136 skPluginSetOpenInputFunction(
1137     open_data_input_fn_t    open_fn);
1138 
1139 /**
1140  *    Returns 1 if all loaded plugins can be safely be run in a
1141  *    threaded context, 0 otherwise.
1142  */
1143 int
1144 skPluginIsThreadSafe(
1145     void);
1146 
1147 /**
1148  *    Returns 1 if any filtering plugins are currently registered, 0
1149  *    if not.
1150  */
1151 int
1152 skPluginFiltersRegistered(
1153     void);
1154 
1155 /**
1156  *    Returns 1 if any transform plugins are currently registered, 0
1157  *    if not.
1158  */
1159 int
1160 skPluginTransformsRegistered(
1161     void);
1162 
1163 /**
1164  *    Binds an iterator around all fields that contain information
1165  *    that matches the 'fn_mask'.  If 'all_fields' is false, will
1166  *    only iterate over "activated" fields.
1167  */
1168 skplugin_err_t
1169 skPluginFieldIteratorBind(
1170     skplugin_field_iter_t  *iter,
1171     skplugin_fn_mask_t      fn_mask,
1172     int                     all_fields);
1173 
1174 /**
1175  *    Resets a field iterator so it can be iterated over again.
1176  */
1177 skplugin_err_t
1178 skPluginFieldIteratorReset(
1179     skplugin_field_iter_t  *iter);
1180 
1181 /**
1182  *    Retrieves the field identifier for the next field.  Returns 1 on
1183  *    success, 0 on failure.
1184  */
1185 int
1186 skPluginFieldIteratorNext(
1187     skplugin_field_iter_t  *iter,
1188     skplugin_field_t      **field);
1189 
1190 /**
1191  *    Returns the function mask for a field.
1192  */
1193 skplugin_fn_mask_t
1194 skPluginFieldFnMask(
1195     const skplugin_field_t *field);
1196 
1197 /**
1198  *    Activate the field 'field'.  All fields start deactivated.
1199  *    Activating a field allows its 'init' and 'cleanup' functions to
1200  *    run.  Return SKPLUGIN_OK.  Exit on memory allocation error.
1201  */
1202 skplugin_err_t
1203 skPluginFieldActivate(
1204     const skplugin_field_t *field);
1205 
1206 /**
1207  *    Deactivate the field 'field'.  All fields start deactivated.
1208  *    Return SKPLUGIN_OK (always).
1209  */
1210 skplugin_err_t
1211 skPluginFieldDeactivate(
1212     const skplugin_field_t *field);
1213 
1214 /**
1215  *    Retrieves a pointer to the constant names of a field.  This is a
1216  *    NULL-terminated list of strings
1217  */
1218 skplugin_err_t
1219 skPluginFieldName(
1220     const skplugin_field_t     *field,
1221     const char               ***name);
1222 
1223 /**
1224  *    Retrieves a pointer to the constant title of a field.  The
1225  *    caller should not modify this value.
1226  */
1227 skplugin_err_t
1228 skPluginFieldTitle(
1229     const skplugin_field_t     *field,
1230     const char                **title);
1231 
1232 /**
1233  *    Retrieves a pointer to the constant description of a field.  The
1234  *    caller should not modify this value.  The description may be
1235  *    NULL.
1236  */
1237 skplugin_err_t
1238 skPluginFieldDescription(
1239     const skplugin_field_t     *field,
1240     const char                **description);
1241 
1242 /**
1243  *    Retrieves a pointer to the constant path of the plugin which
1244  *    created the field.  The caller should not modify this value.
1245  */
1246 skplugin_err_t
1247 skPluginFieldGetPluginName(
1248     const skplugin_field_t     *field,
1249     const char                **plugin_name);
1250 
1251 /**
1252  *    Retrieves the length of the binary representation for this
1253  *    field.  This is the value that was specified in
1254  *    skplugin_callbacks_t.bin_bytes.  Returns SKPLUGIN_ERR if no
1255  *    functions that use the binary length were registered for
1256  *    'field'.
1257  */
1258 skplugin_err_t
1259 skPluginFieldGetLenBin(
1260     const skplugin_field_t *field,
1261     size_t                 *len);
1262 
1263 /**
1264  *    Retrieves the maximum length of text fields (not including
1265  *    terminating NUL) for this field.  This is the value that was
1266  *    specified in skplugin_callbacks_t.column_width.  Returns
1267  *    SKPLUGIN_ERR if no functions that use the textual length were
1268  *    registered for 'field'.
1269  */
1270 skplugin_err_t
1271 skPluginFieldGetLenText(
1272     const skplugin_field_t *field,
1273     size_t                 *len);
1274 
1275 /**
1276  *    Copies the initial binary value for this field into the bytes
1277  *    pointed to by 'initial_value'.  This is the value that was
1278  *    specified in skplugin_callbacks_t.initial.
1279  */
1280 skplugin_err_t
1281 skPluginFieldGetInitialValue(
1282     const skplugin_field_t *aggregate,
1283     uint8_t                *intial_value);
1284 
1285 
1286 /*********************************************/
1287 /*** Functions to invoke plugin callbacks  ***/
1288 /*********************************************/
1289 
1290 /* The following set of functions are invoked by the application, and
1291  * these functions will call the appropriate function on the
1292  * registered/active plugins. */
1293 
1294 /**
1295  *    Runs the 'init' routines for the functions and the activated
1296  *    fields requested.
1297  *
1298  *    That is, calls the skplugin_callback_fn_t function:
1299  *    skplugin_callbacks_t.init(cbdata)
1300  *
1301  *    If 'fn_mask' is non-zero, this will only initialize activated
1302  *    fields for whom 'fn_mask' is a subset of their callback
1303  *    functions.  If 'fn_mask' will run over activated fields, you
1304  *    should not run skPluginFieldRunInitialize() on the individual
1305  *    fields, unless you know the initialization functions will be
1306  *    idempotent.
1307  */
1308 skplugin_err_t
1309 skPluginRunInititialize(
1310     skplugin_fn_mask_t  fn_mask);
1311 
1312 /**
1313  *    Runs the cleanup routines for the activated and activated fields
1314  *    requested.
1315  *
1316  *    That is, calls the skplugin_callback_fn_t function:
1317  *    skplugin_callbacks_t.cleanup(cbdata)
1318  *
1319  *    If 'fn_mask' is non-zero, this will only clean up activated
1320  *    fields for whom 'fn_mask' is a subset of their callback
1321  *    functions.  If 'fn_mask' will fun over activated fields, you
1322  *    should not run skPluginFieldRunCleanup() on the individual
1323  *    fields, unless you know the cleanup functions will be
1324  *    idempotent.
1325  */
1326 skplugin_err_t
1327 skPluginRunCleanup(
1328     skplugin_fn_mask_t  fn_mask);
1329 
1330 /**
1331  *    Runs a specific plugin field's initialization function.
1332  */
1333 skplugin_err_t
1334 skPluginFieldRunInitialize(
1335     const skplugin_field_t *field);
1336 
1337 /**
1338  *    Runs a specific plugin field's cleanup function.
1339  */
1340 skplugin_err_t
1341 skPluginFieldRunCleanup(
1342     const skplugin_field_t *field);
1343 
1344 /**
1345  *    Runs the filter functions over the SiLK Flow record 'rec' for
1346  *    all registered filters.
1347  *
1348  *    That is, calls the skplugin_filter_fn_t function:
1349  *    skplugin_callbacks_t.filter(rec, cbdata, extra)
1350  *
1351  *    The 'extra' fields are determined as described in the EXTRA
1352  *    ARGUMENTS section.
1353  */
1354 skplugin_err_t
1355 skPluginRunFilterFn(
1356     const rwRec        *rec,
1357     void              **extra);
1358 
1359 /**
1360  *    Runs the transform functions over the SiLK Flow record 'rec' for
1361  *    all registered tranformers.
1362  *
1363  *    That is, calls the skplugin_transform_fn_t function:
1364  *    skplugin_callbacks_t.transform(rec, cbdata, extra)
1365  *
1366  *    The 'extra' fields are determined as described in the EXTRA
1367  *    ARGUMENTS section.
1368  */
1369 skplugin_err_t
1370 skPluginRunTransformFn(
1371     rwRec              *rec,
1372     void              **extra);
1373 
1374 /**
1375  *    Runs the record-to-text function over the SiLK Flow record 'rec'
1376  *    for the specified field, and puts the value into 'text', where
1377  *    'text' is an array of 'width' characters.
1378  *
1379  *    That is, calls the skplugin_text_fn_t function:
1380  *    skplugin_callbacks_t.rec_to_text(rec, text. width, cbdata, extra)
1381  *
1382  *    The 'extra' fields are determined as described in the EXTRA
1383  *    ARGUMENTS section.
1384  */
1385 skplugin_err_t
1386 skPluginFieldRunRecToTextFn(
1387     const skplugin_field_t     *field,
1388     char                       *text,
1389     size_t                      width,
1390     const rwRec                *rec,
1391     void                      **extra);
1392 
1393 /**
1394  *    Runs the record-to-bin function over the SiLK Flow record 'rec'
1395  *    for the specified field, and puts the value into 'bin'.
1396  *
1397  *    That is, calls the skplugin_bin_fn_t function:
1398  *    skplugin_callbacks_t.rec_to_bin(rec, bin, cbdata, extra)
1399  *
1400  *    The required size of 'bin' can be determined by a call to
1401  *    skPluginFieldGetLenBin().
1402  *
1403  *    The 'extra' fields are determined as described in the EXTRA
1404  *    ARGUMENTS section.
1405  */
1406 skplugin_err_t
1407 skPluginFieldRunRecToBinFn(
1408     const skplugin_field_t     *field,
1409     uint8_t                    *bin,
1410     const rwRec                *rec,
1411     void                      **extra);
1412 
1413 /**
1414  *    Given a SiLK Flow record 'rec', runs the function that computes
1415  *    a binary value for this field and merges with (adds to) the
1416  *    value into currently in 'bin' into 'bin'.  The required size of
1417  *    'bin' can be determined by a call to skPluginFieldGetLenBin().
1418  *
1419  *    That is, calls the skplugin_bin_fn_t function:
1420  *    skplugin_callbacks_t.add_rec_to_bin(rec, bin, cbdata, extra)
1421  *
1422  *    The 'extra' fields are determined as described in the EXTRA
1423  *    ARGUMENTS section.
1424  */
1425 skplugin_err_t
1426 skPluginFieldRunAddRecToBinFn(
1427     const skplugin_field_t     *field,
1428     uint8_t                    *bin,
1429     const rwRec                *rec,
1430     void                      **extra);
1431 
1432 /**
1433  *    Runs the binary-to-text function for the specified field.  The
1434  *    function takes the binary value 'bin' and puts a textual value
1435  *    into 'text', an array of 'width' characters.
1436  *
1437  *    That is, calls the skplugin_bin_to_text_fn_t function:
1438  *    skplugin_callbacks_t.bin_to_text(bin, text, width, cbdata)
1439  */
1440 skplugin_err_t
1441 skPluginFieldRunBinToTextFn(
1442     const skplugin_field_t *field,
1443     char                   *text,
1444     size_t                  width,
1445     const uint8_t          *bin);
1446 
1447 /**
1448  *    Runs the function that merges two binary values for this field.
1449  *    The binary value in 'src' is merged with 'dst', and the result
1450  *    is put back in 'dst'.
1451  *
1452  *    That is, calls the skplugin_bin_merge_fn_t function:
1453  *    skplugin_callbacks_t.bin_merge(dst, src, cbdata)
1454  */
1455 skplugin_err_t
1456 skPluginFieldRunBinMergeFn(
1457     const skplugin_field_t *field,
1458     uint8_t                *dst,
1459     const uint8_t          *src);
1460 
1461 /**
1462  *    Runs the function that compares two binary values for this
1463  *    field.  The binary value in 'a' is compared with 'b', and the
1464  *    result (less than zero, zero, greater than zero) is put in
1465  *    'val'.
1466  *
1467  *    That is, calls the skplugin_bin_cmp_fn_t function:
1468  *    skplugin_callbacks_t.bin_compare(val, a, b, cbdata)
1469  */
1470 skplugin_err_t
1471 skPluginFieldRunBinCompareFn(
1472     const skplugin_field_t *field,
1473     int                    *val,
1474     const uint8_t          *a,
1475     const uint8_t          *b);
1476 
1477 
1478 
1479 /********************************************************************
1480  *
1481  *    EXTRA ARGUMENTS
1482  *
1483  ********************************************************************/
1484 
1485 /*
1486  *    Extra arguments are sets of extra information that can be passed
1487  *    to plugin functions on a per-SiLK Flow record (rwrec) basis.
1488  *    Extra arguments are named, and it is the responsibility of the
1489  *    application and plugin writers to agree on what type of data
1490  *    each name is associated with.
1491  *
1492  *    Extra arguments are meant to be used when a plugin can make use
1493  *    of extra information associated with an rwrec that is not in the
1494  *    rwrec itself.  Some plugins may actually require certain extra
1495  *    arguments in order to work.  An example: rwptoflow supports a
1496  *    transform function that requires the original packet data as
1497  *    context.
1498  *
1499  *    Extra arguments are meant to be used as follows:
1500  *
1501  *    a) The application registers the set of extra data it can supply
1502  *       with each record using skPluginSetAppExtraArgs().
1503  *
1504  *    b) The plugin gets information about what extra arguments are
1505  *       available using skpinGetAppExtraArgs().
1506  *
1507  *    c) If the plugin wishes to use the any of the extra arguments,
1508  *       it provides the names of those arguments, and the order in
1509  *       which is will expect them, as a NULL-terminated list in the
1510  *       'extra' field of the skplugin_callbacks_t structure.  The
1511  *       plugin may only include names that it received in the call to
1512  *       skpinGetAppExtraArgs().  There is less overheaad involved if
1513  *       the plugin specifies the arguments in the same order specifed
1514  *       in skpinGetAppExtraArgs().
1515  *
1516  *    d) After plugins have been loaded, the application finds out
1517  *       what extra arguments are being requested by the plugins via
1518  *       skPluginGetPluginExtraArgs().  These extra arguments MUST be
1519  *       used by the application, as the plugin will be expecting
1520  *       them.
1521  *
1522  *    e) The application then registers what extra arguments it will
1523  *       send, and in what order, using the
1524  *       skPluginSetUsedAppExtraArgs() function.  This set must
1525  *       include the extra arguments returned by
1526  *       skPluginGetPluginExtraArgs().
1527  *
1528  *    f) The application will hand the extra arguments to calls of
1529  *       skPluginRun*Fn() and skPluginFieldRun*Fn() in the order
1530  *       specified in skPluginSetUsedAppExtraArgs().  (Can send NULL
1531  *       if no extra arguments registered).  The plugins will receive
1532  *       the extra arguments they asked for in the order specified in
1533  *       Step (c) above.  The application and its plugins can reduce
1534  *       the overhead in the skPlugin layer by specifying the same set
1535  *       of extra arguments in the same order.
1536  */
1537 
1538 
1539 /**
1540  *    Called by the application.  Sets the extra arguments that the
1541  *    application handles.  'extra' is a NULL terminated array of
1542  *    strings.  If 'extra' is NULL, no extra arguments are registered.
1543  *    (This is the default).
1544  */
1545 void
1546 skPluginSetAppExtraArgs(
1547     const char        **extra);
1548 
1549 /**
1550  *    Called by the plugin.  Gets the list of extra arguments that the
1551  *    application specified in skPluginSetAppExtraArgs().  The list is
1552  *    returned as a NULL-terminated list of strings.
1553  */
1554 const char **
1555 skpinGetAppExtraArgs(
1556     void);
1557 
1558 /**
1559  *    Called by the application.  Gets the list of extra arguments
1560  *    that the plugins support.  The returned array will be a
1561  *    NULL-terminated list of strings.  The application is obligated
1562  *    to use all these arguments.
1563  */
1564 const char **
1565 skPluginGetPluginExtraArgs(
1566     void);
1567 
1568 /**
1569  *    Called by the application.  Sets which extra arguments the
1570  *    application will actually use, and the order in which they will
1571  *    be given.  'extra' is a NULL-terminated array of strings.  If
1572  *    'extra' is NULL, no extra arguments are registered.
1573  */
1574 void
1575 skPluginSetUsedAppExtraArgs(
1576     const char        **extra);
1577 
1578 #ifdef __cplusplus
1579 }
1580 #endif
1581 #endif /* _SKPLUGIN_H */
1582 
1583 /*
1584 ** Local Variables:
1585 ** mode:c
1586 ** indent-tabs-mode:nil
1587 ** c-basic-offset:4
1588 ** End:
1589 */
1590