1 /* 2 ** Copyright (C) 2016-2020 by Carnegie Mellon University. 3 ** 4 ** @OPENSOURCE_LICENSE_START@ 5 ** See license information in ../../LICENSE.txt 6 ** @OPENSOURCE_LICENSE_END@ 7 */ 8 #ifndef _SKAGGBAG_H 9 #define _SKAGGBAG_H 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 #include <silk/silk.h> 15 16 RCSIDENTVAR(rcsID_SKAGGBAG_H, "$SiLK: skaggbag.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 17 18 #include <silk/silk_types.h> 19 #include <silk/skstream.h> 20 21 22 /* 23 * skaggbag.h 24 * 25 * The API to AggBag, a container and associated file format that 26 * contains a Bag-like data structure (see skbag.h) where the key 27 * and counter are aggregates of multiple fields. 28 * 29 * Since SiLK 3.15.0. 30 * 31 * 32 * To create an AggBag, use skAggBagCreate(). Specify the type of 33 * the fields that comprise the key and counter by calling 34 * skAggBagSetKeyFields() and skAggBagSetCounterFields(), 35 * respectively. 36 * 37 * To insert data into the AggBag, first call 38 * skAggBagInitializeKey() and skAggBagInitializeCounter(). These 39 * functions initialize an sk_aggbag_aggregate_t and an 40 * sk_aggbag_field_t. sk_aggbag_aggregate_t is is an object holds 41 * the values prior to inserting them into the AggBag. 42 * sk_aggbag_field_t is an iterator over the fields that comprise a 43 * key or a counter. For each field, call 44 * skAggBagAggregateSetDatetime(), skAggBagAggregateSetIPAddress(), 45 * or skAggBagAggregateSetUnsigned() to set its value, then call 46 * skAggBagFieldIterNext() to move the iterator to the next field. 47 * Once all key fields and counter fields have been specified, call 48 * skAggBagKeyCounterSet() to insert the key and counter. 49 * 50 * skAggBagKeyCounterAdd(), skAggBagKeyCounterRemove(), and 51 * skAggBagKeyCounterSubtract() may be used to manipulate the 52 * counter values for a key. Use skAggBagKeyCounterGet() to get a 53 * counter for a specified key. 54 * 55 * Once processing is compete, use skAggBagSave() or 56 * skAggBagWrite() to store the AggBag to disk, and 57 * skAggBagDestroy() to free the memory used by the AggBag. 58 * 59 * 60 * For processing an existing AggBag, first use skAggBagLoad() or 61 * skAggBagRead() to read the AggBag from disk. Use 62 * skAggBagIteratorBind() to bind an iterator to the contents of 63 * the AggBag, and skAggBagIteratorNext() to copy the key and 64 * counter from the AggBag into the iterator. Use 65 * skAggBagFieldIterGetType() to get the type of the field, and 66 * then the one of the functions skAggBagAggregateGetDatetime(), 67 * skAggBagAggregateGetIPAddress(), or 68 * skAggBagAggregateGetUnsigned() to retrieve the value for each 69 * field in the key or counter. Use skAggBagFieldIterNext() to 70 * visit each field in the key and counter. Once all keys and 71 * counters have been visited, call skAggBagIteratorFree() to free 72 * the iterator and skAggBagDestroy() to destroy the AggBag. 73 * 74 * 75 * Mark Thomas 76 * December 2016 77 * 78 */ 79 80 /** 81 * sk_aggbag_t is the AggBag data structure. 82 */ 83 typedef struct sk_aggbag_st sk_aggbag_t; 84 85 /** 86 * sk_aggbag_aggregate_t is a structure to hold the key or counter 87 * prior to inserting them into the AggBag or when reading from an 88 * AggBag. An sk_aggbag_field_t is usually paired with the 89 * sk_aggbag_aggregate_t to visit each of the individual fields in 90 * the key or the counter. 91 */ 92 typedef struct sk_aggbag_aggregate_st sk_aggbag_aggregate_t; 93 94 /** 95 * sk_aggbag_field_t is an iterator over the individual fields that 96 * comprise a key or a counter. It is usually paired with an 97 * sk_aggbag_aggregate_t that holds the values. 98 */ 99 typedef struct sk_aggbag_field_st sk_aggbag_field_t; 100 101 102 103 /** 104 * sk_aggbag_options_t is used for specifying features of the 105 * output stream when writing an Aggregate Bag to a file. 106 */ 107 struct sk_aggbag_options_st { 108 /** 109 * type of input to the application, where a non-zero value 110 * indicates application uses existing SiLK files (either AggBags 111 * or Flow files). A non-zero value provides the --notes-strip 112 * option to the application. */ 113 unsigned int existing_silk_files; 114 /** 115 * when 0, do not strip invocations from the AggBag; when 1, 116 * strip invocations from output */ 117 unsigned int invocation_strip; 118 /** 119 * when 0, do not strip annoations (notes) from the AggBag; when 120 * 1, strip annotations from output */ 121 int note_strip; 122 /** 123 * the command line: number of arguments */ 124 unsigned int argc; 125 /** 126 * the command line: the arguments */ 127 char **argv; 128 /** 129 * the version of records to write */ 130 uint16_t record_version; 131 /** 132 * the type of compression to use */ 133 sk_compmethod_t comp_method; 134 }; 135 typedef struct sk_aggbag_options_st sk_aggbag_options_t; 136 137 138 /** 139 * sk_aggbag_iter_t is used for iterating over the keys and 140 * counters that an AggBag contains. The caller is expected to use 141 * the SK_AGGBAG_ITER_INITIALIZER macro when initializing an 142 * sk_aggbag_iter_t on the stack. 143 * 144 * Use skAggBagIteratorBind() to bind the iterator to an AggBag, 145 * skAggBagIteratorNext() to visit each key and counter, and 146 * skAggBagIteratorFree() when done. 147 */ 148 typedef struct sk_aggbag_iter_st sk_aggbag_iter_t; 149 150 /** 151 * sk_aggbag_type_iter_t is a structure used when iterating over 152 * the types of fields that the AggBag code supports. 153 * 154 * Use skAggBagFieldTypeIteratorBind() to initialize it and 155 * skAggBagFieldTypeIteratorNext() to visit each type. 156 */ 157 typedef struct sk_aggbag_type_iter_st sk_aggbag_type_iter_t; 158 159 /** 160 * sk_aggbag_type_t specifies the field types that the AggBag code 161 * supports. 162 */ 163 typedef enum sk_aggbag_type_en { 164 SKAGGBAG_FIELD_SIPv4 = 0, 165 SKAGGBAG_FIELD_DIPv4, 166 SKAGGBAG_FIELD_SPORT, 167 SKAGGBAG_FIELD_DPORT, 168 SKAGGBAG_FIELD_PROTO = 4, 169 SKAGGBAG_FIELD_PACKETS, 170 SKAGGBAG_FIELD_BYTES, 171 SKAGGBAG_FIELD_FLAGS, 172 SKAGGBAG_FIELD_STARTTIME = 8, 173 SKAGGBAG_FIELD_ELAPSED, 174 SKAGGBAG_FIELD_ENDTIME, 175 SKAGGBAG_FIELD_SID, 176 SKAGGBAG_FIELD_INPUT = 12, 177 SKAGGBAG_FIELD_OUTPUT, 178 SKAGGBAG_FIELD_NHIPv4, 179 SKAGGBAG_FIELD_INIT_FLAGS, 180 SKAGGBAG_FIELD_REST_FLAGS = 16, 181 SKAGGBAG_FIELD_TCP_STATE, 182 SKAGGBAG_FIELD_APPLICATION, 183 SKAGGBAG_FIELD_FTYPE_CLASS, 184 SKAGGBAG_FIELD_FTYPE_TYPE = 20, 185 /* 186 * SKAGGBAG_FIELD_STARTTIME_MSEC = 21, 187 * SKAGGBAG_FIELD_ENDTIME_MSEC, 188 * SKAGGBAG_FIELD_ELAPSED_MSEC, 189 */ 190 SKAGGBAG_FIELD_ICMP_TYPE = 24, 191 SKAGGBAG_FIELD_ICMP_CODE = 25, 192 /* the above correspond to values in rwascii.h */ 193 194 SKAGGBAG_FIELD_SIPv6, 195 SKAGGBAG_FIELD_DIPv6, 196 SKAGGBAG_FIELD_NHIPv6 = 28, 197 198 SKAGGBAG_FIELD_ANY_IPv4, 199 SKAGGBAG_FIELD_ANY_IPv6, 200 SKAGGBAG_FIELD_ANY_PORT, 201 SKAGGBAG_FIELD_ANY_SNMP = 32, 202 SKAGGBAG_FIELD_ANY_TIME, 203 204 SKAGGBAG_FIELD_CUSTOM_KEY, 205 206 SKAGGBAG_FIELD_SIP_COUNTRY, 207 SKAGGBAG_FIELD_DIP_COUNTRY = 36, 208 SKAGGBAG_FIELD_ANY_COUNTRY, 209 210 SKAGGBAG_FIELD_SIP_PMAP, 211 SKAGGBAG_FIELD_DIP_PMAP, 212 SKAGGBAG_FIELD_ANY_IP_PMAP = 40, 213 214 SKAGGBAG_FIELD_SPORT_PMAP, 215 SKAGGBAG_FIELD_DPORT_PMAP, 216 SKAGGBAG_FIELD_ANY_PORT_PMAP = 43, 217 218 SKAGGBAG_FIELD_RECORDS = 0xc000, /* 49152 */ 219 SKAGGBAG_FIELD_SUM_PACKETS, 220 SKAGGBAG_FIELD_SUM_BYTES, 221 SKAGGBAG_FIELD_SUM_ELAPSED, 222 SKAGGBAG_FIELD_CUSTOM_COUNTER = 0xc004, /* 49156 */ 223 224 SKAGGBAG_FIELD_INVALID = 65534 225 } sk_aggbag_type_t; 226 227 228 /** 229 * An initializer to use when creating an sk_aggbag_iter_t on the 230 * stack. 231 */ 232 #define SK_AGGBAG_ITER_INITIALIZER \ 233 { NULL, {NULL, {0}}, {NULL, {0}}, {NULL, 0}, {NULL, 0}} 234 235 /** 236 * Specify SK_AGGBAG_KEY as the value of the 'key_counter_flag' 237 * parameter to skAggBagFieldTypeIteratorBind() to visit the field 238 * types that represent keys. 239 */ 240 #define SK_AGGBAG_KEY 1 241 242 /** 243 * Specify SK_AGGBAG_KEY as the value of the 'key_counter_flag' 244 * parameter to skAggBagFieldTypeIteratorBind() to visit the field 245 * types that represent counters. 246 */ 247 #define SK_AGGBAG_COUNTER 2 248 249 /** 250 * The maximum number of octets an aggregate key or counter value 251 * may occupy. 252 */ 253 #define SKAGGBAG_AGGREGATE_MAXLEN UINT16_MAX 254 255 256 /** 257 * Add the AggBag 'ab_addend' to the AggBag 'ab_augend'. 258 * 259 * For each key in 'ab_addend', add the value for the key's counter 260 * to its value in 'ab_augend', creating new entries for keys that 261 * are not present. 262 */ 263 int 264 skAggBagAddAggBag( 265 sk_aggbag_t *ab_augend, 266 const sk_aggbag_t *ab_addend); 267 268 269 /** 270 * Get the value of the field at position 'field' in the key 271 * specified by 'agg' and set the referent of 'time_value' to that 272 * value. 273 * 274 * Return SKAGGBAG_OK on success. Return 275 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 276 * is not a Time. 277 * 278 * To set the value, use skAggBagAggregateSetDatetime(). See also 279 * skAggBagAggregateGetIPAddress() and 280 * skAggBagAggregateGetUnsigned(). 281 */ 282 int 283 skAggBagAggregateGetDatetime( 284 const sk_aggbag_aggregate_t *agg, 285 const sk_aggbag_field_t *field, 286 sktime_t *time_value); 287 288 289 /** 290 * Get the value of the field at position 'field' in the key 291 * specified by 'agg' and set the referent of 'ip_value' to that 292 * value. 293 * 294 * Return SKAGGBAG_OK on success. Return 295 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 296 * is not an IP address. 297 * 298 * To set the value, use skAggBagAggregateSetIPAddress(). See also 299 * skAggBagAggregateGetDatetime() and 300 * skAggBagAggregateGetUnsigned(). 301 */ 302 int 303 skAggBagAggregateGetIPAddress( 304 const sk_aggbag_aggregate_t *agg, 305 const sk_aggbag_field_t *field, 306 skipaddr_t *ip_value); 307 308 309 /** 310 * Get the value of the field at position 'field' in the key or 311 * counter specified by 'agg' and set the referent of 312 * 'unsigned_value' to that value. 313 * 314 * Return SKAGGBAG_OK on success. Return 315 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 316 * is an IP address or a Time. 317 * 318 * To set the value, use skAggBagAggregateSetUnsigned(). See also 319 * skAggBagAggregateGetDatetime() and 320 * skAggBagAggregateGetIPAddress(). 321 */ 322 int 323 skAggBagAggregateGetUnsigned( 324 const sk_aggbag_aggregate_t *agg, 325 const sk_aggbag_field_t *field, 326 uint64_t *unsigned_value); 327 328 329 /** 330 * Set the value of the field at position 'field' in the key 331 * specified by 'agg' to the value in 'time_value'. 332 * 333 * Return SKAGGBAG_OK on success. Return 334 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 335 * is not a Time. 336 * 337 * To get the value, use skAggBagAggregateGetDatetime(). See also 338 * skAggBagAggregateSetIPAddress() and 339 * skAggBagAggregateSetUnsigned(). 340 */ 341 int 342 skAggBagAggregateSetDatetime( 343 sk_aggbag_aggregate_t *agg, 344 const sk_aggbag_field_t *field, 345 sktime_t time_value); 346 347 /** 348 * Set the value of the field at position 'field' in the key 349 * specified by 'agg' to the value in 'ip_value'. 350 * 351 * Return SKAGGBAG_OK on success. Return 352 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 353 * is not an IP address. 354 * 355 * To get the value, use skAggBagAggregateGetIPAddress(). See also 356 * skAggBagAggregateSetDatetime() and 357 * skAggBagAggregateSetUnsigned(). 358 */ 359 int 360 skAggBagAggregateSetIPAddress( 361 sk_aggbag_aggregate_t *agg, 362 const sk_aggbag_field_t *field, 363 const skipaddr_t *ip_value); 364 365 /** 366 * Set the value of the field at position 'field' in the key or 367 * counter specified by 'agg' to the value in 'unsigned_value'. 368 * 369 * Return SKAGGBAG_OK on success. Return 370 * SKAGGBAG_E_FIELD_TYPE_MISMATCH if the value at position 'field' 371 * is an IP address or a Time. 372 * 373 * To get the value, use skAggBagAggregateGetUnsigned(). See also 374 * skAggBagAggregateSetDatetime() and 375 * skAggBagAggregateSetIPAddress(). 376 */ 377 int 378 skAggBagAggregateSetUnsigned( 379 sk_aggbag_aggregate_t *agg, 380 const sk_aggbag_field_t *field, 381 uint64_t unsigned_value); 382 383 384 /** 385 * Create a new AggBag data structure and store it in the referent 386 * of 'ab'. Before the AggBag can be used, the caller must call 387 * skAggBagSetKeyFields() and skAggBagSetCounterFields() to set the 388 * key fields and counter fields of the AggBag. 389 * 390 * The caller must use skAggBagDestroy() to destroy the AggBag once 391 * processing is complete. 392 */ 393 int 394 skAggBagCreate( 395 sk_aggbag_t **ab); 396 397 398 /** 399 * Free all memory associated with an AggBag data structure in the 400 * referent of 'ab' that was allocated via skAggBagCreate(), 401 * skAggBagRead(), or skAggBagLoad(). Do nothing if 'ab' or its 402 * referent is NULL. 403 */ 404 void 405 skAggBagDestroy( 406 sk_aggbag_t **ab); 407 408 409 /** 410 * Return the type of the current field at position 'field_iter'. 411 * Return SKAGGBAG_FIELD_INVALID if 'field_iter' is NULL or if it 412 * is not positioned on a valid key field or counter field. 413 */ 414 sk_aggbag_type_t 415 skAggBagFieldIterGetType( 416 const sk_aggbag_field_t *field_iter); 417 418 419 /** 420 * Set 'field_iter' to the next field that comprises the key or the 421 * counter and return SK_ITERATOR_OK if a field exists or return 422 * SK_ITERATOR_NO_MORE_ENTRIES if all fields have been visited. 423 */ 424 int 425 skAggBagFieldIterNext( 426 sk_aggbag_field_t *field_iter); 427 428 429 /** 430 * Reset the iterator 'field_iter' that supports iterating over the 431 * fields that comprise the key or counter. This function sets the 432 * iterator to point at the first field in the key or counter. 433 * 434 * Since SiLK 3.17.0. 435 */ 436 void 437 skAggBagFieldIterReset( 438 sk_aggbag_field_t *field_iter); 439 440 441 /** 442 * Return the name associated with the field type 'field_type'. 443 * Return NULL if the field type is not known. 444 */ 445 const char * 446 skAggBagFieldTypeGetName( 447 sk_aggbag_type_t field_type); 448 449 /** 450 * Bind the iterator 'type_iter' to visit each type of key field or 451 * counter field that the AggBag code supports. The 452 * 'key_counter_flag' parameter must be either SK_AGGBAG_KEY or 453 * SK_AGGBAG_COUNTER to specify which field types to visit. 454 * 455 * The caller should create the iterator on the stack and pass its 456 * address to this function. 457 * 458 * Do nothing if 'type_iter' is NULL or 'key_counter_flag' is an 459 * invalid value. 460 */ 461 void 462 skAggBagFieldTypeIteratorBind( 463 sk_aggbag_type_iter_t *type_iter, 464 unsigned int key_counter_flag); 465 466 /** 467 * Move the type iterator 'type_iter' to the first/next type, set 468 * the referent of 'field_type' to that type and return the name of 469 * the type. Set the referent of 'field_type' to 470 * SKAGGBAG_FIELD_INVALID and return NULL when all types have been 471 * visitied. 472 * 473 * To use this function, the iterator must first be bound via 474 * skAggBagFieldTypeIteratorBind(). 475 */ 476 const char * 477 skAggBagFieldTypeIteratorNext( 478 sk_aggbag_type_iter_t *type_iter, 479 sk_aggbag_type_t *field_type); 480 481 /** 482 * Move the field type iterator 'type_iter' to the beginning of the 483 * AggBag so that skAggBagIteratorNext() returns the first key and 484 * counter pair in the AggBag. Do nothing if 'iter' is NULL. 485 */ 486 void 487 skAggBagFieldTypeIteratorReset( 488 sk_aggbag_type_iter_t *type_iter); 489 490 491 /** 492 * Set all values in 'counter' to 0 and initialize 493 * 'counter_field_iter' to iterate over the fields that comprise 494 * the aggregate counter in 'ab'. The parameters 'counter' or 495 * 'counter_field_iter' may be NULL. 496 * 497 * After calling this function, the iterator is pointed at the 498 * first field in the counter, and one may set the value of that 499 * field using one of the skAggBagAggregateSetFOO() functions. 500 * Calling skAggBagFieldIterNext() moves the iterator to the second 501 * field in the counter and returns SK_ITERATOR_OK or returns 502 * SK_ITERATOR_NO_MORE_ENTRIES if the counter contains a single 503 * field. 504 * 505 * This function does not modify 'counter' and 'counter_field_iter' 506 * if 'ab' is NULL. 507 * 508 * Use skAggBagInitializeKey() to initialize the key. 509 */ 510 void 511 skAggBagInitializeCounter( 512 const sk_aggbag_t *ab, 513 sk_aggbag_aggregate_t *counter, 514 sk_aggbag_field_t *counter_field_iter); 515 516 517 /** 518 * Set all values in 'key' to 0 and initialize 'key_field_iter' to 519 * iterate over the fields that comprise the aggregate key in 'ab'. 520 * The parameters 'key' or 'key_field_iter' may be NULL. 521 * 522 * After calling this function, the iterator is pointed at the 523 * first field in the key, and one may set the value of that field 524 * using one of the skAggBagAggregateSetFOO() functions. Calling 525 * skAggBagFieldIterNext() moves the iterator to the second field in 526 * the key and returns SK_ITERATOR_OK or returns 527 * SK_ITERATOR_NO_MORE_ENTRIES if the key contains a single field. 528 * 529 * This function does not modify 'key' and 'key_field_iter' if 'ab' 530 * is NULL. 531 * 532 * Use skAggBagInitializeCounter() to initialize the counter. 533 */ 534 void 535 skAggBagInitializeKey( 536 const sk_aggbag_t *ab, 537 sk_aggbag_aggregate_t *key, 538 sk_aggbag_field_t *key_field_iter); 539 540 541 /** 542 * Bind the iterator 'iter' to visit the contents of the AggBag 543 * data structure 'ab'. The caller should create the iterator on 544 * the stack, initialize it with the SK_AGGBAG_ITER_INITIALIZER, 545 * and pass its address to this function. 546 * 547 * The caller may use skAggBagIteratorNext() to move the first/next 548 * key and counter pair in the AggBag. 549 * 550 * Once the contents have been visited or the caller has finished 551 * with the iterator, the caller must use skAggBagIteratorFree() to 552 * free the memory allocated by this function. 553 * 554 * Do nothing if 'iter' or 'ab' are NULL. 555 */ 556 void 557 skAggBagIteratorBind( 558 sk_aggbag_iter_t *iter, 559 const sk_aggbag_t *ab); 560 561 /** 562 * Free the memory used by the AggBag contents iterator 'iter' that 563 * was allocated by skAggBagIteratorBind(). For this function to 564 * work correctly on an iterator that was not bound, the 'iter' 565 * should be allocated on the stack and initialized with 566 * SK_AGGBAG_ITER_INITIALIZER. Do nothing if 'iter' is NULL. 567 */ 568 void 569 skAggBagIteratorFree( 570 sk_aggbag_iter_t *iter); 571 572 /** 573 * Move the AggBag contents iterator 'iter' to the first or next 574 * key and counter pair in the AggBag. Return SK_ITERATOR_OK if 575 * the move was successful or SK_ITERATOR_NO_MORE_ENTRIES if all 576 * key/counter pairs have been visited. Do nothing if 'iter' is 577 * NULL. 578 * 579 * To use this function, the iterator must first be bound to an 580 * AggBag via skAggBagIteratorBind(). 581 */ 582 int 583 skAggBagIteratorNext( 584 sk_aggbag_iter_t *iter); 585 586 /** 587 * Move the AggBag contents iterator 'iter' to the beginning of the 588 * AggBag so that skAggBagIteratorNext() returns the first key and 589 * counter pair in the AggBag. Do nothing if 'iter' is NULL. 590 */ 591 void 592 skAggBagIteratorReset( 593 sk_aggbag_iter_t *iter); 594 595 596 /** 597 * In the AggBag 'ab', add to the counter associated with 'key' the 598 * value in 'counter'. If 'key' does not exist in 'ab', insert it 599 * into 'ab' and set its value to 'counter'. 600 * 601 * If 'new_counter' is not NULL, the new value of the counter is 602 * copied into that location. 'new_counter' is unchanged when this 603 * function turns a value other than SKAGGBAG_OK. 604 * 605 */ 606 int 607 skAggBagKeyCounterAdd( 608 sk_aggbag_t *ab, 609 const sk_aggbag_aggregate_t *key, 610 const sk_aggbag_aggregate_t *counter, 611 sk_aggbag_aggregate_t *new_counter); 612 613 /** 614 * Fill 'counter' with the value that 'key' has in the AggBag 'ab'. 615 * 616 * If 'key' is not in 'ab', set fields in 'counter' to 0 and return 617 * not found. Otherwise, return SKAGGBAG_OK. 618 */ 619 int 620 skAggBagKeyCounterGet( 621 const sk_aggbag_t *ab, 622 const sk_aggbag_aggregate_t *key, 623 sk_aggbag_aggregate_t *counter); 624 625 /** 626 * Remove the counter associated with 'key' from the AggBag 'ab'. 627 */ 628 int 629 skAggBagKeyCounterRemove( 630 sk_aggbag_t *ab, 631 const sk_aggbag_aggregate_t *key); 632 633 /** 634 * In the AggBag 'ab', set the counter associated with 'key' to the 635 * value 'counter', overwriting the current counter value, if any. 636 * If 'counter' is non-zero, create 'key' if it does not already 637 * exist in 'bag'. If 'counter' is 0, remove 'key' if it exists in 638 * 'bag'; otherwise, do nothing. 639 */ 640 int 641 skAggBagKeyCounterSet( 642 sk_aggbag_t *ab, 643 const sk_aggbag_aggregate_t *key, 644 const sk_aggbag_aggregate_t *counter); 645 646 /** 647 * In the AggBag 'ab', subtract from the counter associated with 648 * 'key' the value 'counter'. If 'counter' is 0, return 649 * SKAGGBAG_OK regardless of whether 'key' is in 'bag', but set 650 * 'new_counter' to the counter if 'key' is in 'ab' and if 651 * 'new_counter' is supplied. When 'counter' is non-zero, 652 * 'key' must exist in 'bag'; if it does not, SKBAG_ERR_OP_BOUNDS 653 * is returned. SKBAG_ERR_OP_BOUNDS is also returned when 'key' is 654 * outside the range of keys supported by 'ab'. 655 * 656 * If 'new_counter' is not NULL, the new value of the counter is 657 * copied into that location. 'new_counter' is unchanged when this 658 * function turns a value other than SKAGGBAG_OK. 659 */ 660 int 661 skAggBagKeyCounterSubtract( 662 sk_aggbag_t *ab, 663 const sk_aggbag_aggregate_t *key, 664 const sk_aggbag_aggregate_t *counter, 665 sk_aggbag_aggregate_t *new_counter); 666 667 668 /** 669 * Read a serialized AggBag from the file specified by 'filename' 670 * into a newly created AggBag structure and set the referent of 671 * 'ab' to its location. This function is a wrapper around 672 * skBagRead(). 673 * 674 * The caller must use skAggBagDestroy() to free the AggBag once it 675 * is no longer needed. 676 */ 677 int 678 skAggBagLoad( 679 sk_aggbag_t **ab, 680 const char *filename); 681 682 /** 683 * Bind 'ab_opts' to the AggBag 'ab'. 'ab_opts' specify how the 684 * AggBag will be written to disk. If no options are bound to an 685 * AggBag, the AggBag uses default values when writing the AggBag. 686 * 687 * The AggBag 'ab' does not copy the 'ab_options'; it simply 688 * maintains a pointer to them, and it references the options when 689 * a call to skAggBagSave() or skAggBagWrite() is made. 690 */ 691 void 692 skAggBagOptionsBind( 693 sk_aggbag_t *ab, 694 const sk_aggbag_options_t *ab_opts); 695 696 /** 697 * Register options that affect how binary AggBags are written. 698 * The 'ab_opts' parameter is required; it is initialized to the 699 * default values. 700 * 701 * Prior to calling this function, the caller should set the 702 * 'existing_silk_files' member of the structure to either 0 or 1. 703 * The value 1 indicates the application works with existing 704 * AggBags (e.g., rwaggbagtool) or existing SiLK Flow files 705 * (rwaggbag); the value 0 indicates the application creates new 706 * AggBags (e.g., rwaggbagbuild). If the value is non-zero, the 707 * --notes-strip option is provided. 708 */ 709 int 710 skAggBagOptionsRegister( 711 sk_aggbag_options_t *ab_opts); 712 713 /** 714 * Free any memory or internal state used by the AggBag options. 715 */ 716 void 717 skAggBagOptionsTeardown( 718 void); 719 720 /** 721 * Print usage information for the command line switches registered 722 * by skAggBagOptionsRegister() to the specified file handle. 723 */ 724 void 725 skAggBagOptionsUsage( 726 FILE *fh); 727 728 /** 729 * Read a serialized AggBag from the input stream 'stream' into a 730 * newly created AggBag structure and set the referent of 'ab' to 731 * its location. 732 * 733 * The caller must use skAggBagDestroy() to free the AggBag once it 734 * is no longer needed. 735 * 736 * 737 * See also skBagLoad(). 738 */ 739 int 740 skAggBagRead( 741 sk_aggbag_t **ab, 742 skstream_t *stream); 743 744 /** 745 * Serialize the AggBag structure 'ab' to the file specified by 746 * 'filename'. This function is a wrapper around skBagWrite(). 747 */ 748 int 749 skAggBagSave( 750 const sk_aggbag_t *ab, 751 const char *filename); 752 753 754 /** 755 * Set the key fields of the AggBag 'ab' to the list of 756 * 'field_count' values in in 'fields'. 757 */ 758 int 759 skAggBagSetKeyFields( 760 sk_aggbag_t *ab, 761 unsigned int field_count, 762 const sk_aggbag_type_t fields[]); 763 764 /** 765 * Set the counter fields of the AggBag 'ab' to the list of 766 * 'field_count' values in in 'fields'. 767 */ 768 int 769 skAggBagSetCounterFields( 770 sk_aggbag_t *ab, 771 unsigned int field_count, 772 const sk_aggbag_type_t fields[]); 773 774 775 /** 776 * Return a static string that describes the error associated with 777 * the error code 'err_code. 778 */ 779 const char * 780 skAggBagStrerror( 781 int err_code); 782 783 784 /** 785 * Subtract the AggBag 'ab_subtrahend' from the AggBag 'ab_minuend'. 786 * 787 * For each key common to 'ab_subtrahend' and 'ab_minuend', 788 * subtract the value of the key's counter in 'ab_subtrahend' from 789 * the value of the key's counter in 'ab_minuend'. Remove a key 790 * from 'ab_minuend' if that key's counter is less than or equal to 791 * the key's counter in 'ab_subtrahend'. 792 */ 793 int 794 skAggBagSubtractAggBag( 795 sk_aggbag_t *ab_minuend, 796 const sk_aggbag_t *ab_subtrahend); 797 798 799 /** 800 * Serialize the AggBag structure 'ab' to the output stream 801 * 'stream'. The caller may set the compression method of 'stream' 802 * before calling this function. 803 * 804 * 805 * See also skBagSave(). 806 */ 807 int 808 skAggBagWrite( 809 const sk_aggbag_t *ab, 810 skstream_t *stream); 811 812 813 /* 814 * Definifition of the type for sk_aggbag_aggregate_t so that the 815 * aggregate may be created on the stack. The caller must treat 816 * the internals of this type as opaque. 817 */ 818 struct sk_aggbag_aggregate_st { 819 const void *opaque; 820 uint8_t data[SKAGGBAG_AGGREGATE_MAXLEN]; 821 }; 822 823 /* 824 * Definifition of the type for sk_aggbag_field_t so that the field 825 * iterator may be created on the stack. The caller must treat the 826 * internals of this type as opaque. 827 */ 828 struct sk_aggbag_field_st { 829 const void *opaque; 830 size_t pos; 831 }; 832 833 /* 834 * Definifition of the type for sk_aggbag_iter_t so that the AggBag 835 * content iterator may be created on the stack. The caller must 836 * treat the internals of this type as opaque. 837 * 838 * When creating an sk_aggbag_iter_t on the stack, the caller is 839 * expected to initialize it to SK_AGGBAG_ITER_INITIALIZER. 840 */ 841 struct sk_aggbag_iter_st { 842 const void *opaque; 843 sk_aggbag_aggregate_t key; 844 sk_aggbag_aggregate_t counter; 845 sk_aggbag_field_t key_field_iter; 846 sk_aggbag_field_t counter_field_iter; 847 }; 848 849 850 /* 851 * Definifition of the type for sk_aggbag_type_iter_t so that the 852 * type iterator may be created on the stack. The caller must 853 * treat the internals of this type as opaque. 854 */ 855 struct sk_aggbag_type_iter_st { 856 sk_aggbag_type_t pos; 857 unsigned int key_counter_flag; 858 }; 859 860 861 typedef enum sk_aggbag_retval_en { 862 SKAGGBAG_OK, 863 SKAGGBAG_E_ALLOC, 864 SKAGGBAG_E_NULL_PARM, 865 SKAGGBAG_E_FIXED_FIELDS, 866 SKAGGBAG_E_UNDEFINED_KEY, 867 SKAGGBAG_E_UNDEFINED_COUNTER, 868 SKAGGBAG_E_FIELD_CLASS, 869 SKAGGBAG_E_FIELDS_DIFFER_KEY, 870 SKAGGBAG_E_FIELDS_DIFFER_COUNTER, 871 SKAGGBAG_E_GET_SET_MISMATCH, 872 SKAGGBAG_E_BAD_INDEX, 873 SKAGGBAG_E_READ, 874 SKAGGBAG_E_WRITE, 875 SKAGGBAG_E_HEADER, 876 SKAGGBAG_E_INSERT, 877 SKAGGBAG_E_UNSUPPORTED_IPV6 878 } sk_aggbag_retval_t; 879 880 881 #ifdef __cplusplus 882 } 883 #endif 884 #endif /* _SKAGGBAG_H */ 885 886 /* 887 ** Local Variables: 888 ** mode:c 889 ** indent-tabs-mode:nil 890 ** c-basic-offset:4 891 ** End: 892 */ 893