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 #include <silk/silk.h>
10
11 RCSIDENT("$SiLK: probeconf.c 7af5eab585e4 2020-04-15 15:56:48Z mthomas $");
12
13 #include <silk/libflowsource.h>
14 #include <silk/probeconf.h>
15 #include <silk/rwrec.h>
16 #include <silk/skipaddr.h>
17 #include <silk/skipset.h>
18 #include <silk/sklog.h>
19 #include <silk/sksite.h>
20 #include "probeconfscan.h"
21
22 #if SK_ENABLE_IPFIX
23 #include "ipfixsource.h" /* for extern of show_templates */
24 #endif
25
26 /*
27 * ***** Flow Type **************************************************
28 *
29 * The probe is used to determine the flow-type---as defined by in
30 * the silk.conf file---of a flow record (rwRec) read from that
31 * probe.
32 *
33 * The skpcProbeDetermineFlowtype() function is defined in the
34 * probeconf-<$SILK_SITE>.c file.
35 *
36 */
37
38 /* LOCAL DEFINES AND TYPEDEFS */
39
40 /* Minimum version of libfixbuf required for IPFIX */
41 #define SKPC_LIBFIXBUF_VERSION_IPFIX "1.7.0"
42
43 /* Minimum version of libfixbuf required for NetFlow V9 */
44 #define SKPC_LIBFIXBUF_VERSION_NETFLOWV9 SKPC_LIBFIXBUF_VERSION_IPFIX
45
46 /* Minimum version of libfixbuf required for sFlow */
47 #define SKPC_LIBFIXBUF_VERSION_SFLOW SKPC_LIBFIXBUF_VERSION_IPFIX
48
49 /* Maximum valid value for a port 2^16 - 1 */
50 #define PORT_VALID_MAX 0xFFFF
51
52 /* Set ports to this invalid value initially */
53 #define PORT_NOT_SET 0xFFFFFFFF
54
55 /* Value to use for remaining IPs to say that it hasn't been set */
56 #define REMAINDER_NOT_SET INT8_MAX
57
58 /* Name of environment variable that, when set, causes SiLK to print
59 * the templates that it receives to the log. This adds
60 * SOURCE_LOG_TEMPLATES to a probe's log_flags, but it also sets the
61 * global `show_templates` variable used by UDP collectors. */
62 #define SK_ENV_PRINT_TEMPLATES "SILK_IPFIX_PRINT_TEMPLATES"
63
64
65 /* a map between probe types and printable names */
66 static const struct probe_type_name_map_st {
67 const char *name;
68 skpc_probetype_t value;
69 } probe_type_name_map[] = {
70 {"ipfix", PROBE_ENUM_IPFIX},
71 {"netflow-v5", PROBE_ENUM_NETFLOW_V5},
72 {"netflow-v9", PROBE_ENUM_NETFLOW_V9},
73 {"sflow", PROBE_ENUM_SFLOW},
74 {"silk", PROBE_ENUM_SILK},
75
76 /* legacy name for netflow-v5 */
77 {"netflow", PROBE_ENUM_NETFLOW_V5},
78
79 /* sentinel */
80 {NULL, PROBE_ENUM_INVALID}
81 };
82
83 /* a map between protocols and printable names */
84 static const struct skpc_protocol_name_map_st {
85 const char *name;
86 uint8_t num;
87 skpc_proto_t value;
88 } skpc_protocol_name_map[] = {
89 {"sctp", 132, SKPC_PROTO_SCTP},
90 {"tcp", 6, SKPC_PROTO_TCP},
91 {"udp", 17, SKPC_PROTO_UDP},
92
93 /* sentinel */
94 {NULL, 0, SKPC_PROTO_UNSET}
95 };
96
97 /* a map between the probe log-flags values and printable names */
98 static const struct skpc_log_flags_map_st {
99 const char *name;
100 uint8_t flag;
101 } skpc_log_flags_map[] = {
102 {"all", SOURCE_LOG_ALL},
103 {"bad", SOURCE_LOG_BAD},
104 {"default", SOURCE_LOG_DEFAULT},
105 {"firewall-event", SOURCE_LOG_FIREWALL},
106 #ifdef SOURCE_LOG_LIBFIXBUF
107 {"libfixbuf", SOURCE_LOG_LIBFIXBUF},
108 #endif /* SOURCE_LOG_LIBFIXBUF */
109 {"missing", SOURCE_LOG_MISSING},
110 {"none", SOURCE_LOG_NONE},
111 {"record-timestamps", SOURCE_LOG_TIMESTAMPS},
112 {"sampling", SOURCE_LOG_SAMPLING},
113 {"show-templates", SOURCE_LOG_TEMPLATES},
114 {NULL, 0}
115 };
116
117 /* a map between the probe quirks values and printable names */
118 static const struct skpc_quirks_map_st {
119 const char *name;
120 uint8_t flag;
121 } skpc_quirks_map[] = {
122 {"firewall-event", SKPC_QUIRK_FW_EVENT},
123 {"missing-ips", SKPC_QUIRK_MISSING_IPS},
124 {"nf9-out-is-reverse", SKPC_QUIRK_NF9_OUT_IS_REVERSE},
125 {"nf9-sysuptime-seconds", SKPC_QUIRK_NF9_SYSUPTIME_SECS},
126 {"none", SKPC_QUIRK_NONE},
127 {"zero-packets", SKPC_QUIRK_ZERO_PACKETS},
128 {NULL, 0}
129 };
130
131
132
133 /* EXPORTED VARIABLE DEFINITIONS */
134
135 /*
136 * If non-zero, print the templates when they arrive. This can be
137 * set by defining the environment variable specified in
138 * SK_ENV_PRINT_TEMPLATES ("SILK_IPFIX_PRINT_TEMPLATES").
139 *
140 * When this variable is true, the SOURCE_LOG_TEMPLATES bit is set
141 * on a probe's flags. The variable needs to be public since it is
142 * required for UDP ipfix collectors due to the way that fixbuf
143 * sets (or doesn't set) the context variables.
144 */
145 #if !SK_ENABLE_IPFIX
146 static
147 #endif
148 int show_templates = 0;
149
150
151 /* LOCAL VARIABLES */
152
153 /* The probes that have been created and verified */
154 static sk_vector_t *skpc_probes = NULL;
155
156 /* The sensors that have been created and verified */
157 static sk_vector_t *skpc_sensors = NULL;
158
159 /* The networks that have been created */
160 static sk_vector_t *skpc_networks = NULL;
161
162 /* The groups that have been created */
163 static sk_vector_t *skpc_groups = NULL;
164
165 /* The IPWildcards that are added to the groups. */
166 static sk_vector_t *skpc_wildcards = NULL;
167
168 /* Group containing the default non-routed NetFlow interface */
169 static skpc_group_t *nonrouted_group = NULL;
170
171
172 /* LOCAL FUNCTION PROTOTYPES */
173
174 static int
175 skpcGroupCheckInterface(
176 const skpc_group_t *group,
177 uint32_t interface);
178 static int
179 skpcGroupCheckIPblock(
180 const skpc_group_t *group,
181 const skipaddr_t *ip);
182 static int
183 skpcGroupCheckIPset(
184 const skpc_group_t *group,
185 const skipaddr_t *ip);
186 static int
187 skpcGroupComputeComplement(
188 skpc_group_t *group);
189 static uint32_t
190 skpcGroupGetItemCount(
191 const skpc_group_t *group);
192
193
194 /* FUNCTION DEFINITIONS */
195
196
197 /*
198 * ***** Probe configuration **************************************
199 */
200
201 /* setup the probes */
202 int
skpcSetup(void)203 skpcSetup(
204 void)
205 {
206 const char *env;
207
208 /* Determine whether to write templates to the log file as they
209 * arrive. */
210 env = getenv(SK_ENV_PRINT_TEMPLATES);
211 if (NULL != env && *env && strcmp("0", env)) {
212 show_templates = 1;
213 }
214
215 if (NULL == skpc_probes) {
216 skpc_probes = skVectorNew(sizeof(skpc_probe_t*));
217 if (NULL == skpc_probes) {
218 goto ERROR;
219 }
220 }
221
222 if (NULL == skpc_sensors) {
223 skpc_sensors = skVectorNew(sizeof(skpc_sensor_t*));
224 if (NULL == skpc_sensors) {
225 goto ERROR;
226 }
227 }
228
229 if (NULL == skpc_networks) {
230 skpc_networks = skVectorNew(sizeof(skpc_network_t));
231 if (NULL == skpc_networks) {
232 goto ERROR;
233 }
234 }
235
236 if (NULL == skpc_groups) {
237 skpc_groups = skVectorNew(sizeof(skpc_group_t*));
238 if (NULL == skpc_groups) {
239 goto ERROR;
240 }
241 }
242
243 if (skpcParseSetup()) {
244 goto ERROR;
245 }
246
247 return 0;
248
249 ERROR:
250 if (skpc_probes) {
251 skVectorDestroy(skpc_probes);
252 }
253 if (skpc_sensors) {
254 skVectorDestroy(skpc_sensors);
255 }
256 if (skpc_networks) {
257 skVectorDestroy(skpc_networks);
258 }
259 if (skpc_groups) {
260 skVectorDestroy(skpc_groups);
261 }
262 return -1;
263 }
264
265
266 /* destroy everything */
267 void
skpcTeardown(void)268 skpcTeardown(
269 void)
270 {
271 skpc_network_t *nwp;
272 skpc_probe_t **probe;
273 skpc_sensor_t **sensor;
274 skpc_group_t **group;
275 skIPWildcard_t **ipwild;
276 size_t i;
277
278 /* clean up the parser */
279 skpcParseTeardown();
280
281 /* Free all the networks */
282 if (skpc_networks) {
283 for (i = 0;
284 (nwp = (skpc_network_t*)skVectorGetValuePointer(skpc_networks, i))
285 != NULL;
286 ++i)
287 {
288 free(nwp->name);
289 }
290
291 /* destroy the vector itself */
292 skVectorDestroy(skpc_networks);
293 skpc_networks = NULL;
294 }
295
296 /* Free all the groups */
297 if (skpc_groups) {
298 for (i = 0;
299 (group = (skpc_group_t**)skVectorGetValuePointer(skpc_groups, i))
300 != NULL;
301 ++i)
302 {
303 skpcGroupDestroy(group);
304 }
305 /* destroy the vector itself */
306 skVectorDestroy(skpc_groups);
307 skpc_groups = NULL;
308 }
309
310 /* Free all the sensors */
311 if (skpc_sensors) {
312 for (i = 0;
313 (sensor=(skpc_sensor_t**)skVectorGetValuePointer(skpc_sensors, i))
314 != NULL;
315 ++i)
316 {
317 skpcSensorDestroy(sensor);
318 }
319 /* destroy the vector itself */
320 skVectorDestroy(skpc_sensors);
321 skpc_sensors = NULL;
322 }
323
324 /* Free all the probes */
325 if (skpc_probes) {
326 for (i = 0;
327 (probe = (skpc_probe_t**)skVectorGetValuePointer(skpc_probes, i))
328 != NULL;
329 ++i)
330 {
331 skpcProbeDestroy(probe);
332 }
333 /* destroy the vector itself */
334 skVectorDestroy(skpc_probes);
335 skpc_probes = NULL;
336 }
337
338 /* Free all the wildcards */
339 if (skpc_wildcards) {
340 for (i = 0;
341 (ipwild = ((skIPWildcard_t**)
342 skVectorGetValuePointer(skpc_wildcards, i)))
343 != NULL;
344 ++i)
345 {
346 free(*ipwild);
347 *ipwild = NULL;
348 }
349 /* destroy the vector itself */
350 skVectorDestroy(skpc_wildcards);
351 skpc_wildcards = NULL;
352 }
353 }
354
355
356 /* return a count of verified probes */
357 size_t
skpcCountProbes(void)358 skpcCountProbes(
359 void)
360 {
361 assert(skpc_probes);
362 return skVectorGetCount(skpc_probes);
363 }
364
365
366 int
skpcProbeIteratorBind(skpc_probe_iter_t * probe_iter)367 skpcProbeIteratorBind(
368 skpc_probe_iter_t *probe_iter)
369 {
370 if (probe_iter == NULL || skpc_probes == NULL) {
371 return -1;
372 }
373 probe_iter->cur = 0;
374 return 0;
375 }
376
377
378 int
skpcProbeIteratorNext(skpc_probe_iter_t * probe_iter,const skpc_probe_t ** probe)379 skpcProbeIteratorNext(
380 skpc_probe_iter_t *probe_iter,
381 const skpc_probe_t **probe)
382 {
383 if (probe_iter == NULL || probe == NULL) {
384 return -1;
385 }
386
387 if (0 != skVectorGetValue((void*)probe, skpc_probes, probe_iter->cur)) {
388 return 0;
389 }
390
391 ++probe_iter->cur;
392 return 1;
393 }
394
395
396 /* return a probe having the given probe-name. */
397 const skpc_probe_t *
skpcProbeLookupByName(const char * probe_name)398 skpcProbeLookupByName(
399 const char *probe_name)
400 {
401 const skpc_probe_t **probe;
402 size_t i;
403
404 assert(skpc_probes);
405
406 /* check input */
407 if (probe_name == NULL) {
408 return NULL;
409 }
410
411 /* loop over all probes until we find one with given name */
412 for (i = 0;
413 (probe=(const skpc_probe_t**)skVectorGetValuePointer(skpc_probes, i))
414 != NULL;
415 ++i)
416 {
417 if (0 == strcmp(probe_name, (*probe)->probe_name)) {
418 return *probe;
419 }
420 }
421
422 return NULL;
423 }
424
425
426 /* return a count of verified sensors */
427 size_t
skpcCountSensors(void)428 skpcCountSensors(
429 void)
430 {
431 assert(skpc_sensors);
432 return skVectorGetCount(skpc_sensors);
433 }
434
435
436 int
skpcSensorIteratorBind(skpc_sensor_iter_t * sensor_iter)437 skpcSensorIteratorBind(
438 skpc_sensor_iter_t *sensor_iter)
439 {
440 if (sensor_iter == NULL || skpc_sensors == NULL) {
441 return -1;
442 }
443 sensor_iter->cur = 0;
444 return 0;
445 }
446
447
448 int
skpcSensorIteratorNext(skpc_sensor_iter_t * sensor_iter,const skpc_sensor_t ** sensor)449 skpcSensorIteratorNext(
450 skpc_sensor_iter_t *sensor_iter,
451 const skpc_sensor_t **sensor)
452 {
453 if (sensor_iter == NULL || sensor == NULL) {
454 return -1;
455 }
456
457 if (0 != skVectorGetValue((void*)sensor, skpc_sensors, sensor_iter->cur)) {
458 return 0;
459 }
460
461 ++sensor_iter->cur;
462 return 1;
463 }
464
465
466 /* append to sensor_vec sensors having the given sensor-name. */
467 int
skpcSensorLookupByName(const char * sensor_name,sk_vector_t * sensor_vec)468 skpcSensorLookupByName(
469 const char *sensor_name,
470 sk_vector_t *sensor_vec)
471 {
472 const skpc_sensor_t **s;
473 int count = 0;
474 size_t i;
475
476 assert(skpc_sensors);
477
478 /* check input */
479 if (sensor_name == NULL || sensor_vec == NULL) {
480 return -1;
481 }
482 if (skVectorGetElementSize(sensor_vec) != sizeof(skpc_sensor_t*)) {
483 return -1;
484 }
485
486 /* loop over all sensors looking for the given name */
487 for (i = 0;
488 (s = (const skpc_sensor_t**)skVectorGetValuePointer(skpc_sensors, i))
489 != NULL;
490 ++i)
491 {
492 if (0 == strcmp(sensor_name, (*s)->sensor_name)) {
493 if (skVectorAppendValue(sensor_vec, s)) {
494 return -1;
495 }
496 ++count;
497 }
498 }
499
500 return count;
501 }
502
503
504 /* append to sensor_vec sensors having the given sensor-name. */
505 int
skpcSensorLookupByID(sk_sensor_id_t sensor_id,sk_vector_t * sensor_vec)506 skpcSensorLookupByID(
507 sk_sensor_id_t sensor_id,
508 sk_vector_t *sensor_vec)
509 {
510 const skpc_sensor_t **s;
511 int count = 0;
512 size_t i;
513
514 assert(skpc_sensors);
515
516 /* check input */
517 if (sensor_vec == NULL) {
518 return -1;
519 }
520 if (skVectorGetElementSize(sensor_vec) != sizeof(skpc_sensor_t*)) {
521 return -1;
522 }
523
524 /* loop over all sensors looking for the given id */
525 for (i = 0;
526 (s = (const skpc_sensor_t**)skVectorGetValuePointer(skpc_sensors, i))
527 != NULL;
528 ++i)
529 {
530 if (sensor_id == (*s)->sensor_id) {
531 if (skVectorAppendValue(sensor_vec, s)) {
532 return -1;
533 }
534 ++count;
535 }
536 }
537
538 return count;
539 }
540
541
542 /*
543 * ***** Network ****************************************************
544 */
545
546 /* Add a new id->name pair to the list of networks */
547 int
skpcNetworkAdd(skpc_network_id_t id,const char * name)548 skpcNetworkAdd(
549 skpc_network_id_t id,
550 const char *name)
551 {
552 skpc_network_t *nwp;
553 skpc_network_t nw;
554 size_t i;
555
556 assert(skpc_networks);
557
558 if (id > SKPC_NETWORK_ID_MAX) {
559 return -4;
560 }
561
562 /* check for */
563 for (i = 0;
564 (nwp = (skpc_network_t*)skVectorGetValuePointer(skpc_networks, i))
565 != NULL;
566 ++i)
567 {
568 if (id == nwp->id) {
569 /* duplicate id */
570 return -2;
571 }
572 if (0 == strcmp(name, nwp->name)) {
573 /* duplicate name */
574 return -3;
575 }
576 }
577
578 /* create network and add it to the vector */
579 nw.id = id;
580 nw.name = strdup(name);
581 if (nw.name == NULL) {
582 skAppPrintOutOfMemory(NULL);
583 return -1;
584 }
585 if (skVectorAppendValue(skpc_networks, &nw)) {
586 free(nw.name);
587 return -1;
588 }
589
590 return 0;
591 }
592
593
594 /* Find the network that has the given name 'name' */
595 const skpc_network_t *
skpcNetworkLookupByName(const char * name)596 skpcNetworkLookupByName(
597 const char *name)
598 {
599 skpc_network_t *nwp;
600 size_t i;
601
602 assert(skpc_networks);
603
604 for (i = 0;
605 (nwp = (skpc_network_t*)skVectorGetValuePointer(skpc_networks, i))
606 != NULL;
607 ++i)
608 {
609 if (0 == strcmp(name, nwp->name)) {
610 return nwp;
611 }
612 }
613 return NULL;
614 }
615
616
617 /* Find the network that has the given ID 'id' */
618 const skpc_network_t *
skpcNetworkLookupByID(skpc_network_id_t network_id)619 skpcNetworkLookupByID(
620 skpc_network_id_t network_id)
621 {
622 skpc_network_t *nwp;
623 size_t i;
624
625 assert(skpc_networks);
626 assert(network_id <= SKPC_NETWORK_ID_INVALID);
627
628 for (i = 0;
629 (nwp = (skpc_network_t*)skVectorGetValuePointer(skpc_networks, i))
630 != NULL;
631 ++i)
632 {
633 if (network_id == nwp->id) {
634 return nwp;
635 }
636 }
637 return NULL;
638 }
639
640
641
642 /*
643 * ***** Probes *****************************************************
644 */
645
646 /* Create a probe */
647 int
skpcProbeCreate(skpc_probe_t ** probe,skpc_probetype_t probe_type)648 skpcProbeCreate(
649 skpc_probe_t **probe,
650 skpc_probetype_t probe_type)
651 {
652 assert(probe);
653
654 if (NULL == skpcProbetypeEnumtoName(probe_type)) {
655 return -1;
656 }
657
658 (*probe) = (skpc_probe_t*)calloc(1, sizeof(skpc_probe_t));
659 if (NULL == (*probe)) {
660 return -1;
661 }
662
663 (*probe)->probe_type = probe_type;
664 (*probe)->protocol = SKPC_PROTO_UNSET;
665 skpcProbeAddLogFlag(*probe, "default");
666
667 return 0;
668 }
669
670
671 /* Destroy a probe and free all memory associated with it */
672 void
skpcProbeDestroy(skpc_probe_t ** probe)673 skpcProbeDestroy(
674 skpc_probe_t **probe)
675 {
676 uint32_t i;
677
678 if (!probe || !(*probe)) {
679 return;
680 }
681
682 if ((*probe)->sensor_list) {
683 free((*probe)->sensor_list);
684 }
685 if ((*probe)->unix_domain_path) {
686 free((*probe)->unix_domain_path);
687 }
688 if ((*probe)->file_source) {
689 free((*probe)->file_source);
690 }
691 if ((*probe)->poll_directory) {
692 free((*probe)->poll_directory);
693 }
694 if ((*probe)->probe_name) {
695 free((void *)((*probe)->probe_name));
696 }
697 if ((*probe)->listen_addr) {
698 skSockaddrArrayDestroy((*probe)->listen_addr);
699 }
700 if ((*probe)->accept_from_addr) {
701 for (i = 0; i < (*probe)->accept_from_addr_count; ++i) {
702 skSockaddrArrayDestroy((*probe)->accept_from_addr[i]);
703 }
704 free((*probe)->accept_from_addr);
705 }
706
707 free(*probe);
708 *probe = NULL;
709 }
710
711
712 /* Get and set the name of probe */
713
714 #ifndef skpcProbeGetName
715 const char *
skpcProbeGetName(const skpc_probe_t * probe)716 skpcProbeGetName(
717 const skpc_probe_t *probe)
718 {
719 assert(probe);
720 return probe->probe_name;
721 }
722 #endif /* skpcProbeGetName */
723
724 int
skpcProbeSetName(skpc_probe_t * probe,const char * name)725 skpcProbeSetName(
726 skpc_probe_t *probe,
727 const char *name)
728 {
729 const char *cp;
730 char *copy;
731
732 assert(probe);
733 if (name == NULL || name[0] == '\0') {
734 return -1;
735 }
736
737 /* check for illegal characters */
738 cp = name;
739 while (*cp) {
740 if (*cp == '/' || isspace((int)*cp)) {
741 return -1;
742 }
743 ++cp;
744 }
745
746 copy = strdup(name);
747 if (copy == NULL) {
748 skAppPrintOutOfMemory(NULL);
749 return -1;
750 }
751 if (probe->probe_name) {
752 free((void *)probe->probe_name);
753 }
754 probe->probe_name = copy;
755 return 0;
756 }
757
758
759 /* Get and set the probe type */
760 #ifndef skpcProbeGetType
761 skpc_probetype_t
skpcProbeGetType(const skpc_probe_t * probe)762 skpcProbeGetType(
763 const skpc_probe_t *probe)
764 {
765 assert(probe);
766 return probe->probe_type;
767 }
768 #endif /* skpcProbeGetType */
769
770
771 /* Get and set the probe's protocol */
772 #ifndef skpcProbeGetProtocol
773 skpc_proto_t
skpcProbeGetProtocol(const skpc_probe_t * probe)774 skpcProbeGetProtocol(
775 const skpc_probe_t *probe)
776 {
777 assert(probe);
778 return probe->protocol;
779 }
780 #endif /* skpcProbeGetProtocol */
781
782 int
skpcProbeSetProtocol(skpc_probe_t * probe,skpc_proto_t probe_protocol)783 skpcProbeSetProtocol(
784 skpc_probe_t *probe,
785 skpc_proto_t probe_protocol)
786 {
787 assert(probe);
788
789 if (NULL == skpcProtocolEnumToName(probe_protocol)) {
790 return -1;
791 }
792 probe->protocol = probe_protocol;
793 return 0;
794 }
795
796
797 /* Get and set probe log-flags */
798 #ifndef skpcProbeGetLogFlags
799 uint8_t
skpcProbeGetLogFlags(const skpc_probe_t * probe)800 skpcProbeGetLogFlags(
801 const skpc_probe_t *probe)
802 {
803 assert(probe);
804 return probe->log_flags;
805 }
806 #endif /* skpcProbeGetLogFlags */
807
808 int
skpcProbeAddLogFlag(skpc_probe_t * probe,const char * log_flag)809 skpcProbeAddLogFlag(
810 skpc_probe_t *probe,
811 const char *log_flag)
812 {
813 size_t i;
814 int rv;
815
816 assert(probe);
817
818 if (NULL == log_flag) {
819 return -1;
820 }
821
822 rv = 1;
823 for (i = 0; skpc_log_flags_map[i].name != NULL; ++i) {
824 /* assert names in table are sorted alphabetically */
825 assert(NULL == skpc_log_flags_map[i + 1].name
826 || strcmp(skpc_log_flags_map[i].name,
827 skpc_log_flags_map[i + 1].name) < 0);
828 rv = strcmp(log_flag, skpc_log_flags_map[i].name);
829 if (rv <= 0) {
830 break;
831 }
832 }
833 if (0 != rv) {
834 /* unrecognized log-flag */
835 return -1;
836 }
837 if (SOURCE_LOG_NONE == skpc_log_flags_map[i].flag && probe->log_flags) {
838 assert(0 == strcmp("none", log_flag));
839 /* invalid combination */
840 return -2;
841 }
842 probe->log_flags |= skpc_log_flags_map[i].flag;
843 if (show_templates) {
844 probe->log_flags |= SOURCE_LOG_TEMPLATES;
845 }
846 return 0;
847 }
848
849 int
skpcProbeClearLogFlags(skpc_probe_t * probe)850 skpcProbeClearLogFlags(
851 skpc_probe_t *probe)
852 {
853 assert(probe);
854 probe->log_flags = SOURCE_LOG_NONE;
855 if (show_templates) {
856 probe->log_flags |= SOURCE_LOG_TEMPLATES;
857 }
858 return 0;
859 }
860
861
862 /* Get and set type of data in the input/output fields */
863
864 #ifndef skpcProbeGetInterfaceValueType
865 skpc_ifvaluetype_t
skpcProbeGetInterfaceValueType(const skpc_probe_t * probe)866 skpcProbeGetInterfaceValueType(
867 const skpc_probe_t *probe)
868 {
869 assert(probe);
870 return probe->ifvaluetype;
871 }
872 #endif /* skpcProbeGetInterfaceValueType */
873
874 int
skpcProbeSetInterfaceValueType(skpc_probe_t * probe,skpc_ifvaluetype_t interface_value_type)875 skpcProbeSetInterfaceValueType(
876 skpc_probe_t *probe,
877 skpc_ifvaluetype_t interface_value_type)
878 {
879 assert(probe);
880 switch (interface_value_type) {
881 case SKPC_IFVALUE_SNMP:
882 case SKPC_IFVALUE_VLAN:
883 probe->ifvaluetype = interface_value_type;
884 break;
885 default:
886 return -1; /* NOTREACHED */
887 }
888 return 0;
889 }
890
891
892 /* Get and set any "peculiar" data handling for this probe. */
893 #ifndef skpcProbeGetQuirks
894 uint32_t
skpcProbeGetQuirks(const skpc_probe_t * probe)895 skpcProbeGetQuirks(
896 const skpc_probe_t *probe)
897 {
898 assert(probe);
899 return (uint32_t)probe->quirks;
900 }
901 #endif /* skpcProbeGetQuirks */
902
903 int
skpcProbeAddQuirk(skpc_probe_t * probe,const char * quirk)904 skpcProbeAddQuirk(
905 skpc_probe_t *probe,
906 const char *quirk)
907 {
908 size_t i;
909 int rv;
910
911 assert(probe);
912
913 if (NULL == quirk) {
914 return -1;
915 }
916
917 rv = 1;
918 for (i = 0; skpc_quirks_map[i].name != NULL; ++i) {
919 /* assert names in table are sorted alphabetically */
920 assert(NULL == skpc_quirks_map[i + 1].name
921 || strcmp(skpc_quirks_map[i].name,
922 skpc_quirks_map[i + 1].name) < 0);
923 rv = strcmp(quirk, skpc_quirks_map[i].name);
924 if (rv <= 0) {
925 break;
926 }
927 }
928 if (0 != rv) {
929 /* unrecognized quirk */
930 return -1;
931 }
932 if (SKPC_QUIRK_NONE == skpc_quirks_map[i].flag && probe->quirks) {
933 assert(0 == strcmp("none", quirk));
934 /* invalid combination */
935 return -2;
936 }
937 probe->quirks |= skpc_quirks_map[i].flag;
938 return 0;
939 }
940
941 int
skpcProbeClearQuirks(skpc_probe_t * probe)942 skpcProbeClearQuirks(
943 skpc_probe_t *probe)
944 {
945 assert(probe);
946 probe->quirks = 0;
947 return 0;
948 }
949
950
951 /* Get and set host:port to listen on. */
952 int
skpcProbeGetListenOnSockaddr(const skpc_probe_t * probe,const sk_sockaddr_array_t ** addr)953 skpcProbeGetListenOnSockaddr(
954 const skpc_probe_t *probe,
955 const sk_sockaddr_array_t **addr)
956 {
957 assert(probe);
958 if (probe->listen_addr == NULL) {
959 return -1;
960 }
961
962 if (addr) {
963 *addr = probe->listen_addr;
964 }
965 return 0;
966 }
967
968 int
skpcProbeSetListenOnSockaddr(skpc_probe_t * probe,sk_sockaddr_array_t * addr)969 skpcProbeSetListenOnSockaddr(
970 skpc_probe_t *probe,
971 sk_sockaddr_array_t *addr)
972 {
973 assert(probe);
974
975 if (probe->listen_addr) {
976 skSockaddrArrayDestroy(probe->listen_addr);
977 }
978
979 probe->listen_addr = addr;
980 return 0;
981 }
982
983
984 /* Get and set the unix domain socket on which to listen. */
985 const char *
skpcProbeGetListenOnUnixDomainSocket(const skpc_probe_t * probe)986 skpcProbeGetListenOnUnixDomainSocket(
987 const skpc_probe_t *probe)
988 {
989 assert(probe);
990 return probe->unix_domain_path;
991 }
992
993 int
skpcProbeSetListenOnUnixDomainSocket(skpc_probe_t * probe,const char * u_socket)994 skpcProbeSetListenOnUnixDomainSocket(
995 skpc_probe_t *probe,
996 const char *u_socket)
997 {
998 char *copy;
999
1000 assert(probe);
1001 if (u_socket == NULL || u_socket[0] == '\0') {
1002 return -1;
1003 }
1004
1005 copy = strdup(u_socket);
1006 if (copy == NULL) {
1007 skAppPrintOutOfMemory(NULL);
1008 return -1;
1009 }
1010 if (probe->unix_domain_path) {
1011 free(probe->unix_domain_path);
1012 }
1013 probe->unix_domain_path = copy;
1014
1015 return 0;
1016 }
1017
1018
1019 /* Get and set the file name to read data from */
1020 const char *
skpcProbeGetFileSource(const skpc_probe_t * probe)1021 skpcProbeGetFileSource(
1022 const skpc_probe_t *probe)
1023 {
1024 assert(probe);
1025 return probe->file_source;
1026 }
1027
1028 int
skpcProbeSetFileSource(skpc_probe_t * probe,const char * pathname)1029 skpcProbeSetFileSource(
1030 skpc_probe_t *probe,
1031 const char *pathname)
1032 {
1033 char *copy;
1034
1035 assert(probe);
1036 if (pathname == NULL || pathname[0] == '\0') {
1037 return -1;
1038 }
1039
1040 copy = strdup(pathname);
1041 if (copy == NULL) {
1042 skAppPrintOutOfMemory(NULL);
1043 return -1;
1044 }
1045 if (probe->file_source) {
1046 free(probe->file_source);
1047 }
1048 probe->file_source = copy;
1049
1050 return 0;
1051 }
1052
1053
1054 /* Get and set the name of the directory to poll for new files */
1055 const char *
skpcProbeGetPollDirectory(const skpc_probe_t * probe)1056 skpcProbeGetPollDirectory(
1057 const skpc_probe_t *probe)
1058 {
1059 assert(probe);
1060 return probe->poll_directory;
1061 }
1062
1063 int
skpcProbeSetPollDirectory(skpc_probe_t * probe,const char * pathname)1064 skpcProbeSetPollDirectory(
1065 skpc_probe_t *probe,
1066 const char *pathname)
1067 {
1068 char *copy;
1069
1070 assert(probe);
1071 if (pathname == NULL || pathname[0] == '\0') {
1072 return -1;
1073 }
1074
1075 copy = strdup(pathname);
1076 if (copy == NULL) {
1077 skAppPrintOutOfMemory(NULL);
1078 return -1;
1079 }
1080
1081 if (probe->poll_directory) {
1082 free(probe->poll_directory);
1083 }
1084 probe->poll_directory = copy;
1085
1086 return 0;
1087 }
1088
1089
1090 /* Get and set host to accept connections from */
1091 uint32_t
skpcProbeGetAcceptFromHost(const skpc_probe_t * probe,const sk_sockaddr_array_t *** addr_array)1092 skpcProbeGetAcceptFromHost(
1093 const skpc_probe_t *probe,
1094 const sk_sockaddr_array_t ***addr_array)
1095 {
1096 assert(probe);
1097 if (addr_array) {
1098 *(sk_sockaddr_array_t***)addr_array = probe->accept_from_addr;
1099 }
1100 return probe->accept_from_addr_count;
1101 }
1102
1103 int
skpcProbeSetAcceptFromHost(skpc_probe_t * probe,const sk_vector_t * addr_vec)1104 skpcProbeSetAcceptFromHost(
1105 skpc_probe_t *probe,
1106 const sk_vector_t *addr_vec)
1107 {
1108 sk_sockaddr_array_t **copy;
1109 uint32_t i;
1110
1111 assert(probe);
1112 if (addr_vec == NULL) {
1113 return -1;
1114 }
1115 if (skVectorGetElementSize(addr_vec) != sizeof(sk_sockaddr_array_t*)) {
1116 return -1;
1117 }
1118
1119 copy = (sk_sockaddr_array_t**)skVectorToArrayAlloc(addr_vec);
1120 if (NULL == copy) {
1121 /* either memory error or empty vector */
1122 if (skVectorGetCount(addr_vec) > 0) {
1123 return -1;
1124 }
1125 }
1126 /* remove previous values */
1127 if (probe->accept_from_addr) {
1128 for (i = 0; i < probe->accept_from_addr_count; ++i) {
1129 skSockaddrArrayDestroy(probe->accept_from_addr[i]);
1130 }
1131 free(probe->accept_from_addr);
1132 }
1133 probe->accept_from_addr = copy;
1134 probe->accept_from_addr_count = skVectorGetCount(addr_vec);
1135
1136 return 0;
1137 }
1138
1139 #ifndef skpcProbeGetSensorCount
1140 size_t
skpcProbeGetSensorCount(const skpc_probe_t * probe)1141 skpcProbeGetSensorCount(
1142 const skpc_probe_t *probe)
1143 {
1144 assert(probe);
1145 return probe->sensor_count;
1146 }
1147 #endif /* skpcProbeGetSensorCount */
1148
1149
1150 static int
skpcProbeAddSensor(skpc_probe_t * probe,skpc_sensor_t * sensor)1151 skpcProbeAddSensor(
1152 skpc_probe_t *probe,
1153 skpc_sensor_t *sensor)
1154 {
1155 #if 0
1156 size_t i;
1157
1158 /* 2011.12.09 Allow the same sensor to appear on a probe multiple
1159 * times, and assume the user is using a filter (e.g.,
1160 * discard-when) to avoid packing the flow record multiple
1161 * times. */
1162 /* each sensor may only appear on a probe one time */
1163 for (i = 0; i < probe->sensor_count; ++i) {
1164 if (skpcSensorGetID(probe->sensor_list[i])
1165 == skpcSensorGetID(sensor))
1166 {
1167 return -1;
1168 }
1169 }
1170 #endif /* 0 */
1171
1172 if (probe->sensor_list == NULL) {
1173 /* create the sensor list; large enough to hold one sensor */
1174 assert(probe->sensor_count == 0);
1175 probe->sensor_list = (skpc_sensor_t**)malloc(sizeof(skpc_sensor_t*));
1176 if (probe->sensor_list == NULL) {
1177 skAppPrintOutOfMemory(NULL);
1178 return -1;
1179 }
1180 } else {
1181 /* grow the sensor list by one */
1182 skpc_sensor_t **old = probe->sensor_list;
1183
1184 probe->sensor_list = ((skpc_sensor_t**)
1185 realloc(probe->sensor_list,
1186 ((1 + probe->sensor_count)
1187 * sizeof(skpc_sensor_t*))));
1188 if (probe->sensor_list == NULL) {
1189 probe->sensor_list = old;
1190 skAppPrintOutOfMemory(NULL);
1191 return -1;
1192 }
1193 }
1194 probe->sensor_list[probe->sensor_count] = sensor;
1195 ++probe->sensor_count;
1196
1197 return 0;
1198 }
1199
1200
1201 /*
1202 * ***** Verification ***********************************************
1203 */
1204
1205
1206
1207 #if SK_ENABLE_IPFIX
1208 /*
1209 * is_valid = skpcProbeVerifyIPFIX(p);
1210 *
1211 * Verify that probe has everything required to collect IPFIX data.
1212 */
1213 static int
skpcProbeVerifyIPFIX(skpc_probe_t * probe)1214 skpcProbeVerifyIPFIX(
1215 skpc_probe_t *probe)
1216 {
1217 /* skpcProbeVerify() should have verified that exactly one
1218 * collection mechanism is defined. This function only needs to
1219 * ensure that this probe type supports that mechanism. */
1220
1221 /* IPFIX does not support reading from files */
1222 if (probe->file_source != NULL) {
1223 return 0;
1224 #if 0
1225 skAppPrintErr(("Error verifying probe '%s':\n"
1226 "\tType '%s' probes do not support"
1227 " the read-from-file clause"),
1228 probe->probe_name,
1229 skpcProbetypeEnumtoName(probe->probe_type));
1230 return -1;
1231 #endif
1232 }
1233
1234 /* IPFIX does not support unix sockets */
1235 if (probe->unix_domain_path != NULL) {
1236 skAppPrintErr(("Error verifying probe '%s':\n"
1237 "\tType '%s' probes do not support"
1238 " the listen-on-unix-socket clause"),
1239 probe->probe_name,
1240 skpcProbetypeEnumtoName(probe->probe_type));
1241 return -1;
1242 }
1243
1244 /* Check for non-directory based options */
1245 if (probe->poll_directory == NULL) {
1246 /* Our IPFIX support only allows UDP and TCP and has no default */
1247 switch (probe->protocol) {
1248 case SKPC_PROTO_UDP:
1249 break;
1250 case SKPC_PROTO_TCP:
1251 break;
1252 case SKPC_PROTO_UNSET:
1253 skAppPrintErr(("Error verifying probe '%s':\n"
1254 "\tType '%s' probes must set"
1255 " the protocol to 'tcp' or 'udp'"),
1256 probe->probe_name,
1257 skpcProbetypeEnumtoName(probe->probe_type));
1258 return -1;
1259 default:
1260 skAppPrintErr(("Error verifying probe '%s':\n"
1261 "\tType '%s' probes only support"
1262 " the 'udp' or 'tcp' protocol"),
1263 probe->probe_name,
1264 skpcProbetypeEnumtoName(probe->probe_type));
1265 return -1;
1266 }
1267 }
1268
1269
1270 return 0;
1271 }
1272 #endif /* SK_ENABLE_IPFIX */
1273
1274
1275 /*
1276 * is_valid = skpcProbeVerifyNetflowV5(p);
1277 *
1278 * Verify that probe has everything required to collect NetFlow-V5
1279 * data.
1280 */
1281 static int
skpcProbeVerifyNetflowV5(skpc_probe_t * probe)1282 skpcProbeVerifyNetflowV5(
1283 skpc_probe_t *probe)
1284 {
1285 /* skpcProbeVerify() should have verified that exactly one
1286 * collection mechanism is defined. This function only needs to
1287 * ensure that this probe type supports that mechanism. */
1288
1289 /* NetFlow does not support unix sockets */
1290 if (probe->unix_domain_path != NULL) {
1291 skAppPrintErr(("Error verifying probe '%s':\n"
1292 "\tType '%s' probes do not support"
1293 " the listen-on-unix-socket clause"),
1294 probe->probe_name,
1295 skpcProbetypeEnumtoName(probe->probe_type));
1296 return -1;
1297 }
1298
1299 /* NetFlow only supports the UDP protocol */
1300 if ((probe->listen_addr != NULL)
1301 && (probe->protocol != SKPC_PROTO_UDP))
1302 {
1303 skAppPrintErr(("Error verifying probe '%s':\n"
1304 "\tType '%s' probes only support"
1305 " the 'udp' protocol"),
1306 probe->probe_name,
1307 skpcProbetypeEnumtoName(probe->probe_type));
1308 return -1;
1309 }
1310
1311 /* NetFlow v5 does not support VLAN interfaces */
1312 if (probe->ifvaluetype != SKPC_IFVALUE_SNMP) {
1313 skAppPrintErr(("Error verifying probe '%s':\n"
1314 "\tType '%s' probes do not have access"
1315 " to vlan information"),
1316 probe->probe_name,
1317 skpcProbetypeEnumtoName(probe->probe_type));
1318 return -1;
1319 }
1320
1321 return 0;
1322 }
1323
1324
1325 #if SK_ENABLE_IPFIX
1326 /*
1327 * is_valid = skpcProbeVerifyNetflowV9(p);
1328 *
1329 * Verify that probe has everything required to collect NetFlow-V9
1330 * data.
1331 */
1332 static int
skpcProbeVerifyNetflowV9(skpc_probe_t * probe)1333 skpcProbeVerifyNetflowV9(
1334 skpc_probe_t *probe)
1335 {
1336 /* skpcProbeVerify() should have verified that exactly one
1337 * collection mechanism is defined. This function only needs to
1338 * ensure that this probe type supports that mechanism. */
1339
1340 /* NetFlow v9 does not support reading from files */
1341 if (probe->file_source != NULL) {
1342 skAppPrintErr(("Error verifying probe '%s':\n"
1343 "\tType '%s' probes do not support"
1344 " the read-from-file clause"),
1345 probe->probe_name,
1346 skpcProbetypeEnumtoName(probe->probe_type));
1347 return -1;
1348 }
1349
1350 /* NetFlow v9 does not support unix sockets */
1351 if (probe->unix_domain_path != NULL) {
1352 skAppPrintErr(("Error verifying probe '%s':\n"
1353 "\tType '%s' probes do not support"
1354 " the listen-on-unix-socket clause"),
1355 probe->probe_name,
1356 skpcProbetypeEnumtoName(probe->probe_type));
1357 return -1;
1358 }
1359
1360 /* NetFlow v9 does not yet support directory polling */
1361 if (probe->poll_directory != NULL) {
1362 skAppPrintErr(("Error verifying probe '%s':\n"
1363 "\tType '%s' probes do not support"
1364 " the poll-directory clause"),
1365 probe->probe_name,
1366 skpcProbetypeEnumtoName(probe->probe_type));
1367 return -1;
1368 }
1369
1370 /* NetFlow only supports the UDP protocol */
1371 if ((probe->listen_addr != NULL)
1372 && (probe->protocol != SKPC_PROTO_UDP))
1373 {
1374 skAppPrintErr(("Error verifying probe '%s':\n"
1375 "\tType '%s' probes only support"
1376 " the 'udp' protocol"),
1377 probe->probe_name,
1378 skpcProbetypeEnumtoName(probe->probe_type));
1379 return -1;
1380 }
1381
1382 return 0;
1383 }
1384 #endif /* SK_ENABLE_IPFIX */
1385
1386
1387 /*
1388 * is_valid = skpcProbeVerifySilk(p);
1389 *
1390 * Verify that probe has everything required to re-pack SiLK flow
1391 * files.
1392 */
1393 static int
skpcProbeVerifySilk(skpc_probe_t * probe)1394 skpcProbeVerifySilk(
1395 skpc_probe_t *probe)
1396 {
1397 /* The SiLK Flow file probe does not support reading from files */
1398 if (probe->file_source != NULL) {
1399 skAppPrintErr(("Error verifying probe '%s':\n"
1400 "\tType '%s' probes do not support"
1401 " the read-from-file clause"),
1402 probe->probe_name,
1403 skpcProbetypeEnumtoName(probe->probe_type));
1404 return -1;
1405 }
1406
1407 /* When re-packing SiLK Flow files, we do not support
1408 * network-based options. */
1409 if (probe->unix_domain_path != NULL) {
1410 skAppPrintErr(("Error verifying probe '%s':\n"
1411 "\tType '%s' probes do not support"
1412 " the listen-on-unix-socket clause"),
1413 probe->probe_name,
1414 skpcProbetypeEnumtoName(probe->probe_type));
1415 return -1;
1416 }
1417 if (probe->listen_addr != NULL) {
1418 skAppPrintErr(("Error verifying probe '%s':\n"
1419 "\tType '%s' probes do not support"
1420 " listening on the network"),
1421 probe->probe_name,
1422 skpcProbetypeEnumtoName(probe->probe_type));
1423 return -1;
1424 }
1425
1426 return 0;
1427 }
1428
1429
1430 /*
1431 * Verify that the probes 'p1' and 'p2' both have a list of
1432 * accept-from-host addresses and that none of the addresses
1433 * overlap.
1434 *
1435 * Return 0 if there is no overlap. Return -1 if there is overlap
1436 * or if either probe lacks an accept-from-host list.
1437 */
1438 static int
skpcProbeVerifyCompareAcceptFrom(const skpc_probe_t * p1,const skpc_probe_t * p2)1439 skpcProbeVerifyCompareAcceptFrom(
1440 const skpc_probe_t *p1,
1441 const skpc_probe_t *p2)
1442 {
1443 uint32_t i;
1444 uint32_t j;
1445
1446 if (p1->accept_from_addr == NULL || p2->accept_from_addr == NULL) {
1447 return -1;
1448 }
1449 if (p1->accept_from_addr_count == 0 || p2->accept_from_addr_count == 0) {
1450 return -1;
1451 }
1452
1453 for (i = 0; i < p1->accept_from_addr_count; ++i) {
1454 for (j = 0; j < p2->accept_from_addr_count; ++j) {
1455 if (skSockaddrArrayMatches(p1->accept_from_addr[i],
1456 p2->accept_from_addr[j],
1457 SK_SOCKADDRCOMP_NOPORT))
1458 {
1459 return -1;
1460 }
1461 }
1462 }
1463 return 0;
1464 }
1465
1466
1467 /*
1468 * is_valid = skpcProbeVerifyNetwork(p);
1469 *
1470 * Verify that this network-based probe does not conflict with
1471 * existing probes.
1472 */
1473 static int
skpcProbeVerifyNetwork(const skpc_probe_t * probe)1474 skpcProbeVerifyNetwork(
1475 const skpc_probe_t *probe)
1476 {
1477 const skpc_probe_t **p;
1478 size_t i;
1479
1480 /* Loop over all existing probes */
1481 for (i = 0;
1482 (p = (const skpc_probe_t**)skVectorGetValuePointer(skpc_probes, i))
1483 != NULL;
1484 ++i)
1485 {
1486 if (((*p)->protocol == probe->protocol)
1487 && skSockaddrArrayMatches((*p)->listen_addr,
1488 probe->listen_addr, 0))
1489 {
1490 /* Listen addresses match. */
1491
1492 /* Must have the same probe type */
1493 if (probe->probe_type != (*p)->probe_type) {
1494 skAppPrintErr(("Error verifying probe '%s':\n"
1495 "\tThe listening port and address are the same"
1496 " as probe '%s'\n\tand the probe types do not"
1497 " match"),
1498 probe->probe_name, (*p)->probe_name);
1499 return -1;
1500 }
1501
1502 /* Check their accept_from addresses. */
1503 if (skpcProbeVerifyCompareAcceptFrom(probe, *p)) {
1504 skAppPrintErr(("Error verifying probe '%s':\n"
1505 "\tThe listening port and address are the same"
1506 " as probe '%s';\n\tto distinguish each probe's"
1507 " traffic, a unique value for the\n"
1508 "\taccept-from-host clause is required on"
1509 " each probe."),
1510 probe->probe_name, (*p)->probe_name);
1511 return -1;
1512 }
1513 }
1514 }
1515
1516 return 0;
1517 }
1518
1519
1520 /* Has probe been verified? */
1521 int
skpcProbeIsVerified(const skpc_probe_t * probe)1522 skpcProbeIsVerified(
1523 const skpc_probe_t *probe)
1524 {
1525 assert(probe);
1526 return probe->verified;
1527 }
1528
1529
1530 /*
1531 * Verify that 'p' is a valid probe.
1532 */
1533 int
skpcProbeVerify(skpc_probe_t * probe,int is_ephemeral)1534 skpcProbeVerify(
1535 skpc_probe_t *probe,
1536 int is_ephemeral)
1537 {
1538 size_t count;
1539
1540 assert(probe);
1541 assert(skpc_probes);
1542
1543 /* check name */
1544 if ('\0' == probe->probe_name[0]) {
1545 skAppPrintErr("Error verifying probe:\n\tProbe has no name.");
1546 return -1;
1547 }
1548
1549 /* verify type is not invalid */
1550 if (probe->probe_type == PROBE_ENUM_INVALID) {
1551 skAppPrintErr(("Error verifying probe '%s':\n"
1552 "\tProbe's type is INVALID."),
1553 probe->probe_name);
1554 return -1;
1555 }
1556
1557 /* make certain no other probe has this name */
1558 if (skpcProbeLookupByName(probe->probe_name)) {
1559 skAppPrintErr(("Error verifying probe '%s':\n"
1560 "\tA probe with this name is already defined"),
1561 probe->probe_name);
1562 return -1;
1563 }
1564
1565 /* if is_ephemeral is specified, add it to the global list of
1566 * probes but don't mark it as verified */
1567 if (is_ephemeral) {
1568 return skVectorAppendValue(skpc_probes, &probe);
1569 }
1570
1571 /* when listen-as-host is specified, listen-on-port must be as
1572 * well */
1573 if ((probe->listen_addr != NULL)
1574 && (skSockaddrArrayGetSize(probe->listen_addr) > 0)
1575 && (skSockaddrGetPort(skSockaddrArrayGet(probe->listen_addr, 0)) == 0))
1576 {
1577 skAppPrintErr(("Error verifying probe '%s':\n"
1578 "\tThe listen-on-port clause is required when"
1579 " listen-as-host is specified"),
1580 probe->probe_name);
1581 return -1;
1582 }
1583
1584 /* when listen-on-port is specifed, the protocol is also required */
1585 if ((probe->listen_addr != NULL)
1586 && (probe->protocol == SKPC_PROTO_UNSET))
1587 {
1588 skAppPrintErr(("Error verifying probe '%s':\n"
1589 "\tThe protocol clause is required when"
1590 " listen-on-port is specified"),
1591 probe->probe_name);
1592 return -1;
1593 }
1594
1595 /* when accept-from-host is specifed, listen-on-port must be
1596 * specified as well */
1597 if ((probe->accept_from_addr != NULL)
1598 && (probe->listen_addr == NULL))
1599 {
1600 skAppPrintErr(("Error verifying probe '%s':\n"
1601 "\tThe listen-on-port clause is required when"
1602 " accept-from-host is specified"),
1603 probe->probe_name);
1604 return -1;
1605 }
1606
1607 /* check that one and only one of port, unix socket,
1608 * file-source, and poll-directory were given */
1609 count = 0;
1610 if (probe->listen_addr != NULL) {
1611 ++count;
1612 }
1613 if (probe->unix_domain_path != NULL) {
1614 ++count;
1615 }
1616 if (probe->file_source != NULL) {
1617 ++count;
1618 }
1619 if (probe->poll_directory != NULL) {
1620 ++count;
1621 }
1622
1623 if (count != 1) {
1624 if (count == 0) {
1625 skAppPrintErr(("Error verifying probe '%s':\n"
1626 "\tProbe needs a collection source; must give one"
1627 " of listen-on-port,\n\tpoll-directory,"
1628 " listen-on-unix-socket, or read-from-file."),
1629 probe->probe_name);
1630 } else {
1631 skAppPrintErr(("Error verifying probe '%s':\n"
1632 "\tMultiple collection sources; must give only one"
1633 " of listen-on-port,\n\tpoll-directory,"
1634 " listen-on-unix-socket, or read-from-file."),
1635 probe->probe_name);
1636 }
1637 return -1;
1638 }
1639
1640 /* when poll-directory is specified, no other probe can specify
1641 * that same directory */
1642 if (probe->poll_directory != NULL) {
1643 const skpc_probe_t **p;
1644 size_t i;
1645
1646 /* loop over all probes checking the poll-directory */
1647 for (i = 0;
1648 (p = (const skpc_probe_t**)skVectorGetValuePointer(skpc_probes,i))
1649 != NULL;
1650 ++i)
1651 {
1652 if ((*p)->poll_directory
1653 && (0 == strcmp(probe->poll_directory, (*p)->poll_directory)))
1654 {
1655 skAppPrintErr(("Error verifying probe '%s':\n"
1656 "\tThe poll-directory must be unique, but"
1657 " probe '%s' is\n\talso polling '%s'"),
1658 probe->probe_name, (*p)->probe_name,
1659 probe->poll_directory);
1660 return -1;
1661 }
1662 }
1663 }
1664
1665 /* when listening on a port, make sure we're not tromping over
1666 * other probes' ports */
1667 if (probe->listen_addr != NULL && skpcProbeVerifyNetwork(probe)) {
1668 return -1;
1669 }
1670
1671 /* verify the probe by its type */
1672 switch (probe->probe_type) {
1673 case PROBE_ENUM_NETFLOW_V5:
1674 if (0 != skpcProbeVerifyNetflowV5(probe)) {
1675 return -1;
1676 }
1677 break;
1678
1679
1680 case PROBE_ENUM_IPFIX:
1681 #if !SK_ENABLE_IPFIX
1682 skAppPrintErr(("Error verifying probe '%s':\n"
1683 "\tIPFIX support requires libfixbuf-%s or later"
1684 " and the required\n"
1685 "\tlibfixbuf version was not included at compile time"),
1686 probe->probe_name, SKPC_LIBFIXBUF_VERSION_IPFIX);
1687 #else
1688 if (0 == skpcProbeVerifyIPFIX(probe)) {
1689 break;
1690 }
1691 #endif /* SK_ENABLE_IPFIX */
1692 return -1;
1693
1694 case PROBE_ENUM_NETFLOW_V9:
1695 #if !SK_ENABLE_IPFIX
1696 skAppPrintErr(("Error verifying probe '%s':\n"
1697 "\tNetFlow v9 support requires libfixbuf-%s or later"
1698 " and the required\n\t"
1699 "libfixbuf version was not included at compile time"),
1700 probe->probe_name, SKPC_LIBFIXBUF_VERSION_NETFLOWV9);
1701 #else
1702 if (0 == skpcProbeVerifyNetflowV9(probe)) {
1703 break;
1704 }
1705 #endif /* SK_ENABLE_IPFIX */
1706 return -1;
1707
1708 case PROBE_ENUM_SFLOW:
1709 #if !SK_ENABLE_IPFIX
1710 skAppPrintErr(("Error verifying probe '%s':\n"
1711 "\tsFlow support requires libfixbuf-%s or later"
1712 " and the required\n\t"
1713 "libfixbuf version was not included at compile time"),
1714 probe->probe_name, SKPC_LIBFIXBUF_VERSION_SFLOW);
1715 #else
1716 /* sFlow probes have same requirements as NetFlow v9 */
1717 if (0 == skpcProbeVerifyNetflowV9(probe)) {
1718 break;
1719 }
1720 #endif /* SK_ENABLE_IPFIX */
1721 return -1;
1722
1723 case PROBE_ENUM_SILK:
1724 if (0 != skpcProbeVerifySilk(probe)) {
1725 return -1;
1726 }
1727 break;
1728
1729 case PROBE_ENUM_INVALID:
1730 /* should have caught this above */
1731 skAbortBadCase(probe->probe_type);
1732 }
1733
1734 /* probe is valid; add it to the global vector of probes */
1735 if (skVectorAppendValue(skpc_probes, &probe)) {
1736 return -1;
1737 }
1738
1739 probe->verified = 1;
1740 return 0;
1741 }
1742
1743
1744 void
skpcProbePrint(const skpc_probe_t * probe,sk_msg_fn_t printer)1745 skpcProbePrint(
1746 const skpc_probe_t *probe,
1747 sk_msg_fn_t printer)
1748 {
1749 char name[PATH_MAX];
1750 char log_flags[PATH_MAX];
1751 char quirks[PATH_MAX];
1752 char *accept_list;
1753 const char *label;
1754 size_t len;
1755 char *s;
1756 size_t i;
1757 size_t bits;
1758 ssize_t t;
1759
1760 /* fill 'name' with name and type of probe */
1761 snprintf(name, sizeof(name), "'%s': %s probe;",
1762 probe->probe_name ? probe->probe_name : "<EMPTY_NAME>",
1763 skpcProbetypeEnumtoName(probe->probe_type));
1764
1765 /* fill 'log_flags' with the log flags, if any */
1766 label = "; log-flags:";
1767 log_flags[0] = '\0';
1768 len = sizeof(log_flags);
1769 s = log_flags;
1770 for (i = 0; skpc_log_flags_map[i].name; ++i) {
1771 BITS_IN_WORD32(&bits, skpc_log_flags_map[i].flag);
1772 if ((1 == bits) && (probe->log_flags & skpc_log_flags_map[i].flag)) {
1773 t = snprintf(s, len, "%s %s", label, skpc_log_flags_map[i].name);
1774 if ((size_t)t < len) {
1775 len -= t;
1776 s += t;
1777 assert((size_t)(s - log_flags) == (sizeof(log_flags) - len));
1778 }
1779 label = "";
1780 }
1781 }
1782
1783 /* fill 'quirks' with the quirks, if any */
1784 label = "; quirks:";
1785 quirks[0] = '\0';
1786 len = sizeof(quirks);
1787 s = quirks;
1788 for (i = 0; skpc_quirks_map[i].name; ++i) {
1789 BITS_IN_WORD32(&bits, skpc_quirks_map[i].flag);
1790 if ((1 == bits) && (probe->quirks & skpc_quirks_map[i].flag)) {
1791 t = snprintf(s, len, "%s %s", label, skpc_quirks_map[i].name);
1792 if ((size_t)t < len) {
1793 len -= t;
1794 s += t;
1795 assert((size_t)(s - quirks) == (sizeof(quirks) - len));
1796 }
1797 label = "";
1798 }
1799 }
1800
1801 accept_list = NULL;
1802 if (probe->accept_from_addr) {
1803 label = "; accept-from:";
1804 len = probe->accept_from_addr_count * PATH_MAX * sizeof(char);
1805 accept_list = s = (char *)malloc(len);
1806 if (NULL == accept_list) {
1807 goto SKIP_FOR;
1808 }
1809 for (i = 0; i < probe->accept_from_addr_count; ++i) {
1810 t = (snprintf(
1811 s, len, "%s %s", label,
1812 skSockaddrArrayGetHostname(probe->accept_from_addr[i])));
1813 if ((size_t)t < len) {
1814 len -= t;
1815 s += t;
1816 }
1817 label = "";
1818 }
1819 SKIP_FOR: ;
1820 }
1821
1822
1823 /* print result, branching based on collection mechanism */
1824 if (probe->file_source) {
1825 printer("%s file: '%s'%s%s",
1826 name, probe->file_source, log_flags, quirks);
1827 } else if (probe->poll_directory) {
1828 printer("%s poll: '%s'%s%s",
1829 name, probe->poll_directory, log_flags, quirks);
1830 } else if (probe->unix_domain_path) {
1831 printer("%s listen: '%s'%s%s",
1832 name, probe->poll_directory, log_flags, quirks);
1833 } else if (probe->listen_addr) {
1834 printer("%s listen: %s/%s%s%s%s",
1835 name, skSockaddrArrayGetHostPortPair(probe->listen_addr),
1836 ((SKPC_PROTO_TCP == probe->protocol)
1837 ? "tcp" : ((SKPC_PROTO_UDP == probe->protocol)
1838 ? "udp" : ((SKPC_PROTO_SCTP == probe->protocol)
1839 ? "sctp"
1840 : ""))),
1841 accept_list ? accept_list : "", log_flags, quirks);
1842 } else {
1843 printer("%s", name);
1844 }
1845 free(accept_list);
1846 }
1847
1848
1849 /*
1850 * ***** Sensors *****************************************************
1851 */
1852
1853 /* Create a sensor */
1854 int
skpcSensorCreate(skpc_sensor_t ** sensor)1855 skpcSensorCreate(
1856 skpc_sensor_t **sensor)
1857 {
1858 assert(sensor);
1859
1860 (*sensor) = (skpc_sensor_t*)calloc(1, sizeof(skpc_sensor_t));
1861 if (NULL == (*sensor)) {
1862 skAppPrintOutOfMemory(NULL);
1863 return -1;
1864 }
1865
1866 (*sensor)->sensor_id = SK_INVALID_SENSOR;
1867
1868 (*sensor)->fixed_network[0] = SKPC_NETWORK_ID_INVALID;
1869 (*sensor)->fixed_network[1] = SKPC_NETWORK_ID_INVALID;
1870
1871 /* create the decider array; one for each network */
1872 (*sensor)->decider_count = skVectorGetCount(skpc_networks);
1873 if ((*sensor)->decider_count) {
1874 (*sensor)->decider = (skpc_netdecider_t*)calloc(
1875 (*sensor)->decider_count, sizeof(skpc_netdecider_t));
1876 if ((*sensor)->decider == NULL) {
1877 skAppPrintOutOfMemory(NULL);
1878 free(*sensor);
1879 return -1;
1880 }
1881 }
1882
1883 return 0;
1884 }
1885
1886
1887 void
skpcSensorDestroy(skpc_sensor_t ** sensor)1888 skpcSensorDestroy(
1889 skpc_sensor_t **sensor)
1890 {
1891 size_t i;
1892
1893 if (!sensor || !(*sensor)) {
1894 return;
1895 }
1896
1897 /* set the sensor's deciders' group to NULL, then destroy the
1898 * deciders */
1899 for (i = 0; i < (*sensor)->decider_count; ++i) {
1900 (*sensor)->decider[i].nd_group = NULL;
1901 }
1902 (*sensor)->decider_count = 0;
1903
1904 if ((*sensor)->decider) {
1905 free((*sensor)->decider);
1906 (*sensor)->decider = NULL;
1907 }
1908
1909 /* destroy the probe list */
1910 if ((*sensor)->probe_list) {
1911 free((*sensor)->probe_list);
1912 (*sensor)->probe_list = NULL;
1913 (*sensor)->probe_count = 0;
1914 }
1915
1916 /* set the 'group' reference on all filters to NULL, then destroy
1917 * the filters array. */
1918 for (i = 0; i < (*sensor)->filter_count; ++i) {
1919 (*sensor)->filter[i].f_group = NULL;
1920 }
1921 (*sensor)->filter_count = 0;
1922
1923 if ((*sensor)->filter) {
1924 free((*sensor)->filter);
1925 (*sensor)->filter = NULL;
1926 }
1927
1928 /* destroy other attributes of the sensor */
1929 if ((*sensor)->isp_ip_count) {
1930 free((*sensor)->isp_ip_list);
1931 (*sensor)->isp_ip_list = NULL;
1932 (*sensor)->isp_ip_count = 0;
1933 }
1934 if ((*sensor)->sensor_name) {
1935 free((*sensor)->sensor_name);
1936 }
1937
1938 /* destroy the sensor itself */
1939 free(*sensor);
1940 *sensor = NULL;
1941 }
1942
1943
1944 /* Get and set the name of this sensor. */
1945 #ifndef skpcSensorGetID
1946 sk_sensor_id_t
skpcSensorGetID(const skpc_sensor_t * sensor)1947 skpcSensorGetID(
1948 const skpc_sensor_t *sensor)
1949 {
1950 assert(sensor);
1951 return sensor->sensor_id;
1952 }
1953 #endif /* skpcSensorGetID */
1954
1955 #ifndef skpcSensorGetName
1956 const char *
skpcSensorGetName(const skpc_sensor_t * sensor)1957 skpcSensorGetName(
1958 const skpc_sensor_t *sensor)
1959 {
1960 assert(sensor);
1961 return sensor->sensor_name;
1962 }
1963 #endif /* skpcSensorGetName */
1964
1965 int
skpcSensorSetName(skpc_sensor_t * sensor,const char * name)1966 skpcSensorSetName(
1967 skpc_sensor_t *sensor,
1968 const char *name)
1969 {
1970 char *copy;
1971
1972 assert(sensor);
1973 if (name == NULL || name[0] == '\0') {
1974 return -1;
1975 }
1976
1977 copy = strdup(name);
1978 if (copy == NULL) {
1979 skAppPrintOutOfMemory(NULL);
1980 return -1;
1981 }
1982 if (sensor->sensor_name) {
1983 free(sensor->sensor_name);
1984 }
1985 sensor->sensor_name = copy;
1986
1987 sensor->sensor_id = sksiteSensorLookup(name);
1988 return 0;
1989 }
1990
1991
1992 /* Count the number of SNMP interfaces that have been mapped to a
1993 * flowtype on 'sensor' excluding the network 'ignored_network_id' */
1994 uint32_t
skpcSensorCountNetflowInterfaces(const skpc_sensor_t * sensor,int ignored_network_id)1995 skpcSensorCountNetflowInterfaces(
1996 const skpc_sensor_t *sensor,
1997 int ignored_network_id)
1998 {
1999 uint32_t ifcount = 0;
2000 size_t i;
2001
2002 for (i = 0; i < sensor->decider_count; ++i) {
2003 if (ignored_network_id == (int)i) {
2004 continue;
2005 }
2006 if (((sensor->decider[i].nd_type == SKPC_INTERFACE)
2007 || (sensor->decider[i].nd_type == SKPC_REMAIN_INTERFACE))
2008 && (sensor->decider[i].nd_group != NULL))
2009 {
2010 ifcount += skpcGroupGetItemCount(sensor->decider[i].nd_group);
2011 }
2012 }
2013 return ifcount;
2014 }
2015
2016
2017 /* Test rwrec against the interfaces (either SNMP or IP block) on the
2018 * sensor, or used the fixed network value if set. */
2019 int
skpcSensorTestFlowInterfaces(const skpc_sensor_t * sensor,const rwRec * rwrec,skpc_network_id_t network_id,skpc_direction_t rec_dir)2020 skpcSensorTestFlowInterfaces(
2021 const skpc_sensor_t *sensor,
2022 const rwRec *rwrec,
2023 skpc_network_id_t network_id,
2024 skpc_direction_t rec_dir)
2025 {
2026 skipaddr_t ip;
2027 int found = 0;
2028
2029 assert(sensor);
2030 assert(rwrec);
2031 assert(network_id <= SKPC_NETWORK_ID_MAX);
2032 assert(rec_dir == SKPC_DIR_SRC || rec_dir == SKPC_DIR_DST);
2033
2034 /* use the fixed value if provided */
2035 if (sensor->fixed_network[rec_dir] == network_id) {
2036 return 1;
2037 }
2038
2039 switch (sensor->decider[network_id].nd_type) {
2040 case SKPC_UNSET:
2041 break;
2042
2043 case SKPC_INTERFACE:
2044 case SKPC_REMAIN_INTERFACE:
2045 /* An SNMP interface list was set for the network_id. Test
2046 * the record's SNMP value against it. Whether incoming or
2047 * outgoing depends on 'rec_dir'. */
2048 if (rec_dir == SKPC_DIR_SRC) {
2049 /* look where the record is coming from: its input SNMP
2050 * interface */
2051 if (skpcGroupCheckInterface(sensor->decider[network_id].nd_group,
2052 rwRecGetInput(rwrec)))
2053 {
2054 return 1;
2055 }
2056 } else {
2057 /* look where the record is going to: output SNMP */
2058 assert(rec_dir == SKPC_DIR_DST);
2059 if (skpcGroupCheckInterface(sensor->decider[network_id].nd_group,
2060 rwRecGetOutput(rwrec)))
2061 {
2062 return 1;
2063 }
2064 }
2065 return -1;
2066
2067 case SKPC_NEG_IPBLOCK:
2068 case SKPC_REMAIN_IPBLOCK:
2069 /* want to find whether the IP is NOT in the list */
2070 found = 1;
2071 /* FALLTHROUGH */
2072
2073 case SKPC_IPBLOCK:
2074 /* An IP block was set for 'network_id'. Test the record's IP
2075 * against it. Whether source IP or dest IP depends on
2076 * 'rec_dir'. */
2077 if (rec_dir == SKPC_DIR_SRC) {
2078 /* look where the record is coming from: its source IP */
2079 rwRecMemGetSIP(rwrec, &ip);
2080 } else {
2081 /* look where the record is going to: destination IP */
2082 assert(rec_dir == SKPC_DIR_DST);
2083 rwRecMemGetDIP(rwrec, &ip);
2084 }
2085
2086 if (skpcGroupCheckIPblock(sensor->decider[network_id].nd_group, &ip)) {
2087 found = !found;
2088 }
2089 return ((found == 0) ? -1 : 1);
2090
2091 case SKPC_NEG_IPSET:
2092 case SKPC_REMAIN_IPSET:
2093 found = 1;
2094 /* FALLTHROUGH */
2095
2096 case SKPC_IPSET:
2097 if (rec_dir == SKPC_DIR_SRC) {
2098 /* look where the record is coming from: its source IP */
2099 rwRecMemGetSIP(rwrec, &ip);
2100 } else {
2101 /* look where the record is going to: destination IP */
2102 assert(rec_dir == SKPC_DIR_DST);
2103 rwRecMemGetDIP(rwrec, &ip);
2104 }
2105
2106 if (skpcGroupCheckIPset(sensor->decider[network_id].nd_group, &ip)) {
2107 found = !found;
2108 }
2109 return ((found == 0) ? -1 : 1);
2110 }
2111
2112 return 0;
2113 }
2114
2115
2116 /* Return non-zero if 'rwrec' matches ANY of the "discard-when"
2117 * filters on 'sensor' or if it does not match ALL of the
2118 * "discard-unless" filters. */
2119 int
skpcSensorCheckFilters(const skpc_sensor_t * sensor,const rwRec * rwrec)2120 skpcSensorCheckFilters(
2121 const skpc_sensor_t *sensor,
2122 const rwRec *rwrec)
2123 {
2124 skipaddr_t sip;
2125 skipaddr_t dip;
2126 const skpc_filter_t *filter;
2127 size_t discard;
2128 size_t j;
2129
2130 assert(sensor);
2131 assert(rwrec);
2132
2133 for (j = 0, filter = sensor->filter;
2134 j < sensor->filter_count;
2135 ++j, ++filter)
2136 {
2137 discard = !filter->f_discwhen;
2138 switch (filter->f_group_type) {
2139 case SKPC_GROUP_UNSET:
2140 skAbortBadCase(filter->f_group_type);
2141
2142 case SKPC_GROUP_IPBLOCK:
2143 switch (filter->f_type) {
2144 case SKPC_FILTER_SOURCE:
2145 rwRecMemGetSIP(rwrec, &sip);
2146 if (skpcGroupCheckIPblock(filter->f_group, &sip)) {
2147 discard = !discard;
2148 }
2149 break;
2150
2151 case SKPC_FILTER_DESTINATION:
2152 rwRecMemGetDIP(rwrec, &dip);
2153 if (skpcGroupCheckIPblock(filter->f_group, &dip)) {
2154 discard = !discard;
2155 }
2156 break;
2157
2158 case SKPC_FILTER_ANY:
2159 rwRecMemGetSIP(rwrec, &sip);
2160 rwRecMemGetDIP(rwrec, &dip);
2161 if (skpcGroupCheckIPblock(filter->f_group, &sip)
2162 || skpcGroupCheckIPblock(filter->f_group, &dip))
2163 {
2164 discard = !discard;
2165 }
2166 break;
2167 }
2168 break;
2169
2170 case SKPC_GROUP_IPSET:
2171 switch (filter->f_type) {
2172 case SKPC_FILTER_SOURCE:
2173 rwRecMemGetSIP(rwrec, &sip);
2174 if (skpcGroupCheckIPset(filter->f_group, &sip)) {
2175 discard = !discard;
2176 }
2177 break;
2178
2179 case SKPC_FILTER_DESTINATION:
2180 rwRecMemGetDIP(rwrec, &dip);
2181 if (skpcGroupCheckIPset(filter->f_group, &dip)) {
2182 discard = !discard;
2183 }
2184 break;
2185
2186 case SKPC_FILTER_ANY:
2187 rwRecMemGetSIP(rwrec, &sip);
2188 rwRecMemGetDIP(rwrec, &dip);
2189 if (skpcGroupCheckIPset(filter->f_group, &sip)
2190 || skpcGroupCheckIPset(filter->f_group, &dip))
2191 {
2192 discard = !discard;
2193 }
2194 break;
2195 }
2196 break;
2197
2198 case SKPC_GROUP_INTERFACE:
2199 switch (filter->f_type) {
2200 case SKPC_FILTER_SOURCE:
2201 if (skpcGroupCheckInterface(filter->f_group,
2202 rwRecGetInput(rwrec)))
2203 {
2204 discard = !discard;
2205 }
2206 break;
2207
2208 case SKPC_FILTER_DESTINATION:
2209 if (skpcGroupCheckInterface(filter->f_group,
2210 rwRecGetOutput(rwrec)))
2211 {
2212 discard = !discard;
2213 }
2214 break;
2215
2216 case SKPC_FILTER_ANY:
2217 if (skpcGroupCheckInterface(filter->f_group,
2218 rwRecGetInput(rwrec))
2219 || skpcGroupCheckInterface(filter->f_group,
2220 rwRecGetOutput(rwrec)))
2221 {
2222 discard = !discard;
2223 }
2224 break;
2225 }
2226 break;
2227 }
2228 if (discard) {
2229 return 1;
2230 }
2231 }
2232
2233 return 0;
2234 }
2235
2236
2237 int
skpcSensorSetNetworkDirection(skpc_sensor_t * sensor,skpc_network_id_t network_id,skpc_direction_t dir)2238 skpcSensorSetNetworkDirection(
2239 skpc_sensor_t *sensor,
2240 skpc_network_id_t network_id,
2241 skpc_direction_t dir)
2242 {
2243 const skpc_network_t *network;
2244 const char *prev_decider = NULL;
2245
2246 assert(sensor);
2247 assert(network_id <= SKPC_NETWORK_ID_INVALID);
2248 assert(dir == SKPC_DIR_SRC || dir == SKPC_DIR_DST);
2249
2250 /* get network */
2251 network = skpcNetworkLookupByID(network_id);
2252 if (network == NULL) {
2253 return -1;
2254 }
2255
2256 /* verify that value not previously set */
2257 if (sensor->fixed_network[dir] != SKPC_NETWORK_ID_INVALID) {
2258 skAppPrintErr(("Error setting %s-network on sensor '%s':\n"
2259 "\tCannot overwrite existing value"),
2260 ((dir == 0) ? "source" : "destination"),
2261 sensor->sensor_name);
2262 return -1;
2263 }
2264
2265 /* verify that no ipblocks or interfaces have been set for this
2266 * network */
2267 switch (sensor->decider[network->id].nd_type) {
2268 case SKPC_UNSET:
2269 /* valid */
2270 break;
2271
2272 case SKPC_INTERFACE:
2273 case SKPC_REMAIN_INTERFACE:
2274 prev_decider = "interface";
2275 break;
2276
2277 case SKPC_NEG_IPBLOCK:
2278 case SKPC_REMAIN_IPBLOCK:
2279 case SKPC_IPBLOCK:
2280 prev_decider = "ipblock";
2281 break;
2282
2283 case SKPC_NEG_IPSET:
2284 case SKPC_REMAIN_IPSET:
2285 case SKPC_IPSET:
2286 prev_decider = "ipset";
2287 break;
2288 }
2289
2290 if (prev_decider) {
2291 skAppPrintErr(("Error setting %s-network on sensor '%s':\n"
2292 "\tA %s-%s value has already been set"),
2293 ((dir == 0) ? "source" : "destination"),
2294 sensor->sensor_name, network->name, prev_decider);
2295 return -1;
2296 }
2297
2298 sensor->fixed_network[dir] = network->id;
2299 return 0;
2300 }
2301
2302
2303 /* Set the list of interfaces/IPs that represent a network */
2304 int
skpcSensorSetNetworkGroup(skpc_sensor_t * sensor,skpc_network_id_t network_id,const skpc_group_t * group)2305 skpcSensorSetNetworkGroup(
2306 skpc_sensor_t *sensor,
2307 skpc_network_id_t network_id,
2308 const skpc_group_t *group)
2309 {
2310 const skpc_network_t *network;
2311 size_t i;
2312
2313 /* check input */
2314 assert(sensor);
2315 assert(network_id <= SKPC_NETWORK_ID_INVALID);
2316 assert(group);
2317 assert(skpcGroupGetType(group) != SKPC_GROUP_UNSET);
2318
2319 /* check that group has data and that it is the correct type */
2320 if (group == NULL) {
2321 return -1;
2322 }
2323 if (!skpcGroupIsFrozen(group)
2324 || (skpcGroupGetItemCount(group) == 0))
2325 {
2326 return -1;
2327 }
2328
2329 /* get network */
2330 network = skpcNetworkLookupByID(network_id);
2331 if (network == NULL) {
2332 return -1;
2333 }
2334 assert(network->id < sensor->decider_count);
2335
2336 /* cannot set group when the source/destination network has
2337 * been fixed to this network_id. */
2338 for (i = 0; i < 2; ++i) {
2339 if (sensor->fixed_network[i] == network_id) {
2340 skAppPrintErr(("Error setting %ss on sensor '%s':\n"
2341 "\tAll flows are assumed to be %s the %s network"),
2342 skpcGrouptypeEnumtoName(skpcGroupGetType(group)),
2343 sensor->sensor_name,
2344 ((i == 0) ? "coming from" : "going to"),
2345 network->name);
2346 return -1;
2347 }
2348 }
2349
2350 /* check that we're not attempting to change an existing value */
2351 if (sensor->decider[network->id].nd_type != SKPC_UNSET) {
2352 skAppPrintErr(("Error setting %ss on sensor '%s':\n"
2353 "\tCannot overwrite existing %s network value"),
2354 skpcGrouptypeEnumtoName(skpcGroupGetType(group)),
2355 sensor->sensor_name, network->name);
2356 return -1;
2357 }
2358
2359 sensor->decider[network->id].nd_group = group;
2360 switch (skpcGroupGetType(group)) {
2361 case SKPC_GROUP_INTERFACE:
2362 sensor->decider[network->id].nd_type = SKPC_INTERFACE;
2363 break;
2364 case SKPC_GROUP_IPBLOCK:
2365 sensor->decider[network->id].nd_type = SKPC_IPBLOCK;
2366 break;
2367 case SKPC_GROUP_IPSET:
2368 sensor->decider[network->id].nd_type = SKPC_IPSET;
2369 break;
2370 case SKPC_GROUP_UNSET:
2371 skAbortBadCase(skpcGroupGetType(group));
2372 }
2373
2374 return 0;
2375 }
2376
2377
2378 /* Set the specified network to all values not covered by other networks */
2379 int
skpcSensorSetNetworkRemainder(skpc_sensor_t * sensor,skpc_network_id_t network_id,skpc_group_type_t group_type)2380 skpcSensorSetNetworkRemainder(
2381 skpc_sensor_t *sensor,
2382 skpc_network_id_t network_id,
2383 skpc_group_type_t group_type)
2384 {
2385 const skpc_network_t *network;
2386 int i;
2387
2388 assert(sensor);
2389 assert(network_id <= SKPC_NETWORK_ID_INVALID);
2390 assert(group_type != SKPC_GROUP_UNSET);
2391
2392 /* get network */
2393 network = skpcNetworkLookupByID(network_id);
2394 if (network == NULL) {
2395 return -1;
2396 }
2397
2398 assert(network->id < sensor->decider_count);
2399
2400 /* cannot set network when the source/destination network has
2401 * been fixed to this network_id. */
2402 for (i = 0; i < 2; ++i) {
2403 if (sensor->fixed_network[i] == network_id) {
2404 skAppPrintErr(("Error setting %ss on sensor '%s':\n"
2405 "\tAll flows are assumed to be %s the %s network"),
2406 skpcGrouptypeEnumtoName(group_type),
2407 sensor->sensor_name,
2408 ((i == 0) ? "coming from" : "going to"),
2409 network->name);
2410 return -1;
2411 }
2412 }
2413 /* check that we're not attempting to change an existing value */
2414 if (sensor->decider[network->id].nd_type != SKPC_UNSET) {
2415 skAppPrintErr(("Error setting %ss on sensor '%s':\n"
2416 "\tCannot overwrite existing %s network value"),
2417 skpcGrouptypeEnumtoName(group_type),
2418 sensor->sensor_name, network->name);
2419 return -1;
2420 }
2421
2422 switch (group_type) {
2423 case SKPC_GROUP_INTERFACE:
2424 sensor->decider[network->id].nd_type = SKPC_REMAIN_INTERFACE;
2425 break;
2426 case SKPC_GROUP_IPBLOCK:
2427 sensor->decider[network->id].nd_type = SKPC_REMAIN_IPBLOCK;
2428 break;
2429 case SKPC_GROUP_IPSET:
2430 sensor->decider[network->id].nd_type = SKPC_REMAIN_IPSET;
2431 break;
2432 case SKPC_GROUP_UNSET:
2433 skAbortBadCase(group_type);
2434 }
2435
2436 return 0;
2437 }
2438
2439
2440 int
skpcSensorSetDefaultNonrouted(skpc_sensor_t * sensor,skpc_network_id_t network_id)2441 skpcSensorSetDefaultNonrouted(
2442 skpc_sensor_t *sensor,
2443 skpc_network_id_t network_id)
2444 {
2445 sk_vector_t *ifvec = NULL;
2446 const uint32_t default_nonrouted = 0;
2447 int rv = -1;
2448
2449 assert(sensor);
2450 assert(network_id <= SKPC_NETWORK_ID_INVALID);
2451
2452 if (NULL == nonrouted_group) {
2453 ifvec = skVectorNew(sizeof(uint32_t));
2454 if (ifvec == NULL) {
2455 skAppPrintOutOfMemory(NULL);
2456 goto END;
2457 }
2458 if (skVectorAppendValue(ifvec, &default_nonrouted)) {
2459 skAppPrintOutOfMemory(NULL);
2460 goto END;
2461 }
2462
2463 if (skpcGroupCreate(&nonrouted_group)) {
2464 skAppPrintOutOfMemory(NULL);
2465 goto END;
2466 }
2467 skpcGroupSetType(nonrouted_group, SKPC_GROUP_INTERFACE);
2468 if (skpcGroupAddValues(nonrouted_group, ifvec)) {
2469 skAppPrintOutOfMemory(NULL);
2470 goto END;
2471 }
2472 skpcGroupFreeze(nonrouted_group);
2473 }
2474
2475 rv = skpcSensorSetNetworkGroup(sensor, network_id, nonrouted_group);
2476 END:
2477 if (ifvec) {
2478 skVectorDestroy(ifvec);
2479 }
2480 return rv;
2481 }
2482
2483
2484 static int
skpcSensorComputeRemainingInterfaces(skpc_sensor_t * sensor)2485 skpcSensorComputeRemainingInterfaces(
2486 skpc_sensor_t *sensor)
2487 {
2488 size_t remain_network = SKPC_NETWORK_ID_INVALID;
2489 size_t i;
2490 skpc_group_t *group = NULL;
2491
2492 /* determine which network has claimed the 'remainder' */
2493 for (i = 0; i < sensor->decider_count; ++i) {
2494 if (sensor->decider[i].nd_type == SKPC_REMAIN_INTERFACE) {
2495 if (remain_network != SKPC_NETWORK_ID_INVALID) {
2496 /* cannot have more than one "remainder" */
2497 skAppPrintErr(("Cannot verify sensor '%s':\n"
2498 "\tMultiple network values claim 'remainder'"),
2499 sensor->sensor_name);
2500 return -1;
2501 }
2502 remain_network = i;
2503 }
2504 }
2505
2506 if (remain_network == SKPC_NETWORK_ID_INVALID) {
2507 /* no one is set to remainder; return */
2508 return 0;
2509 }
2510
2511 /* create a new group */
2512 if (skpcGroupCreate(&group)) {
2513 skAppPrintOutOfMemory(NULL);
2514 return -1;
2515 }
2516 skpcGroupSetType(group, SKPC_GROUP_INTERFACE);
2517
2518 sensor->decider[remain_network].nd_group = group;
2519
2520 /* add all existing groups to the new group */
2521 for (i = 0; i < sensor->decider_count; ++i) {
2522 if (sensor->decider[i].nd_type == SKPC_INTERFACE) {
2523 if (skpcGroupAddGroup(group, sensor->decider[i].nd_group)) {
2524 skAppPrintOutOfMemory(NULL);
2525 return -1;
2526 }
2527 }
2528 }
2529
2530 /* take the complement of the group, then freeze it */
2531 skpcGroupComputeComplement(group);
2532 skpcGroupFreeze(group);
2533
2534 return 0;
2535 }
2536
2537
2538 static int
skpcSensorComputeRemainingIpBlocks(skpc_sensor_t * sensor)2539 skpcSensorComputeRemainingIpBlocks(
2540 skpc_sensor_t *sensor)
2541 {
2542 size_t remain_network = SKPC_NETWORK_ID_INVALID;
2543 int has_ipblocks = 0;
2544 skpc_group_t *group = NULL;
2545 size_t i;
2546
2547 /* determine which network has claimed the 'remainder'. At the
2548 * same time, verify that at least one network has 'ipblocks' */
2549 for (i = 0; i < sensor->decider_count; ++i) {
2550 if (sensor->decider[i].nd_type == SKPC_REMAIN_IPBLOCK) {
2551 if (remain_network != SKPC_NETWORK_ID_INVALID) {
2552 /* cannot have more than one "remainder" */
2553 skAppPrintErr(("Cannot verify sensor '%s':\n"
2554 "\tMultiple network values claim 'remainder'"),
2555 sensor->sensor_name);
2556 return -1;
2557 }
2558 remain_network = i;
2559 } else if (sensor->decider[i].nd_type == SKPC_IPBLOCK) {
2560 has_ipblocks = 1;
2561 }
2562 }
2563
2564 if (remain_network == SKPC_NETWORK_ID_INVALID) {
2565 /* no one is set to remainder; return */
2566 return 0;
2567 }
2568
2569 /* need to have existing IPblocks to set a remainder */
2570 if (has_ipblocks == 0) {
2571 const skpc_network_t *network = skpcNetworkLookupByID(remain_network);
2572 skAppPrintErr(("Cannot verify sensor '%s':\n"
2573 "\tCannot set %s-ipblocks to remaining IP because\n"
2574 "\tno other interfaces hold IP blocks"),
2575 sensor->sensor_name, network->name);
2576 return -1;
2577 }
2578
2579 /* create a new group */
2580 if (skpcGroupCreate(&group)) {
2581 skAppPrintOutOfMemory(NULL);
2582 return -1;
2583 }
2584 skpcGroupSetType(group, SKPC_GROUP_IPBLOCK);
2585
2586 sensor->decider[remain_network].nd_group = group;
2587
2588 /* add all existing groups to the new group */
2589 for (i = 0; i < sensor->decider_count; ++i) {
2590 if (sensor->decider[i].nd_type == SKPC_IPBLOCK) {
2591 if (skpcGroupAddGroup(group, sensor->decider[i].nd_group)) {
2592 skAppPrintOutOfMemory(NULL);
2593 return -1;
2594 }
2595 }
2596 }
2597
2598 /* freze the group */
2599 skpcGroupFreeze(group);
2600
2601 return 0;
2602 }
2603
2604
2605 static int
skpcSensorComputeRemainingIpSets(skpc_sensor_t * sensor)2606 skpcSensorComputeRemainingIpSets(
2607 skpc_sensor_t *sensor)
2608 {
2609 size_t remain_network = SKPC_NETWORK_ID_INVALID;
2610 int has_ipsets = 0;
2611 skpc_group_t *group = NULL;
2612 size_t i;
2613
2614 /* determine which network has claimed the 'remainder'. At the
2615 * same time, verify that at least one network has 'ipsets' */
2616 for (i = 0; i < sensor->decider_count; ++i) {
2617 if (sensor->decider[i].nd_type == SKPC_REMAIN_IPSET) {
2618 if (remain_network != SKPC_NETWORK_ID_INVALID) {
2619 /* cannot have more than one "remainder" */
2620 skAppPrintErr(("Cannot verify sensor '%s':\n"
2621 "\tMultiple network values claim 'remainder'"),
2622 sensor->sensor_name);
2623 return -1;
2624 }
2625 remain_network = i;
2626 } else if (sensor->decider[i].nd_type == SKPC_IPSET) {
2627 has_ipsets = 1;
2628 }
2629 }
2630
2631 if (remain_network == SKPC_NETWORK_ID_INVALID) {
2632 /* no one is set to remainder; return */
2633 return 0;
2634 }
2635
2636 /* need to have existing IPsets to set a remainder */
2637 if (has_ipsets == 0) {
2638 const skpc_network_t *network = skpcNetworkLookupByID(remain_network);
2639 skAppPrintErr(("Cannot verify sensor '%s':\n"
2640 "\tCannot set %s-ipsets to remaining IP because\n"
2641 "\tno other interfaces hold IP sets"),
2642 sensor->sensor_name, network->name);
2643 return -1;
2644 }
2645
2646 /* create a new group */
2647 if (skpcGroupCreate(&group)) {
2648 skAppPrintOutOfMemory(NULL);
2649 return -1;
2650 }
2651 skpcGroupSetType(group, SKPC_GROUP_IPSET);
2652
2653 sensor->decider[remain_network].nd_group = group;
2654
2655 /* add all existing groups to the new group */
2656 for (i = 0; i < sensor->decider_count; ++i) {
2657 if (sensor->decider[i].nd_type == SKPC_IPSET) {
2658 if (skpcGroupAddGroup(group, sensor->decider[i].nd_group)) {
2659 skAppPrintOutOfMemory(NULL);
2660 return -1;
2661 }
2662 }
2663 }
2664
2665 /* freze the group */
2666 skpcGroupFreeze(group);
2667
2668 return 0;
2669 }
2670
2671
2672 /* add a new discard-{when,unless} list to 'sensor' */
2673 int
skpcSensorAddFilter(skpc_sensor_t * sensor,const skpc_group_t * group,skpc_filter_type_t filter_type,int is_discardwhen_list,skpc_group_type_t group_type)2674 skpcSensorAddFilter(
2675 skpc_sensor_t *sensor,
2676 const skpc_group_t *group,
2677 skpc_filter_type_t filter_type,
2678 int is_discardwhen_list,
2679 skpc_group_type_t group_type)
2680 {
2681 const char *filter_name;
2682 skpc_filter_t *filter;
2683 size_t j;
2684 int rv = -1;
2685
2686 assert(sensor);
2687
2688 /* check that group has data and that it is the correct type */
2689 if (group == NULL) {
2690 return -1;
2691 }
2692 if (!skpcGroupIsFrozen(group)
2693 || (skpcGroupGetItemCount(group) == 0)
2694 || (skpcGroupGetType(group) != group_type))
2695 {
2696 return -1;
2697 }
2698
2699 /* verify we are not attempting to overwrite a value */
2700 for (j = 0, filter = sensor->filter;
2701 j < sensor->filter_count;
2702 ++j, ++filter)
2703 {
2704 if (filter->f_type == filter_type
2705 && filter->f_group_type == group_type)
2706 {
2707 /* error */
2708 switch (filter_type) {
2709 case SKPC_FILTER_ANY:
2710 filter_name = "any";
2711 break;
2712 case SKPC_FILTER_DESTINATION:
2713 filter_name = "destination";
2714 break;
2715 case SKPC_FILTER_SOURCE:
2716 filter_name = "source";
2717 break;
2718 default:
2719 skAbortBadCase(filter_type);
2720 }
2721 skAppPrintErr(("Error setting discard-%s list on sensor '%s':\n"
2722 "\tMay not overwrite existing %s-%ss list"),
2723 (is_discardwhen_list ? "when" : "unless"),
2724 sensor->sensor_name, filter_name,
2725 skpcGrouptypeEnumtoName(group_type));
2726 return -1;
2727 }
2728 }
2729
2730 /* if this is the first filter, allocate space for all the filters
2731 * on this sensor */
2732 if (NULL == sensor->filter) {
2733 assert(0 == sensor->filter_count);
2734 /* allow room for both interface-filters and ipblock-filters */
2735 sensor->filter = ((skpc_filter_t*)
2736 calloc(SKPC_NUM_GROUP_TYPES * SKPC_NUM_FILTER_TYPES,
2737 sizeof(skpc_filter_t)));
2738 if (NULL == sensor->filter) {
2739 skAppPrintOutOfMemory(NULL);
2740 goto END;
2741 }
2742 }
2743
2744 assert(sensor->filter_count < (2 * SKPC_NUM_FILTER_TYPES));
2745
2746 filter = &sensor->filter[sensor->filter_count];
2747
2748 filter->f_group = group;
2749 filter->f_type = filter_type;
2750 filter->f_group_type = group_type;
2751 filter->f_discwhen = (is_discardwhen_list ? 1 : 0);
2752
2753 ++sensor->filter_count;
2754
2755 rv = 0;
2756
2757 END:
2758 return rv;
2759 }
2760
2761
2762 /* Get and set the list of IPs of the ISP */
2763 uint32_t
skpcSensorGetIspIps(const skpc_sensor_t * sensor,const uint32_t ** out_ip_list)2764 skpcSensorGetIspIps(
2765 const skpc_sensor_t *sensor,
2766 const uint32_t **out_ip_list)
2767 {
2768 assert(sensor);
2769
2770 if (sensor->isp_ip_count > 0) {
2771 if (out_ip_list != NULL) {
2772 *out_ip_list = sensor->isp_ip_list;
2773 }
2774 }
2775 return sensor->isp_ip_count;
2776 }
2777
2778 int
skpcSensorSetIspIps(skpc_sensor_t * sensor,const sk_vector_t * isp_ip_vec)2779 skpcSensorSetIspIps(
2780 skpc_sensor_t *sensor,
2781 const sk_vector_t *isp_ip_vec)
2782 {
2783 size_t count;
2784 uint32_t *copy;
2785
2786 /* check input */
2787 assert(sensor);
2788 if (isp_ip_vec == NULL) {
2789 return -1;
2790 }
2791 count = skVectorGetCount(isp_ip_vec);
2792 if (count == 0) {
2793 return -1;
2794 }
2795
2796 /* copy the values out of the vector */
2797 copy = (uint32_t*)malloc(count * skVectorGetElementSize(isp_ip_vec));
2798 if (copy == NULL) {
2799 skAppPrintOutOfMemory(NULL);
2800 return -1;
2801 }
2802 skVectorToArray(copy, isp_ip_vec);
2803
2804 /* free the existing list and set value on the sensor */
2805 if (sensor->isp_ip_count) {
2806 free(sensor->isp_ip_list);
2807 }
2808 sensor->isp_ip_list = copy;
2809 sensor->isp_ip_count = count;
2810
2811 return 0;
2812 }
2813
2814
2815 uint32_t
skpcSensorGetProbes(const skpc_sensor_t * sensor,sk_vector_t * out_probe_vec)2816 skpcSensorGetProbes(
2817 const skpc_sensor_t *sensor,
2818 sk_vector_t *out_probe_vec)
2819 {
2820 assert(sensor);
2821
2822 if (sensor->probe_count != 0 && out_probe_vec != NULL) {
2823 if (skVectorAppendFromArray(out_probe_vec, sensor->probe_list,
2824 sensor->probe_count))
2825 {
2826 skAppPrintOutOfMemory(NULL);
2827 return 0;
2828 }
2829 }
2830 return sensor->probe_count;
2831 }
2832
2833 int
skpcSensorSetProbes(skpc_sensor_t * sensor,const sk_vector_t * probe_vec)2834 skpcSensorSetProbes(
2835 skpc_sensor_t *sensor,
2836 const sk_vector_t *probe_vec)
2837 {
2838 size_t count;
2839 void *copy;
2840
2841 /* check input */
2842 assert(sensor);
2843 if (probe_vec == NULL) {
2844 return -1;
2845 }
2846 count = skVectorGetCount(probe_vec);
2847 if (count == 0) {
2848 return -1;
2849 }
2850
2851 /* copy the values out of the vector */
2852 if (0 == sensor->probe_count) {
2853 /* create a new array */
2854 copy = malloc(count * skVectorGetElementSize(probe_vec));
2855 if (NULL == copy) {
2856 skAppPrintOutOfMemory(NULL);
2857 return -1;
2858 }
2859 sensor->probe_list = (skpc_probe_t**)copy;
2860 sensor->probe_count = count;
2861 } else {
2862 /* grow current array */
2863 copy = sensor->probe_list;
2864 sensor->probe_list
2865 = (skpc_probe_t**)realloc(copy, (skVectorGetElementSize(probe_vec)
2866 * (sensor->probe_count + count)));
2867 if (NULL == sensor->probe_list) {
2868 sensor->probe_list = (skpc_probe_t**)copy;
2869 skAppPrintOutOfMemory(NULL);
2870 return -1;
2871 }
2872 /* point 'copy' at new memory location */
2873 copy = sensor->probe_list + sensor->probe_count;
2874 sensor->probe_count += count;
2875 }
2876
2877 skVectorToArray(copy, probe_vec);
2878
2879 return 0;
2880 }
2881
2882
2883 int
skpcSensorVerify(skpc_sensor_t * sensor,int (* site_sensor_verify_fn)(skpc_sensor_t * sensor))2884 skpcSensorVerify(
2885 skpc_sensor_t *sensor,
2886 int (*site_sensor_verify_fn)(skpc_sensor_t *sensor))
2887 {
2888 uint32_t i;
2889
2890 assert(sensor);
2891
2892 if (sensor->sensor_id == SK_INVALID_SENSOR) {
2893 skAppPrintErr(("Error verifying sensor '%s'\n"
2894 "\tSensor is not defined in site file silk.conf"),
2895 sensor->sensor_name);
2896 return -1;
2897 }
2898
2899 #if 0
2900 /* 2008.05.16 --- Allow sensors to be defined multiple times. The
2901 * add-sensor-to-probe call below will fail if we attempt to
2902 * define two sensors with the same name that each process the
2903 * same probe. */
2904
2905 /* make certain no other sensor has this name */
2906 if (skpcSensorLookupByName(sensor->sensor_name)) {
2907 skAppPrintErr(("Error verifying sensor '%s':\n"
2908 "\tA sensor with this name is already defined"),
2909 sensor->sensor_name);
2910 return -1;
2911 }
2912 #endif /* 0 */
2913
2914 /* verifying the sensor for this site (i.e., by its class) */
2915 if (site_sensor_verify_fn != NULL) {
2916 if (0 != site_sensor_verify_fn(sensor)) {
2917 return -1;
2918 }
2919 }
2920
2921 /* if any network decider is set to 'remainder', update the sensor */
2922 if (skpcSensorComputeRemainingInterfaces(sensor)) {
2923 return -1;
2924 }
2925 if (skpcSensorComputeRemainingIpBlocks(sensor)) {
2926 return -1;
2927 }
2928 if (skpcSensorComputeRemainingIpSets(sensor)) {
2929 return -1;
2930 }
2931
2932 /* add a link on each probe to this sensor */
2933 for (i = 0; i < sensor->probe_count; ++i) {
2934 if (skpcProbeAddSensor(sensor->probe_list[i], sensor)) {
2935 skAppPrintErr(("Error verifying sensor '%s':\n"
2936 "\tCannot link probe '%s' to this sensor"),
2937 sensor->sensor_name,
2938 sensor->probe_list[i]->probe_name);
2939 return -1;
2940 }
2941 }
2942
2943 /* sensor is valid; add it to the global vector of sensors */
2944 if (skVectorAppendValue(skpc_sensors, &sensor)) {
2945 skAppPrintOutOfMemory(NULL);
2946 return -1;
2947 }
2948
2949 return 0;
2950 }
2951
2952
2953 /*
2954 * ***** Groups ***********************************************************
2955 */
2956
2957 /* create a new group */
2958 int
skpcGroupCreate(skpc_group_t ** group)2959 skpcGroupCreate(
2960 skpc_group_t **group)
2961 {
2962 skpc_group_t *g;
2963
2964 assert(group);
2965
2966 g = (skpc_group_t*)calloc(1, sizeof(skpc_group_t));
2967 if (NULL == g) {
2968 skAppPrintOutOfMemory(NULL);
2969 return -1;
2970 }
2971
2972 g->g_type = SKPC_GROUP_UNSET;
2973
2974 *group = g;
2975
2976 return 0;
2977 }
2978
2979 /* destroy a group */
2980 void
skpcGroupDestroy(skpc_group_t ** group)2981 skpcGroupDestroy(
2982 skpc_group_t **group)
2983 {
2984 if (!group || !(*group)) {
2985 return;
2986 }
2987
2988 switch ((*group)->g_type) {
2989 case SKPC_GROUP_UNSET:
2990 break;
2991 case SKPC_GROUP_INTERFACE:
2992 if ((*group)->g_value.map) {
2993 skBitmapDestroy(&((*group)->g_value.map));
2994 (*group)->g_value.map = NULL;
2995 }
2996 break;
2997 case SKPC_GROUP_IPBLOCK:
2998 if ((*group)->g_is_frozen) {
2999 if ((*group)->g_value.ipblock) {
3000 free((*group)->g_value.ipblock);
3001 (*group)->g_value.ipblock = NULL;
3002 }
3003 } else if ((*group)->g_value.vec) {
3004 skVectorDestroy((*group)->g_value.vec);
3005 (*group)->g_value.vec = NULL;
3006 }
3007 break;
3008 case SKPC_GROUP_IPSET:
3009 if ((*group)->g_value.ipset) {
3010 skIPSetDestroy(&(*group)->g_value.ipset);
3011 (*group)->g_value.ipset = NULL;
3012 }
3013 break;
3014 }
3015
3016 if ((*group)->g_name) {
3017 free((*group)->g_name);
3018 (*group)->g_name = NULL;
3019 }
3020
3021 free(*group);
3022 *group = NULL;
3023 }
3024
3025
3026 /* mark group as unchangeable, convert ipblock vector to array, and
3027 * count number of items */
3028 int
skpcGroupFreeze(skpc_group_t * group)3029 skpcGroupFreeze(
3030 skpc_group_t *group)
3031 {
3032 size_t count;
3033 skIPWildcard_t **ipwild_list;
3034 sk_vector_t *ipblock_vec;
3035 uint64_t ip_count;
3036
3037 assert(group);
3038 if (group->g_is_frozen) {
3039 return 0;
3040 }
3041
3042 if (SKPC_GROUP_UNSET == group->g_type) {
3043 /* nothing else do */
3044 goto END;
3045 }
3046 if (SKPC_GROUP_INTERFACE == group->g_type) {
3047 group->g_itemcount = skBitmapGetHighCount(group->g_value.map);
3048 goto END;
3049 }
3050 if (SKPC_GROUP_IPSET == group->g_type) {
3051 if (skIPSetClean(group->g_value.ipset)) {
3052 return -1;
3053 }
3054 ip_count = skIPSetCountIPs(group->g_value.ipset, NULL);
3055 if (ip_count > UINT32_MAX) {
3056 group->g_itemcount = UINT32_MAX;
3057 } else {
3058 group->g_itemcount = (uint32_t)ip_count;
3059 }
3060 goto END;
3061 }
3062 if (SKPC_GROUP_IPBLOCK != group->g_type) {
3063 skAbortBadCase(group->g_type);
3064 }
3065
3066 /* convert the vector to an array */
3067 ipblock_vec = group->g_value.vec;
3068 count = skVectorGetCount(ipblock_vec);
3069
3070 /* allocate memory for the list of ip-wildcards */
3071 ipwild_list = (skIPWildcard_t**)malloc(count * sizeof(skIPWildcard_t*));
3072 if (NULL == ipwild_list) {
3073 skAppPrintOutOfMemory(NULL);
3074 return -1;
3075 }
3076
3077 /* convert vector to an array */
3078 skVectorToArray(ipwild_list, ipblock_vec);
3079
3080 /* finished with the vector */
3081 skVectorDestroy(ipblock_vec);
3082
3083 group->g_value.ipblock = ipwild_list;
3084 group->g_itemcount = count;
3085
3086 END:
3087 group->g_is_frozen = 1;
3088 if (skVectorAppendValue(skpc_groups, &group)) {
3089 skAppPrintOutOfMemory(NULL);
3090 return -1;
3091 }
3092 return 0;
3093 }
3094
3095
3096 /* get or set the name of the group */
3097 const char *
skpcGroupGetName(const skpc_group_t * group)3098 skpcGroupGetName(
3099 const skpc_group_t *group)
3100 {
3101 assert(group);
3102 return group->g_name;
3103 }
3104
3105 int
skpcGroupSetName(skpc_group_t * group,const char * name)3106 skpcGroupSetName(
3107 skpc_group_t *group,
3108 const char *name)
3109 {
3110 const char *cp;
3111 char *copy;
3112
3113 assert(group);
3114 if (group->g_is_frozen) {
3115 return -1;
3116 }
3117
3118 if (name == NULL || name[0] == '\0') {
3119 return -1;
3120 }
3121
3122 /* check for illegal characters */
3123 cp = name;
3124 while (*cp) {
3125 if (*cp == '/' || isspace((int)*cp)) {
3126 return -1;
3127 }
3128 ++cp;
3129 }
3130
3131 copy = strdup(name);
3132 if (copy == NULL) {
3133 skAppPrintOutOfMemory(NULL);
3134 return -1;
3135 }
3136 if (group->g_name) {
3137 free(group->g_name);
3138 }
3139 group->g_name = copy;
3140 return 0;
3141 }
3142
3143
3144 /* get or set the type of the group */
3145 skpc_group_type_t
skpcGroupGetType(const skpc_group_t * group)3146 skpcGroupGetType(
3147 const skpc_group_t *group)
3148 {
3149 assert(group);
3150 return group->g_type;
3151 }
3152
3153 int
skpcGroupSetType(skpc_group_t * group,skpc_group_type_t group_type)3154 skpcGroupSetType(
3155 skpc_group_t *group,
3156 skpc_group_type_t group_type)
3157 {
3158 assert(group);
3159 if (group->g_is_frozen) {
3160 return -1;
3161 }
3162 if (SKPC_GROUP_UNSET != group->g_type) {
3163 return -1;
3164 }
3165
3166 switch (group_type) {
3167 case SKPC_GROUP_UNSET:
3168 return -1;
3169
3170 case SKPC_GROUP_INTERFACE:
3171 if (skBitmapCreate(&group->g_value.map, SK_SNMP_INDEX_LIMIT)) {
3172 return -1;
3173 }
3174 break;
3175
3176 case SKPC_GROUP_IPBLOCK:
3177 group->g_value.vec = skVectorNew(sizeof(skIPWildcard_t**));
3178 if (NULL == group->g_value.vec) {
3179 return -1;
3180 }
3181 break;
3182
3183 case SKPC_GROUP_IPSET:
3184 if (skIPSetCreate(&group->g_value.ipset, 0)) {
3185 return -1;
3186 }
3187 break;
3188 }
3189
3190 group->g_type = group_type;
3191 return 0;
3192 }
3193
3194
3195 /* add the values from 'vec' to 'group' */
3196 int
skpcGroupAddValues(skpc_group_t * group,const sk_vector_t * vec)3197 skpcGroupAddValues(
3198 skpc_group_t *group,
3199 const sk_vector_t *vec)
3200 {
3201 size_t count;
3202 size_t i;
3203 uint32_t *num;
3204 const skipset_t *ipset;
3205 int rv;
3206
3207 assert(group);
3208 if (group->g_is_frozen) {
3209 return -1;
3210 }
3211
3212 if (NULL == vec) {
3213 return 0;
3214 }
3215
3216 count = skVectorGetCount(vec);
3217 if (0 == count) {
3218 return 0;
3219 }
3220
3221 switch (group->g_type) {
3222 case SKPC_GROUP_UNSET:
3223 return -1;
3224
3225 case SKPC_GROUP_INTERFACE:
3226 /* check that vector has data of the correct type (size) */
3227 if (skVectorGetElementSize(vec) != sizeof(uint32_t)) {
3228 return -1;
3229 }
3230 for (i = 0; i < count; ++i) {
3231 num = (uint32_t*)skVectorGetValuePointer(vec, i);
3232 skBitmapSetBit(group->g_value.map, *num);
3233 }
3234 break;
3235
3236 case SKPC_GROUP_IPBLOCK:
3237 /* check that vector has data of the correct type (size) */
3238 if (skVectorGetElementSize(vec) != sizeof(skIPWildcard_t*)) {
3239 return -1;
3240 }
3241 /* add IPWildcards to the group */
3242 if (skVectorAppendVector(group->g_value.vec, vec)) {
3243 skAppPrintOutOfMemory(NULL);
3244 return -1;
3245 }
3246 /* store the IPWildcards in skpc_wildcards for memory cleanup */
3247 if (!skpc_wildcards) {
3248 skpc_wildcards = skVectorNew(sizeof(skIPWildcard_t**));
3249 if (!skpc_wildcards) {
3250 skAppPrintOutOfMemory(NULL);
3251 return -1;
3252 }
3253 }
3254 if (skVectorAppendVector(skpc_wildcards, vec)) {
3255 skAppPrintOutOfMemory(NULL);
3256 return -1;
3257 }
3258 break;
3259
3260 case SKPC_GROUP_IPSET:
3261 /* check that vector has data of the correct type (size) */
3262 if (skVectorGetElementSize(vec) != sizeof(skipset_t*)) {
3263 return -1;
3264 }
3265 for (i = 0; i < count; ++i) {
3266 ipset = *(skipset_t**)skVectorGetValuePointer(vec, i);
3267 rv = skIPSetUnion(group->g_value.ipset, ipset);
3268 if (rv) {
3269 skAppPrintOutOfMemory(NULL);
3270 return -1;
3271 }
3272 }
3273 rv = skIPSetClean(group->g_value.ipset);
3274 if (rv) {
3275 return -1;
3276 }
3277 break;
3278 }
3279
3280 return 0;
3281 }
3282
3283
3284 /* add the values from the existing group 'g' to group 'group' */
3285 int
skpcGroupAddGroup(skpc_group_t * group,const skpc_group_t * g)3286 skpcGroupAddGroup(
3287 skpc_group_t *group,
3288 const skpc_group_t *g)
3289 {
3290 assert(group);
3291 if (group->g_is_frozen) {
3292 return -1;
3293 }
3294
3295 /* verify group 'g' */
3296 if (NULL == g) {
3297 return 0;
3298 }
3299 if (!g->g_is_frozen) {
3300 return -1;
3301 }
3302 if (0 == g->g_itemcount) {
3303 return 0;
3304 }
3305
3306 if (g->g_type != group->g_type) {
3307 return -1;
3308 }
3309
3310 switch (group->g_type) {
3311 case SKPC_GROUP_UNSET:
3312 return -1;
3313
3314 case SKPC_GROUP_INTERFACE:
3315 skBitmapUnion(group->g_value.map, g->g_value.map);
3316 break;
3317
3318 case SKPC_GROUP_IPBLOCK:
3319 /* count number of IPWildcards */
3320 if (skVectorAppendFromArray(group->g_value.vec, g->g_value.ipblock,
3321 g->g_itemcount))
3322 {
3323 return -1;
3324 }
3325 break;
3326
3327 case SKPC_GROUP_IPSET:
3328 if (skIPSetUnion(group->g_value.ipset, g->g_value.ipset)) {
3329 return -1;
3330 }
3331 if (skIPSetClean(group->g_value.ipset)) {
3332 return -1;
3333 }
3334 break;
3335 }
3336
3337 return 0;
3338 }
3339
3340
3341 /* is group frozen? */
3342 int
skpcGroupIsFrozen(const skpc_group_t * group)3343 skpcGroupIsFrozen(
3344 const skpc_group_t *group)
3345 {
3346 assert(group);
3347 return group->g_is_frozen;
3348 }
3349
3350
3351 /* find the group named 'group_name' */
3352 skpc_group_t *
skpcGroupLookupByName(const char * group_name)3353 skpcGroupLookupByName(
3354 const char *group_name)
3355 {
3356 skpc_group_t **group;
3357 size_t i;
3358
3359 assert(skpc_groups);
3360
3361 /* check input */
3362 if (group_name == NULL) {
3363 return NULL;
3364 }
3365
3366 /* loop over all groups until we find one with given name */
3367 for (i = 0;
3368 (group = (skpc_group_t**)skVectorGetValuePointer(skpc_groups, i))
3369 != NULL;
3370 ++i)
3371 {
3372 if ((NULL != (*group)->g_name)
3373 && (0 == strcmp(group_name, (*group)->g_name)))
3374 {
3375 if (skpcGroupFreeze(*group)) {
3376 return NULL;
3377 }
3378 return *group;
3379 }
3380 }
3381
3382 return NULL;
3383 }
3384
3385
3386 /*
3387 * status = skpcGroupComputeComplement(group);
3388 *
3389 * If the type of 'group' is SKPC_GROUP_INTERFACE, modify the group
3390 * contain the complement of its current interface list. Return 0
3391 * on success.
3392 *
3393 * Return -1 if 'group' is frozen or has a type other than
3394 * SKPC_GROUP_INTERFACE.
3395 */
3396 static int
skpcGroupComputeComplement(skpc_group_t * group)3397 skpcGroupComputeComplement(
3398 skpc_group_t *group)
3399 {
3400 assert(group);
3401 if (group->g_is_frozen) {
3402 return -1;
3403 }
3404
3405 /* can only complement interfaces */
3406 if (SKPC_GROUP_INTERFACE != group->g_type) {
3407 return -1;
3408 }
3409
3410 skBitmapComplement(group->g_value.map);
3411 return 0;
3412 }
3413
3414
3415 /*
3416 * found = skpcGroupCheckInterface(group, interface);
3417 *
3418 * Return 1 if 'group' contains the value 'interface'; 0 otherwise.
3419 */
3420 static int
skpcGroupCheckInterface(const skpc_group_t * group,uint32_t interface)3421 skpcGroupCheckInterface(
3422 const skpc_group_t *group,
3423 uint32_t interface)
3424 {
3425 assert(group->g_type == SKPC_GROUP_INTERFACE);
3426 return skBitmapGetBit(group->g_value.map, interface);
3427 }
3428
3429
3430 /*
3431 * found = skpcGroupCheckIPblock(group, ip);
3432 *
3433 * Return 1 if 'group' contains the IP Address 'ip'; 0 otherwise.
3434 */
3435 static int
skpcGroupCheckIPblock(const skpc_group_t * group,const skipaddr_t * ip)3436 skpcGroupCheckIPblock(
3437 const skpc_group_t *group,
3438 const skipaddr_t *ip)
3439 {
3440 size_t i;
3441
3442 assert(group->g_type == SKPC_GROUP_IPBLOCK);
3443 for (i = 0; i < group->g_itemcount; ++i) {
3444 if (skIPWildcardCheckIp(group->g_value.ipblock[i], ip)) {
3445 return 1;
3446 }
3447 }
3448 return 0;
3449 }
3450
3451
3452 /*
3453 * found = skpcGroupCheckIPset(group, ip);
3454 *
3455 * Return 1 if 'group' contains the IP Address 'ip'; 0 otherwise.
3456 */
3457 static int
skpcGroupCheckIPset(const skpc_group_t * group,const skipaddr_t * ip)3458 skpcGroupCheckIPset(
3459 const skpc_group_t *group,
3460 const skipaddr_t *ip)
3461 {
3462 assert(group->g_type == SKPC_GROUP_IPSET);
3463 return skIPSetCheckAddress(group->g_value.ipset, ip);
3464 }
3465
3466
3467 /*
3468 * count = skpcGroupGetItemCount(group);
3469 *
3470 * Return the count of the number of items in 'group'. Returns 0
3471 * if 'group' is not frozen.
3472 */
3473 static uint32_t
skpcGroupGetItemCount(const skpc_group_t * group)3474 skpcGroupGetItemCount(
3475 const skpc_group_t *group)
3476 {
3477 assert(group);
3478 return group->g_itemcount;
3479 }
3480
3481
3482 /*
3483 * ***** Probes Types *****************************************************
3484 */
3485
3486 /* return an enum value given a probe type name */
3487 skpc_probetype_t
skpcProbetypeNameToEnum(const char * name)3488 skpcProbetypeNameToEnum(
3489 const char *name)
3490 {
3491 const struct probe_type_name_map_st *entry;
3492
3493 if (name) {
3494 for (entry = probe_type_name_map; entry->name; ++entry) {
3495 if (0 == strcmp(name, entry->name)) {
3496 return entry->value;
3497 }
3498 }
3499 }
3500 return PROBE_ENUM_INVALID;
3501 }
3502
3503
3504 /* return the name given a probe type number */
3505 const char *
skpcProbetypeEnumtoName(skpc_probetype_t type)3506 skpcProbetypeEnumtoName(
3507 skpc_probetype_t type)
3508 {
3509 const struct probe_type_name_map_st *entry;
3510
3511 for (entry = probe_type_name_map; entry->name; ++entry) {
3512 if (type == entry->value) {
3513 return entry->name;
3514 }
3515 }
3516 return NULL;
3517 }
3518
3519
3520 /* return a name given a group type */
3521 const char *
skpcGrouptypeEnumtoName(skpc_group_type_t type)3522 skpcGrouptypeEnumtoName(
3523 skpc_group_type_t type)
3524 {
3525 switch (type) {
3526 case SKPC_GROUP_INTERFACE:
3527 return "interface";
3528 case SKPC_GROUP_IPBLOCK:
3529 return "ipblock";
3530 case SKPC_GROUP_IPSET:
3531 return "ipset";
3532 case SKPC_GROUP_UNSET:
3533 break;
3534 }
3535 return NULL;
3536 }
3537
3538
3539 /*
3540 * ***** Probes Protocols *************************************************
3541 */
3542
3543 /* return an protocol enum value given a probe protocol name */
3544 skpc_proto_t
skpcProtocolNameToEnum(const char * name)3545 skpcProtocolNameToEnum(
3546 const char *name)
3547 {
3548 const struct skpc_protocol_name_map_st *entry;
3549 uint32_t num;
3550
3551 if (NULL != name) {
3552 for (entry = skpc_protocol_name_map; entry->name; ++entry) {
3553 if (0 == strcmp(name, entry->name)) {
3554 return entry->value;
3555 }
3556 }
3557 if (isdigit((int)*name)) {
3558 /* attempt to parse as a number */
3559 if (0 == skStringParseUint32(&num, name, 0, 255)) {
3560 for (entry = skpc_protocol_name_map; entry->name; ++entry) {
3561 if (num == entry->num) {
3562 return entry->value;
3563 }
3564 }
3565 }
3566 }
3567 }
3568
3569 return SKPC_PROTO_UNSET;
3570 }
3571
3572
3573 /* return a name given a probe protocol enum */
3574 const char *
skpcProtocolEnumToName(skpc_proto_t protocol)3575 skpcProtocolEnumToName(
3576 skpc_proto_t protocol)
3577 {
3578 const struct skpc_protocol_name_map_st *entry;
3579
3580 for (entry = skpc_protocol_name_map; entry->name; ++entry) {
3581 if (protocol == entry->value) {
3582 return entry->name;
3583 }
3584 }
3585 return NULL;
3586 }
3587
3588
3589 /*
3590 ** Local Variables:
3591 ** mode:c
3592 ** indent-tabs-mode:nil
3593 ** c-basic-offset:4
3594 ** End:
3595 */
3596