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