1 /* 2 ** Copyright (C) 2004-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 ** probeconf.h 11 ** 12 ** Functions to parse a probe configuration file and use the 13 ** results. 14 ** 15 */ 16 17 #ifndef _PROBECONF_H 18 #define _PROBECONF_H 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #include <silk/silk.h> 24 25 RCSIDENTVAR(rcsID_PROBECONF_H, "$SiLK: probeconf.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 26 27 #include <silk/silk_types.h> 28 29 /** 30 * @file 31 * 32 * Functions to parse a probe configuration file and use the 33 * results. 34 * 35 * This file is part of libflowsource. 36 * 37 * 38 * Lifecycle: 39 * 40 * The application calls skpcSetup() to initialize the 41 * skpc data structures and memory. 42 * 43 * The application should call skpcParse() to parse the 44 * application's configuration file. skpcParse() will create 45 * sensors (if any) and probes. The probes are created and checked 46 * for validity--this means they have all the data they require. 47 * If valid they are added to the list maintained by the skpc. 48 * If not valid, they are destroyed. 49 * 50 * Once the probes have been created, the application can use 51 * skpcProbeIteratorBind() and skpcProbeIteratorNext() to process 52 * each probe. 53 * 54 * Finally, the application calls skpcTeardown() to destroy 55 * the probes, sensors, and to fee all memory. 56 * 57 * Note that skpc allows one to create a "temporary" sensor; 58 * i.e., a sensor that will only exist as long as the application 59 * is running; this is useful for testing a new sensor without 60 * requiring a complete recompile of SiLK. However, "temporary" 61 * sensors will NOT be available to the analysis applications. For 62 * the analysis applications to know about a sensor, it MUST be 63 * listed in the sensorInfo[] array. 64 */ 65 66 67 /** 68 * Values for the type of a probe. 69 */ 70 typedef enum { 71 PROBE_ENUM_INVALID = 0, 72 PROBE_ENUM_IPFIX = 10, 73 PROBE_ENUM_NETFLOW_V5 = 5, 74 PROBE_ENUM_NETFLOW_V9 = 9, 75 PROBE_ENUM_SFLOW = 16, 76 PROBE_ENUM_SILK = 15 77 } skpc_probetype_t; 78 79 80 /** 81 * Possible protocols 82 */ 83 typedef enum { 84 SKPC_PROTO_UNSET = 0, 85 SKPC_PROTO_TCP = 1, 86 SKPC_PROTO_UDP = 2, 87 #if 0 88 /* not sure if these should be here; we'll decide when we add SSL 89 * support */ 90 SKPC_PROTO_DTLS_SCTP, 91 SKPC_PROTO_TLS_TCP, 92 SKPC_PROTO_DTLS_UDP, 93 #endif 94 SKPC_PROTO_SCTP = 3 95 } skpc_proto_t; 96 97 98 /* 99 * Supported "quirks" for special record handling. 100 */ 101 102 /** 103 * Value returned by skpcProbeGetQuirks() to denote that no quirks 104 * are set. 105 */ 106 #define SKPC_QUIRK_NONE 0x00 107 108 /** 109 * Quirks flag to support checking for firewall event codes, such 110 * as those returned by the Cisco ASA series of routers. 111 */ 112 #define SKPC_QUIRK_FW_EVENT 0x01 113 114 /** 115 * Quirks flag to support flow records that do not contain a valid 116 * packets field, such as those from the Cisco ASA series of 117 * routers. 118 */ 119 #define SKPC_QUIRK_ZERO_PACKETS 0x02 120 121 /** 122 * Quirks flag to force processing of NetFlow v9/IPFIX records 123 * whose templates do not contain any IP addresses. 124 */ 125 #define SKPC_QUIRK_MISSING_IPS 0x04 126 127 /** 128 * Quirks flag to handle NetFlow v9 from a SonicWall appliance 129 * where the sysUpTime field in the header is reported in seconds 130 * instead of in milliseconds. Since SiLK 3.14.0. 131 */ 132 #define SKPC_QUIRK_NF9_SYSUPTIME_SECS 0x08 133 134 /** 135 * Quirks flag to handle NetFlow v9 from an appliance where the 136 * OUT_BYTES and OUT_PKTS info elements contain volume counts for 137 * traffic going in the reverse direction of IN_BYTES and IN_PKTS. 138 * Versions of libfixbuf prior to 1.8.0 treated those elements as 139 * reverse-volume elements; starting in 1.8.0, they are treated as 140 * post-volume elements. Since SiLK 3.17.2. 141 */ 142 #define SKPC_QUIRK_NF9_OUT_IS_REVERSE 0x10 143 144 /*#define SKPC_QUIRK_ 0x20*/ 145 /*#define SKPC_QUIRK_ 0x40*/ 146 /*#define SKPC_QUIRK_ 0x80*/ 147 148 149 /** 150 * The type for network ids 151 */ 152 typedef size_t skpc_network_id_t; 153 154 /** 155 * The maximum possible network ID 156 */ 157 #define SKPC_NETWORK_ID_MAX ((skpc_network_id_t)254) 158 159 /** 160 * The invalid network ID 161 */ 162 #define SKPC_NETWORK_ID_INVALID ((skpc_network_id_t)255) 163 164 165 /** 166 * Which "side" of the record we look at when testing its flow 167 * interfaces, whether 168 * 169 * -- its source is a particular network; i.e., it is COMING FROM an 170 * internet cloud. For this case, look at its source IP or input 171 * SNMP interface. 172 * 173 * -- its destination is a particular network; i.e., it is GOING TO 174 * a cloud. For this case, look at the destination IP or output 175 * SNMP interface. 176 */ 177 typedef enum { 178 SKPC_DIR_SRC = 0, SKPC_DIR_DST = 1 179 } skpc_direction_t; 180 181 182 /** 183 * The "type" of value that the probe stores in the input and 184 * output fields. 185 * 186 * A value of 'SKPC_IFVALUE_SNMP' signifies that those fields hold 187 * the index of the interface (ifIndex) where the flows entered and 188 * left the router, respectively. 189 * 190 * A value of 'SKPC_IFVALUE_VLAN' signifies that those fields hold 191 * the vlanIds for the source and destination networks, 192 * respectively. If only vlan Id is available, the 'input' is set 193 * to that value and the 'output' is set to 0. 194 */ 195 typedef enum { 196 SKPC_IFVALUE_SNMP = 0, 197 SKPC_IFVALUE_VLAN = 1 198 } skpc_ifvaluetype_t; 199 200 201 /* Forward declaration */ 202 typedef struct skpc_sensor_st skpc_sensor_t; 203 204 205 /** 206 * The network definition. 207 * 208 * Maps a name to an ID. 209 */ 210 typedef struct skpc_network_st { 211 char *name; 212 skpc_network_id_t id; 213 } skpc_network_t; 214 215 216 /** 217 * The probe definition. 218 * 219 * A probe tells how to collect data and the type of data. For 220 * example, IPFIX data from machine 10.10.10.10 as TCP to port 221 * 9999. A probe is associated with one or more sensors. 222 */ 223 typedef struct skpc_probe_st { 224 225 /** List of sensors to which this probe belongs, and a count of 226 * those sensors */ 227 skpc_sensor_t **sensor_list; 228 size_t sensor_count; 229 230 /** The host:port combination on which this probe should listen for 231 * data, as an IP address and a port-number. */ 232 sk_sockaddr_array_t *listen_addr; 233 234 /** The list of host that this probe should accept connections 235 * from. Length is in the accept_from_addr_count member. */ 236 sk_sockaddr_array_t **accept_from_addr; 237 238 /** The unix domain socket on which this probe should listen for 239 * data, as a UNIX pathname */ 240 char *unix_domain_path; 241 242 /** A file name from which to read flow data */ 243 char *file_source; 244 245 /** A directory path name to poll in order to find files from which 246 * to read flow data */ 247 char *poll_directory; 248 249 /** the name of the probe */ 250 const char *probe_name; 251 252 /** length of the accept_from_addr array */ 253 uint32_t accept_from_addr_count; 254 255 /** Probe quirks */ 256 uint8_t quirks; 257 258 /** Probe logging flags */ 259 uint8_t log_flags; 260 261 /** Probe protocol */ 262 skpc_proto_t protocol; 263 264 /** Probe type */ 265 skpc_probetype_t probe_type; 266 267 /** Type of the interface value */ 268 skpc_ifvaluetype_t ifvaluetype; 269 270 /** Has probe been verified */ 271 unsigned verified :1; 272 273 } skpc_probe_t; 274 275 276 /** 277 * A 'group' 278 * 279 * A 'group' may contain one of the following: (1)a list of 280 * interface numbers, (2)a list of IPWildcards, (3)an IPset. 281 * 282 * A group is created by giving it a list containing values or 283 * previously defined groups. 284 */ 285 typedef enum { 286 SKPC_GROUP_UNSET, 287 SKPC_GROUP_INTERFACE, 288 SKPC_GROUP_IPBLOCK, 289 SKPC_GROUP_IPSET 290 } skpc_group_type_t; 291 292 /** 293 * Number of different types of groups. 294 */ 295 #define SKPC_NUM_GROUP_TYPES 3 296 297 typedef struct skpc_group_st { 298 /** groups have an optional name */ 299 char *g_name; 300 /** the contents of the group */ 301 union skpc_group_value_un { 302 /** A bitmap of SK_SNMP_INDEX_LIMIT bits. */ 303 sk_bitmap_t *map; 304 /** A list containing pointers to skIPWildcard_t. */ 305 skIPWildcard_t **ipblock; 306 /** Vectory of IPWildcards used while building group. This is 307 * replaced by the 'ipblock' once the group is frozen. */ 308 sk_vector_t *vec; 309 /** An IPset */ 310 skipset_t *ipset; 311 } g_value; 312 /** number of items in the group */ 313 uint32_t g_itemcount; 314 /** the type of the group */ 315 skpc_group_type_t g_type; 316 /** once frozen, a group cannot be changed */ 317 int8_t g_is_frozen; 318 } skpc_group_t; 319 320 321 322 /** 323 * The 'decider'. 324 * 325 * This describes the logic that the sensor will use to determine 326 * (decide) the flowtype (class/type) of each flow. The type will 327 * depend on whether the sensor.conf file lists interfaces, 328 * ipblocks, or IPsets for the sensor. 329 */ 330 typedef enum { 331 /** no interface, ipblock, or ipset values seen */ 332 SKPC_UNSET, 333 /** *-interface (SNMP) value seen */ 334 SKPC_INTERFACE, 335 /** *-ipblock value seen */ 336 SKPC_IPBLOCK, 337 /** ipblock is inverted */ 338 SKPC_NEG_IPBLOCK, 339 /** *-ipset value seen */ 340 SKPC_IPSET, 341 /** ipset is inverted */ 342 SKPC_NEG_IPSET, 343 /** sensor.conf has "*-interface remainder" line */ 344 SKPC_REMAIN_INTERFACE, 345 /** sensor.conf has "*-ipblock remainder" line */ 346 SKPC_REMAIN_IPBLOCK, 347 /** sensor.conf has "*-ipset remainder" line */ 348 SKPC_REMAIN_IPSET 349 } skpc_netdecider_type_t; 350 351 typedef struct skpc_netdecider_st { 352 skpc_netdecider_type_t nd_type; 353 const skpc_group_t *nd_group; 354 } skpc_netdecider_t; 355 356 /** number of 'decider' types */ 357 #define SKPC_NUM_NETDECIDER_TYPES 9 358 359 360 /** 361 * A filter 362 * 363 * A filter is similar to the decider in that it accepts a list of 364 * interfaces, ipblocks, or IPsets. However, instead of being used 365 * to decide the flowtype, a filter is used to determine whether 366 * rwflowpack should even consider the flow. A filter can match 367 * the 'source' (either source IP or input interface), the 368 * 'destination' (either destination IP or output interface), or 369 * 'any' (any of the above). Filters are set in the sensor.conf 370 * file by using the 'discard-when' and 'discard-unless' 371 * statements. 372 */ 373 typedef enum { 374 SKPC_FILTER_SOURCE, SKPC_FILTER_DESTINATION, SKPC_FILTER_ANY 375 } skpc_filter_type_t; 376 377 typedef struct skpc_filter_st { 378 /** the value to use as the filter */ 379 const skpc_group_t *f_group; 380 /** the part of the flow record to use */ 381 skpc_filter_type_t f_type; 382 /** the type of the group in 'f_group' */ 383 skpc_group_type_t f_group_type; 384 /** if non-zero, discard flows that match the value in 'f_group'. 385 * if zero, discard flows that do NOT match the value */ 386 unsigned f_discwhen :1; 387 } skpc_filter_t; 388 389 /** number of 'filter' types */ 390 #define SKPC_NUM_FILTER_TYPES 3 391 392 393 394 /** 395 * The sensor definition. 396 * 397 * The sensor takes the flows from one or more probes and 398 * determines how to pack them---i.e., their flowtype or 399 * class/type. 400 */ 401 struct skpc_sensor_st { 402 403 /** An array of network-deciders, one for each of the networks 404 * defined for this site. For example, a normal border router 405 * that has the INTERNAL, EXTERNAL, and NULL networks would have 3 406 * valid elements. */ 407 skpc_netdecider_t *decider; 408 size_t decider_count; 409 410 /** An array of probes associated with this sensor and the number 411 * of entries in that list */ 412 skpc_probe_t **probe_list; 413 size_t probe_count; 414 415 /** the name of the sensor */ 416 char *sensor_name; 417 418 /** An array of filters and the count. */ 419 skpc_filter_t *filter; 420 size_t filter_count; 421 422 /** A list (and a count of the elements in the list) that contains 423 * the IP addresses of the ISP's this probe talks to. */ 424 uint32_t *isp_ip_list; 425 size_t isp_ip_count; 426 427 /** The source and destination networks, if they have been set to a 428 * fixed value. */ 429 skpc_network_id_t fixed_network[2]; 430 431 /** The sensor ID as defined in the silk.conf file. */ 432 sk_sensor_id_t sensor_id; 433 }; 434 435 436 /** 437 * Iterators over probes and sensors 438 */ 439 typedef struct skpc_probe_iter_st { 440 size_t cur; 441 } skpc_probe_iter_t; 442 443 typedef struct skpc_sensor_iter_st { 444 size_t cur; 445 } skpc_sensor_iter_t; 446 447 448 449 /* 450 * ***** Probe configuration ************************************** 451 */ 452 453 454 /** 455 * Initialize the probe configuration data structures. 456 */ 457 int 458 skpcSetup( 459 void); 460 461 462 /** 463 * Destroy all probes and sensors and free all memory used by the 464 * probe configuration. 465 */ 466 void 467 skpcTeardown( 468 void); 469 470 471 /** 472 * Parse the probe configuration file 'filename'. This should only 473 * be called one time. 474 * 475 * This function will parse the configuration file and create 476 * sensors and probes. 477 */ 478 int 479 skpcParse( 480 const char *filename, 481 int (*site_sensor_verify_fn)(skpc_sensor_t *sensor)); 482 483 484 /** 485 * Return the count of created and verified probes. 486 */ 487 size_t 488 skpcCountProbes( 489 void); 490 491 492 /** 493 * Bind 'probe_iter' to loop over all the probes that have been 494 * defined. Returns 0 on success, or -1 on error. 495 */ 496 int 497 skpcProbeIteratorBind( 498 skpc_probe_iter_t *probe_iter); 499 500 501 /** 502 * If the probe iterator 'probe_iter' has exhausted all probes, 503 * leave 'probe' untouched and return 0; otherwise, fill 'probe' 504 * with a pointer to the next verified probe and return 1. Returns 505 * -1 on error (such as NULL input). The caller should not modify 506 * or free the probe. 507 */ 508 int 509 skpcProbeIteratorNext( 510 skpc_probe_iter_t *probe_iter, 511 const skpc_probe_t **probe); 512 513 514 /** 515 * Returns the probe named 'probe_name'. Returns NULL if not 516 * found. The caller should not modify nor free the return value. 517 */ 518 const skpc_probe_t * 519 skpcProbeLookupByName( 520 const char *probe_name); 521 522 523 /** 524 * Return the count of created and verified sensors. 525 */ 526 size_t 527 skpcCountSensors( 528 void); 529 530 531 /** 532 * Bind 'sensor_iter' to loop over all the sensors that have been 533 * defined. Returns 0 on success, or -1 on error. 534 */ 535 int 536 skpcSensorIteratorBind( 537 skpc_sensor_iter_t *sensor_iter); 538 539 540 /** 541 * If the sensor iterator 'sensor_iter' has exhausted all sensors, 542 * leave 'sensor' untouched and return 0; otherwise, fill 'sensor' 543 * with a pointer to the next verified sensor and return 1. Returns 544 * -1 on error (such as NULL input). The caller should not modify 545 * or free the sensor. 546 */ 547 int 548 skpcSensorIteratorNext( 549 skpc_sensor_iter_t *sensor_iter, 550 const skpc_sensor_t **sensor); 551 552 553 /** 554 * Appends to 'sensor_vec' the sensors whose ID is 'sensor_id'. 555 * Returns the number of sensors added to 'sensor_vec'. Returns -1 556 * to indicate invalid input or memory error appending to the 557 * vector. 'sensor_vec' should be a vector having elements of size 558 * sizeof(skpc_sensor_t*). The caller should not modify nor free 559 * the values appended to the vector. 560 */ 561 int 562 skpcSensorLookupByID( 563 sk_sensor_id_t sensor_id, 564 sk_vector_t *sensor_vec); 565 566 567 /** 568 * Appends to 'sensor_vec' the sensors whose name is 'sensor_name'. 569 * Returns the number of sensors added to 'sensor_vec'. Returns -1 570 * to indicate invalid input or memory error appending to the 571 * vector. 'sensor_vec' should be a vector having elements of size 572 * sizeof(skpc_sensor_t*). The caller should not modify nor free 573 * the values appended to the vector. 574 */ 575 int 576 skpcSensorLookupByName( 577 const char *sensor_name, 578 sk_vector_t *sensor_vec); 579 580 581 /** 582 * Given a printable representation of a probe, return the probe 583 * type. 584 * 585 * Return PROBE_ENUM_INVALID when given an unrecognized name. 586 */ 587 skpc_probetype_t 588 skpcProbetypeNameToEnum( 589 const char *name); 590 591 /** 592 * Return the printable respresentation of the probe type. 593 * 594 * Return NULL when given an illegal value. 595 */ 596 const char * 597 skpcProbetypeEnumtoName( 598 skpc_probetype_t type); 599 600 601 /** 602 * Given a printable representation of a protocol, return the 603 * protocol. 604 * 605 * Return SKPC_PROTO_UNSET when given an unrecognized name. 606 */ 607 skpc_proto_t 608 skpcProtocolNameToEnum( 609 const char *name); 610 611 /** 612 * Return the printable respresentation of the protocol. 613 * 614 * Return NULL when given an illegal value. 615 */ 616 const char * 617 skpcProtocolEnumToName( 618 skpc_proto_t proto); 619 620 621 /* 622 * ***** Networks *************************************************** 623 */ 624 625 626 /** 627 * Add a (id, name) pair to the list of networks used when 628 * determining the flowtype (class/type) of a flow record. 629 */ 630 int 631 skpcNetworkAdd( 632 skpc_network_id_t network_id, 633 const char *name); 634 635 /** 636 * Return the network object that was created with the name 637 * attribute set to 'name'. Returns NULL if no such network 638 * exists. 639 */ 640 const skpc_network_t * 641 skpcNetworkLookupByName( 642 const char *name); 643 644 645 /** 646 * Return the network object that was created with the id attribute 647 * set to 'id'. Returns NULL if no such network exists. 648 */ 649 const skpc_network_t * 650 skpcNetworkLookupByID( 651 skpc_network_id_t network_id); 652 653 654 655 /* 656 * ***** Probes ***************************************************** 657 * 658 * 659 * Flows are stored by SENSOR; a SENSOR is a logical construct made 660 * up of one or more physical PROBES. 661 * 662 * A probe collects flows in one of three ways: 663 * 664 * 1. The probe can listen to network traffic. For this case, 665 * skpcProbeGetListenOnSockaddr() will return the port on which to 666 * listen for traffic and the IP address that the probe should bind() 667 * to. In addition, the skpcProbeGetAcceptFromHost() method will 668 * give the IP address from which the probe should accept 669 * connections. 670 * 671 * 2. The probe can listen on a UNIX domain socket. The 672 * skpcProbeGetListenOnUnixDomainSocket() method returns the pathname 673 * to the socket. 674 * 675 * 3. The probe can read from a file. The skpcProbeGetFileSource() 676 * method returns the name of the file. 677 * 678 * A probe is not valid it has been set to use one and only one of 679 * these collection methods. 680 * 681 * Once the probe has collected a flow, it needs to determine whether 682 * the flow represents incoming traffic, outgoing traffic, ACL 683 * traffic, etc. The packLogicDetermineFlowtype() will take an 684 * 'rwrec' and the probe where the record was collected and use the 685 * external, internal, and null interface values and the list of ISP 686 * IPs to update the 'flow_type' field on the rwrec. The rwrec's 687 * sensor id ('sID') field is also updated. 688 * 689 */ 690 691 692 /** 693 * Create a new probe of type 'probe_type' and set the referent of 694 * 'probe' to the newly allocated probe. Return 0 on success. 695 * Return -1 if 'probe_type' is unknown or if the allocation fails. 696 */ 697 int 698 skpcProbeCreate( 699 skpc_probe_t **probe, 700 skpc_probetype_t probe_type); 701 702 703 /** 704 * Destroy the probe at '**probe' and free all memory. Sets *probe 705 * to NULL. Does nothing if 'probe' or the location it points to 706 * is NULL. 707 */ 708 void 709 skpcProbeDestroy( 710 skpc_probe_t **probe); 711 712 713 /** 714 * Return the name of a probe. The caller should not modify the 715 * name, and does not need to free() it. 716 */ 717 #define skpcProbeGetName(m_probe) ((m_probe)->probe_name) 718 #ifndef skpcProbeGetName 719 const char * 720 skpcProbeGetName( 721 const skpc_probe_t *probe); 722 #endif /* skpcProbeGetName */ 723 724 725 /** 726 * Set the name of a probe. The probe name must 727 * meet all the requirements of a sensor name. Each probe that is 728 * a collection point for a single sensor must have a unique name. 729 * 730 * The function makes a copy of 'name' and returns 0 on 731 * success, non-zero on memory allocation failure. 732 */ 733 int 734 skpcProbeSetName( 735 skpc_probe_t *probe, 736 const char *name); 737 738 739 /** 740 * Return the type of the probe. Before it is set by the user, the 741 * probe's type is PROBE_ENUM_INVALID. 742 */ 743 #define skpcProbeGetType(m_probe) ((m_probe)->probe_type) 744 #ifndef skpcProbeGetType 745 skpc_probetype_t 746 skpcProbeGetType( 747 const skpc_probe_t *probe); 748 #endif /* skpcProbeGetType */ 749 750 751 /** 752 * Get the probe's protocol. Before it is set by the user, the 753 * probe's protocol is SKPC_PROTO_UNSET. 754 */ 755 #define skpcProbeGetProtocol(m_probe) ((m_probe)->protocol) 756 #ifndef skpcProbeGetProtocol 757 skpc_proto_t 758 skpcProbeGetProtocol( 759 const skpc_probe_t *probe); 760 #endif /* skpcProbeGetProtocol */ 761 762 /** 763 * Set the probe's protocol. 764 */ 765 int 766 skpcProbeSetProtocol( 767 skpc_probe_t *probe, 768 skpc_proto_t skpc_protocol); 769 770 771 /** 772 * Get the probe's logging-flags. 773 */ 774 #define skpcProbeGetLogFlags(m_probe) ((m_probe)->log_flags) 775 #ifndef skpcProbeGetLogFlags 776 uint8_t 777 skpcProbeGetLogFlags( 778 const skpc_probe_t *probe); 779 #endif /* skpcProbeGetLogFlags */ 780 781 /** 782 * Add 'log_flag' to the logging flags for 'probe'; these logging 783 * flags refer to log messages regarding NetFlow v5 missing 784 * packets, NetFlow v5 bad packets, NetFlow v9/IPFIX firewall 785 * events, NetFlow v9/IPFIX sampling Options Template, and record 786 * timestamps. 787 * 788 * Before setting any log-flags on 'probe', the caller should call 789 * skpcProbeClearLogFlags() to remove all flags. 790 * 791 * Return 0 on success. Return -1 if 'log_flag' is not recognized 792 * for this particular probe. Return -2 if 'log_flag' conflicts 793 * with an existing log-flag on 'probe'; for example, it is an 794 * error to specify "none" when any of the probe's log-flags are 795 * set. 796 */ 797 int 798 skpcProbeAddLogFlag( 799 skpc_probe_t *probe, 800 const char *log_flag); 801 802 803 /** 804 * Clear all the "log-flag" settings on 'probe'. 805 */ 806 int 807 skpcProbeClearLogFlags( 808 skpc_probe_t *probe); 809 810 811 /** 812 * Determine whether the probe is currently configured to store 813 * SNMP interfaces or VLAN tags. 814 */ 815 #define skpcProbeGetInterfaceValueType(m_probe) \ 816 ((m_probe)->ifvaluetype) 817 #ifndef skpcProbeGetInterfaceValueType 818 skpc_ifvaluetype_t 819 skpcProbeGetInterfaceValueType( 820 const skpc_probe_t *probe); 821 #endif /* skpcProbeGetInterfaceValueType */ 822 823 824 /** 825 * Set the type of value that the probe stores in the 'input' and 826 * 'output' fields on the SiLK flow records; specifically SNMP 827 * values or VLAN tags. 828 * 829 * If not set by the user, the probe stores the SNMP interfaces in 830 * the input and output fields. 831 */ 832 int 833 skpcProbeSetInterfaceValueType( 834 skpc_probe_t *probe, 835 skpc_ifvaluetype_t interface_value_type); 836 837 838 /** 839 * Return a bitmap that specifies any special (or "peculiar" or 840 * "quirky") data handling for the probe. 841 */ 842 #define skpcProbeGetQuirks(m_probe) ((uint32_t)((m_probe)->quirks)) 843 #ifndef skpcProbeGetQuirks 844 uint32_t 845 skpcProbeGetQuirks( 846 const skpc_probe_t *probe); 847 #endif /* skpcProbeGetQuirks */ 848 849 850 /** 851 * Add 'quirk' to the special data handling directives for 'probe'. 852 * 853 * Before setting any quirks on 'probe', the caller should call 854 * skpcProbeClearQuirks() to remove all quirks. 855 * 856 * Return 0 on success. Return -1 if 'quirk' is not recognized for 857 * this particular probe. Return -2 if 'quirk' conflicts with an 858 * existing quirk on 'probe'; for example, it is an error to 859 * specify "none" when any of the probe's quirk are set. 860 */ 861 int 862 skpcProbeAddQuirk( 863 skpc_probe_t *probe, 864 const char *quirk); 865 866 867 /** 868 * Clear all the quirk settings on 'probe'. 869 */ 870 int 871 skpcProbeClearQuirks( 872 skpc_probe_t *probe); 873 874 875 /** 876 * Get the port on which the probe listens for 877 * connections, and, for multi-homed hosts, the IP address that the 878 * probe should consider to be its IP. The IP address is in host 879 * byte order. 880 * 881 * When getting the information, the caller may pass in locations 882 * to be filled with the address and port; either parameter may be 883 * NULL to ignore that value. 884 * 885 * The probe simply stores the address; it does not manipulate 886 * it in any way. 887 * 888 * If the IP address to listen as is not set, the function 889 * returns INADDR_ANY in the 'out_addr'. If the port has not been 890 * set, the 'get' function returns -1 and neither 'out' parameter 891 * is modified. 892 */ 893 int 894 skpcProbeGetListenOnSockaddr( 895 const skpc_probe_t *probe, 896 const sk_sockaddr_array_t **addr); 897 898 /** 899 * Set the port on which the probe listens for connections, and, 900 * for multi-homed hosts, the IP address that the probe should 901 * consider to be its IP. The probe takes ownership of the 'addr' 902 * object. 903 * 904 * To specify the host(s) that may connect to this probe, use the 905 * skpcProbeSetAcceptFromHost() function. 906 * 907 * When setting the information, the 'addr' must be non-zero and 908 * the port must be valid. 909 * 910 * The probe simply stores the address; it does not manipulate 911 * it in any way. 912 */ 913 int 914 skpcProbeSetListenOnSockaddr( 915 skpc_probe_t *probe, 916 sk_sockaddr_array_t *addr); 917 918 919 /** 920 * Get the unix domain socket on which the 921 * probe listens for connections. 922 * 923 * The caller should neither modify nor free the value returned by 924 * the 'get' method. The 'get' method returns NULL if the 'set' 925 * method has not yet been called. 926 */ 927 const char * 928 skpcProbeGetListenOnUnixDomainSocket( 929 const skpc_probe_t *probe); 930 931 /** 932 * Set the unix domain socket on which the 933 * probe listens for connections. 934 * 935 * The 'set' method will make a copy of the 'u_socket' value. 936 */ 937 int 938 skpcProbeSetListenOnUnixDomainSocket( 939 skpc_probe_t *probe, 940 const char *u_socket); 941 942 943 /** 944 * Get the file name from which to read data. 945 * 946 * The caller should neither modify nor free the value returned by 947 * the 'get' method. The 'get' method returns NULL if the 'set' 948 * method has not yet been called. 949 */ 950 const char * 951 skpcProbeGetFileSource( 952 const skpc_probe_t *probe); 953 954 /** 955 * Set the file name from which to read data. 956 * 957 * The 'set' function will make a copy of the 'pathname' value. 958 */ 959 int 960 skpcProbeSetFileSource( 961 skpc_probe_t *probe, 962 const char *pathname); 963 964 965 /** 966 * Get the name of the directory to poll for 967 * files containing flow records. 968 * 969 * The caller should neither modify nor free the value returned by 970 * the 'get' method. The 'get' method returns NULL if the 'set' 971 * method has not yet been called. 972 */ 973 const char * 974 skpcProbeGetPollDirectory( 975 const skpc_probe_t *probe); 976 977 /** 978 * Set the name of the directory to poll for 979 * files containing flow records. 980 * 981 * The 'set' function will make a copy of the 'pathname' value. 982 */ 983 int 984 skpcProbeSetPollDirectory( 985 skpc_probe_t *probe, 986 const char *pathname); 987 988 989 /** 990 * Get the hosts that are allowed to connect to 'probe'. 991 * 992 * The function stores the address of an array of 993 * sk_sockaddr_array_t* objects in the location referenced by 994 * 'addr_array'. The return value is the length of that array. 995 * 996 * The caller must not modify the values in the 'addr_array'. 997 * 998 * If the get function is called before the set function, the 999 * location referenced by 'addr_array' is set to NULL and 0 is 1000 * returned. 1001 * 1002 * If 'addr_array' is NULL, the number of addresses is returned. 1003 */ 1004 uint32_t 1005 skpcProbeGetAcceptFromHost( 1006 const skpc_probe_t *probe, 1007 const sk_sockaddr_array_t ***addr_array); 1008 1009 /** 1010 * Set the host(s) that are allowed to connect to 'probe'. The 1011 * 'addr_vec' argument must be a vector whose elements are 1012 * sk_sockaddr_array_t*. The function copies the 1013 * sk_sockaddr_array_t* elements from 'addr_vec' onto the 'probe' 1014 * and takes ownership of the sk_sockaddr_array_t*. The caller is 1015 * responsible for destroying the 'addr_vec' vector. 1016 * 1017 * Any previous accept-from-host values are removed. 1018 * 1019 * The probe simply stores the host_address; it does not manipulate 1020 * it in any way. 1021 */ 1022 int 1023 skpcProbeSetAcceptFromHost( 1024 skpc_probe_t *probe, 1025 const sk_vector_t *addr_vec); 1026 1027 1028 /** 1029 * Return a count of sensors that are using this probe. 1030 */ 1031 #define skpcProbeGetSensorCount(m_probe) ((m_probe)->sensor_count) 1032 #ifndef skpcProbeGetSensorCount 1033 size_t 1034 skpcProbeGetSensorCount( 1035 const skpc_probe_t *probe); 1036 #endif /* skpcProbeGetSensorCount */ 1037 1038 1039 /** 1040 * Return 1 if probe has been verified; 0 otherwise. 1041 */ 1042 int 1043 skpcProbeIsVerified( 1044 const skpc_probe_t *probe); 1045 1046 1047 /** 1048 * Verify the 'probe' is valid. For example, that it's name is 1049 * unique among all probes, and that if it is an IPFIX probe, 1050 * verify that a listen-on-port has been specified. 1051 * 1052 * When 'is_ephemeral' is specified, the function only verifies 1053 * that is name is unique. If the name is unique, the probe will 1054 * be added to the global list of probes, but skpcProbeIsVerified() 1055 * on the probe will return 0. 1056 * 1057 * If valid, add the probe to the list of probes and return 0. 1058 * Otherwise return non-zero. 1059 */ 1060 int 1061 skpcProbeVerify( 1062 skpc_probe_t *probe, 1063 int is_ephemeral); 1064 1065 1066 /** 1067 * Print a one line summary of 'probe' using the print function 1068 * 'printer'. 1069 */ 1070 void 1071 skpcProbePrint( 1072 const skpc_probe_t *probe, 1073 sk_msg_fn_t printer); 1074 1075 1076 1077 1078 /* 1079 * ***** Sensors **************************************************** 1080 */ 1081 1082 1083 /** 1084 * Create a new sensor and fill in 'sensor' with the address of 1085 * the newly allocated sensor. 1086 */ 1087 int 1088 skpcSensorCreate( 1089 skpc_sensor_t **sensor); 1090 1091 1092 /** 1093 * Destroy the sensor at '**sensor' and free all memory. Sets 1094 * *sensor to NULL. Does nothing if 'sensor' or the location it 1095 * points to is NULL. 1096 */ 1097 void 1098 skpcSensorDestroy( 1099 skpc_sensor_t **sensor); 1100 1101 1102 /** 1103 * Get the numeric ID of the sensor, as determined by the silk.conf 1104 * file. 1105 */ 1106 #define skpcSensorGetID(m_sensor) ((m_sensor)->sensor_id) 1107 #ifndef skpcSensorGetID 1108 sk_sensor_id_t 1109 skpcSensorGetID( 1110 const skpc_sensor_t *sensor); 1111 #endif /* skpcSensorGetID */ 1112 1113 /** 1114 * Get the name of the sensor. The caller should not modify the 1115 * name, and does not need to free() it. 1116 */ 1117 #define skpcSensorGetName(m_sensor) ((m_sensor)->sensor_name) 1118 #ifndef skpcSensorGetName 1119 const char * 1120 skpcSensorGetName( 1121 const skpc_sensor_t *sensor); 1122 #endif /* skpcSensorGetName */ 1123 1124 /** 1125 * Set the name of a sensor. The function makes a copy of 'name' 1126 * and returns 0 on success, non-zero on memory allocation failure. 1127 */ 1128 int 1129 skpcSensorSetName( 1130 skpc_sensor_t *sensor, 1131 const char *name); 1132 1133 1134 /** 1135 * Add a new filter (discard-when, discard-unless) to 'sensor'. 1136 * 'filter_type' specifies what part of the record to match 1137 * (source, destination, or any). 1138 * 1139 * If 'is_discardwhen_list' is non-zero, the caller is adding a 1140 * filter that, when matched, causes rwflowpack to discard the 1141 * flow. Otherwise, not matching the filter causes the flow to be 1142 * discarded. 1143 * 1144 * When 'is_wildcard_list' is non-zero, the type of 'group' must be 1145 * SKPC_GROUP_IPBLOCK and it must contain skIPWildcard_t* objects. 1146 * Otherwise, the type of 'group' must be SKPC_GROUP_INTERFACE and 1147 * it must contain numbers to treat as SNMP interface IDs. The 1148 * 'group' must be frozen and it must contain values, otherwise the 1149 * function returns -1. 1150 * 1151 * Return 0 on success. Return -1 on memory allocation error or 1152 * when a filter for the specified 'filter_type' already exists. 1153 */ 1154 int 1155 skpcSensorAddFilter( 1156 skpc_sensor_t *sensor, 1157 const skpc_group_t *group, 1158 skpc_filter_type_t filter_type, 1159 int is_discardwhen_list, 1160 skpc_group_type_t group_type); 1161 1162 1163 /** 1164 * Get the IP addresses of the ISP routers 1165 * that this sensor receives data from. 1166 * 1167 * The method returns the length of the list of ISP-IPs. If 1168 * the 'out_ip_list' parameter is provided, it will be modified to point to 1169 * the list of IP addresses (a C-array). The caller should NOT 1170 * modify the ISP-IP list that she receives, nor should she free() 1171 * it. When the 'get' method is called before the 'set' method, 0 1172 * is returned and the out parameter is not modified. 1173 */ 1174 uint32_t 1175 skpcSensorGetIspIps( 1176 const skpc_sensor_t *sensor, 1177 const uint32_t **out_ip_list); 1178 1179 /** 1180 * Set the IP addresses of the ISP routers 1181 * that this sensor receives data from. When flows are sent to the 1182 * null-interface, these IP addresses are used to distinguish 1183 * between flows that were ACL'ed and those that were probably 1184 * IP-routing messages sent from the ISP to this sensor. 1185 * 1186 * The method takes a vector of uint32_t's containing the 1187 * list of IP addresses. The function will copy the values from 1188 * the vector. It returns 0 on success, or -1 on memory allocation 1189 * errors. 1190 */ 1191 int 1192 skpcSensorSetIspIps( 1193 skpc_sensor_t *sensor, 1194 const sk_vector_t *isp_ip_vec); 1195 1196 1197 /** 1198 * Specify that for all traffic seen at 'sensor' the direction 1199 * 'dir' of all traffic is assigned to the network 'network_id'. 1200 * The list of 'network_id's is defined by the 1201 * packing logic plug-in that is specified on the rwflowpack 1202 * command line. 1203 * 1204 * Here, "network" refers to one of the domains that are being 1205 * monitored by the router or other flow collection software. For 1206 * example, a border router joins the internal and external 1207 * networks, and a flow whose source IP is specified in the list of 1208 * external network addresses will be considered incoming. 1209 * 1210 * For example, to configure 'sensor' so that all its traffic is 1211 * incoming (coming from the external network and going to the 1212 * internal network), one would call this function twice, once to 1213 * set the SKPC_DIR_SRC to 'external' and again to set the 1214 * SKPC_DIR_DST to 'internal'. 1215 * 1216 * This function conflicts with skpcSensorSetNetworkGroup(). 1217 */ 1218 int 1219 skpcSensorSetNetworkDirection( 1220 skpc_sensor_t *sensor, 1221 skpc_network_id_t network_id, 1222 skpc_direction_t dir); 1223 1224 1225 /** 1226 * Function to set the list of interfaces or IPs associated with 1227 * the network 'network_id' to those in the group 'group'. The 1228 * list of 'network_id's is defined by the packing logic plug-in 1229 * that is specified on the rwflowpack command line. 1230 * 1231 * Here, "network" refers to one of the domains that are being 1232 * monitored by the router or other flow collection software. For 1233 * example, a border router joins the internal and external 1234 * networks, and a flow whose source IP is specified in the list of 1235 * external network addresses will be considered incoming. 1236 * 1237 * The 'group' must be frozen. 1238 * 1239 * The function returns 0 on success, or -1 if the group is NULL, 1240 * not frozen, or empty. 1241 * 1242 * The skpcSensorSetNetworkGroup() function will return an error if 1243 * it is called multiple times for the same network or if 1244 * the skpcSensorSetNetworkDirection() function has already assigned all 1245 * source or destination traffic to this 'network_id'. 1246 */ 1247 int 1248 skpcSensorSetNetworkGroup( 1249 skpc_sensor_t *sensor, 1250 skpc_network_id_t network_id, 1251 const skpc_group_t *ip_group); 1252 1253 1254 /** 1255 * Sets the list of interfaces or IPs that are part of the network 1256 * 'network_id' to all those that not assigned to another 1257 * interface. The list of 'network_id's is defined by the packing 1258 * logic plug-in that is specified on the rwflowpack command line. 1259 */ 1260 int 1261 skpcSensorSetNetworkRemainder( 1262 skpc_sensor_t *sensor, 1263 skpc_network_id_t network_id, 1264 skpc_group_type_t group_type); 1265 1266 1267 /** 1268 * Sets the group of SNMP interfaces that connect to the network 1269 * whose ID is 'network_id' to 0, the SNMP interface value used by 1270 * Cisco to designate a non-routed flow. The network may not have 1271 * been previously set. Return 0 on success, or non-zero on 1272 * failure. 1273 */ 1274 int 1275 skpcSensorSetDefaultNonrouted( 1276 skpc_sensor_t *sensor, 1277 skpc_network_id_t network_id); 1278 1279 1280 /** 1281 * Appends to 'out_probe_vec' all the probes defined on 'sensor'. 1282 * Returns the number of probes defined on 'sensor'. Returns 0 if 1283 * no probes are defined or if there is a memory error appending 1284 * the probes to the vector. If 'out_probe_vec' is NULL, the count 1285 * of probes on sensors is returned. 'out_probe_vec' should be a 1286 * vector having elements of size sizeof(skpc_probe_t*). The 1287 * caller should not modify nor free the values appended to the 1288 * vector. 1289 */ 1290 uint32_t 1291 skpcSensorGetProbes( 1292 const skpc_sensor_t *sensor, 1293 sk_vector_t *out_probe_vec); 1294 1295 1296 /** 1297 * Copy the probes listed in 'probe_vec' onto 'sensor'. 1298 * 1299 * Return 0 on success, or -1 if 'probe_vec' is NULL or empty, or 1300 * if memory allocation fails. 1301 */ 1302 int 1303 skpcSensorSetProbes( 1304 skpc_sensor_t *sensor, 1305 const sk_vector_t *probe_vec); 1306 1307 1308 /** 1309 * Count the number of SNMP interfaces that have been mapped to a 1310 * flowtype on 'sensor'. Will exclude the network ID 1311 * 'ignored_network_id'; pass SKPC_NETWORK_ID_INVALID or a negative 1312 * value in that parameter to ensure that all SNMP interfaces are 1313 * counted. 1314 */ 1315 uint32_t 1316 skpcSensorCountNetflowInterfaces( 1317 const skpc_sensor_t *sensor, 1318 int ignored_network_id); 1319 1320 1321 /** 1322 * Test 'rwrec' against the 'network_id' interfaces---either the 1323 * SNMP values or the IP-block values---on the 'sensor'. The value 1324 * 'rec_dir' tells the function whether to check if the rwrec was 1325 * coming from the specified 'network_id' or going to that network. 1326 * 1327 * The function returns 1 if there is a match, -1 if there was not 1328 * a match, and 0 if neither an IP block list nor an SNMP interface 1329 * list was defined for the 'network_id'. 1330 * 1331 * If 'rec_dir' is SKPC_DIR_SRC, the function checks the record's 1332 * sIP against the list of IP blocks for the 'network_id'. If no 1333 * IP blocks are defined for the specified 'network_id' on this 1334 * 'sensor', the function checks the record's SNMP input interface 1335 * against the list of SNMP interfaces for the 'network_id'. When 1336 * 'rec_dir' is SKPC_DIR_DST, the record's dIP and SNMP output 1337 * values are checked. 1338 */ 1339 int 1340 skpcSensorTestFlowInterfaces( 1341 const skpc_sensor_t *sensor, 1342 const rwRec *rwrec, 1343 skpc_network_id_t network_id, 1344 skpc_direction_t rec_dir); 1345 1346 1347 /** 1348 * Check whether 'rwrec' matches the filters specified on 'sensor'. 1349 * Return 0 if the flow should be packed, or non-zero to discard 1350 * the flow. 1351 * 1352 * When 'rwrec' matches any "discard-when" filter on 'sensor', this 1353 * function returns non-zero. Otherwise, if no "discard-unless" 1354 * filters exist, the function returns 0. 1355 * 1356 * If any "discard-unless" filters exist on 'sensor', 'rwrec' must 1357 * match EVERY one of them for the function to return 0. 1358 */ 1359 int 1360 skpcSensorCheckFilters( 1361 const skpc_sensor_t *sensor, 1362 const rwRec *rwrec); 1363 1364 1365 /** 1366 * Verify that 'sensor' is valid. For example, that if its probe 1367 * is an IPFIX probe, the sensor has ipblocks are defined, etc. If 1368 * 'site_sensor_verify_fn' is defined, it will be called to verify 1369 * the sensor for the current site. That function should return 0 1370 * if the sensor is valid, or non-zero if not valid. 1371 * 1372 * Returns 0 if it is valid, non-zero otherwise. 1373 */ 1374 int 1375 skpcSensorVerify( 1376 skpc_sensor_t *sensor, 1377 int (*site_sensor_verify_fn)(skpc_sensor_t *sensor)); 1378 1379 1380 1381 /* 1382 * ***** Groups ***************************************************** 1383 */ 1384 1385 1386 /** 1387 * Create a new group and fill in 'group' with the address of the 1388 * newly allocated group. 1389 */ 1390 int 1391 skpcGroupCreate( 1392 skpc_group_t **group); 1393 1394 1395 /** 1396 * Destroy the group at '**group' and free all memory. Sets *group 1397 * to NULL. Does nothing if 'group' or the location it points to 1398 * is NULL. 1399 */ 1400 void 1401 skpcGroupDestroy( 1402 skpc_group_t **group); 1403 1404 1405 /** 1406 * Specifies that no changes can be made to the group (other than 1407 * destroying it). Returns 0 on success, or -1 if there is a 1408 * memory allocation failure. (Freezing a group may allocate 1409 * memory as data is rearranged in the group.) 1410 * 1411 * Freezing a frozen group is no-op, and the function returns 0. 1412 */ 1413 int 1414 skpcGroupFreeze( 1415 skpc_group_t *group); 1416 1417 1418 /** 1419 * Get the name of a group. 1420 * 1421 * A group can be anonymous---that is, not have a name. These 1422 * groups are created when an interface or ipblock list is specified 1423 * outside of a "group" block; for example, by listing integers (or 1424 * multiple groups) on in "internal-interfaces" statement. For 1425 * these groups, the name is NULL. 1426 * 1427 * The function returns the name of the group. The caller 1428 * should not modify the name, and does not need to free() it. 1429 */ 1430 const char * 1431 skpcGroupGetName( 1432 const skpc_group_t *group); 1433 1434 /** 1435 * Set the name of a group. A group name must 1436 * meet all the requirements of a sensor name. 1437 * 1438 * The set function makes a copy of 'name' and returns 0 on 1439 * success, non-zero on memory allocation failure. The set 1440 * function also returns non-zero if the group is frozen (see 1441 * skpcGroupFreeze()). 1442 */ 1443 int 1444 skpcGroupSetName( 1445 skpc_group_t *group, 1446 const char *group_name); 1447 1448 1449 /** 1450 * Get the groups's type; that is, whether it stores IP-blocks or 1451 * interface values. 1452 * 1453 * Until it has been set, the group's type is SKPC_GROUP_UNSET. 1454 */ 1455 skpc_group_type_t 1456 skpcGroupGetType( 1457 const skpc_group_t *group); 1458 1459 /** 1460 * Set the groups's type. 1461 * 1462 * The set function returns -1 if the type of the group has been 1463 * previously set or if the group is frozen (see 1464 * skpcGroupFreeze()). 1465 */ 1466 int 1467 skpcGroupSetType( 1468 skpc_group_t *group, 1469 skpc_group_type_t group_type); 1470 1471 1472 /** 1473 * Add the values in 'vec' to the group 'group'. If the type of 1474 * 'group' is SKPC_GROUP_INTERFACE, 'vec' should contain 1475 * uint32_t's. If the type of 'group' is SKPC_GROUP_IPBLOCK, 'vec' 1476 * should contain pointers to skIPWildcard_t. 1477 * 1478 * When 'vec' contains skIPWildcard_t*, this function assumes 1479 * ownership of the data and will free the skIPWildcard_t when 1480 * skpcTeardown() is called. 1481 * 1482 * The function returns 0 on success. It also returns 0 when 'vec' 1483 * is NULL or contains no elements. 1484 * 1485 * Return -1 if the group is frozen, if the group's type is 1486 * SKPC_GROUP_UNSET, if the size of elements in the 'vec' is not 1487 * consistent with the group's type, or if there is a memory 1488 * allocation error. 1489 */ 1490 int 1491 skpcGroupAddValues( 1492 skpc_group_t *group, 1493 const sk_vector_t *vec); 1494 1495 1496 /** 1497 * Add the contents of group 'g' to group 'group'. 1498 * 1499 * Return 0 on success. Also return 0 if 'g' is NULL or if 1500 * contains no items. 1501 * 1502 * Return -1 if 'group' is frozen, if 'g' is NOT frozen, if the 1503 * groups' types are different, or if there is a memory allocation 1504 * error. 1505 */ 1506 int 1507 skpcGroupAddGroup( 1508 skpc_group_t *group, 1509 const skpc_group_t *g); 1510 1511 1512 /** 1513 * Return 1 if 'group' is frozen; 0 otherwise. 1514 */ 1515 int 1516 skpcGroupIsFrozen( 1517 const skpc_group_t *group); 1518 1519 1520 /** 1521 * Returns the group named 'group_name'. Returns NULL if not found 1522 * of if 'group_name' is NULL. The returned group is frozen. 1523 */ 1524 skpc_group_t * 1525 skpcGroupLookupByName( 1526 const char *group_name); 1527 1528 1529 /** 1530 * Return the printable respresentation of the group type. 1531 * 1532 * Return NULL when given an illegal value. 1533 */ 1534 const char * 1535 skpcGrouptypeEnumtoName( 1536 skpc_group_type_t type); 1537 1538 1539 #ifdef __cplusplus 1540 } 1541 #endif 1542 #endif /* _PROBECONF_H */ 1543 1544 /* 1545 ** Local Variables: 1546 ** mode:c 1547 ** indent-tabs-mode:nil 1548 ** c-basic-offset:4 1549 ** End: 1550 */ 1551