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