diff --git a/src/Makefile.am b/src/Makefile.am index f1ed914752..8956b6bdbc 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -291,6 +291,7 @@ detect-modbus.c detect-modbus.h \ detect-xbits.c detect-xbits.h \ detect-cipservice.c detect-cipservice.h \ device-storage.c device-storage.h \ +feature.c feature.h \ flow-bit.c flow-bit.h \ flow.c flow.h \ flow-bypass.c flow-bypass.h \ diff --git a/src/feature.c b/src/feature.c new file mode 100644 index 0000000000..d759194f03 --- /dev/null +++ b/src/feature.c @@ -0,0 +1,147 @@ +/* Copyright (C) 2019 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Jeff Lucovsky + * + * Implements feature tracking + */ + +#include "suricata-common.h" +#include "feature.h" + +#include "util-hash.h" + +typedef struct FeatureEntryType { + const char *feature; +} FeatureEntryType; + +static SCMutex feature_table_mutex = SCMUTEX_INITIALIZER; +static HashListTable *feature_hash_table; + +static uint32_t FeatureHashFunc(HashListTable *ht, void *data, + uint16_t datalen) +{ + FeatureEntryType *f = (FeatureEntryType *)data; + uint32_t hash = 0; + int len = strlen(f->feature); + + for (int i = 0; i < len; i++) + hash += tolower((unsigned char)f->feature[i]); + + return (hash % ht->array_size); +} + +static char FeatureHashCompareFunc(void *data1, uint16_t datalen1, + void *data2, uint16_t datalen2) +{ + FeatureEntryType *f1 = (FeatureEntryType *)data1; + FeatureEntryType *f2 = (FeatureEntryType *)data2; + int len1 = 0; + int len2 = 0; + + if (f1 == NULL || f2 == NULL) + return 0; + + if (f1->feature == NULL || f2->feature == NULL) + return 0; + + len1 = strlen(f1->feature); + len2 = strlen(f2->feature); + + return (len1 == len2 && memcmp(f1->feature, f2->feature, len1) == 0); +} + +static void FeatureHashFreeFunc(void *data) +{ + FeatureEntryType *f = data; + if (f->feature) { + SCFree((void *)f->feature); + } + SCFree(data); +} + +static void FeatureInit(void) { + feature_hash_table = HashListTableInit(256, FeatureHashFunc, + FeatureHashCompareFunc, + FeatureHashFreeFunc); + + if (!feature_hash_table) { + FatalError(SC_ERR_MEM_ALLOC, "Unable to allocate feature hash table."); + } +} + +static void FeatureAddEntry(const char *feature_name) +{ + int rc; + + FeatureEntryType *feature = SCCalloc(1, sizeof(*feature)); + if (!feature) { + FatalError(SC_ERR_MEM_ALLOC, "Unable to allocate feature entry memory."); + } + + feature->feature = SCStrdup(feature_name); + if (feature->feature) { + rc = HashListTableAdd(feature_hash_table, feature, sizeof(*feature)); + if (rc == 0) + return; + } + + FeatureHashFreeFunc(feature); +} + +void ProvidesFeature(const char *feature_name) +{ + FeatureEntryType f = { feature_name }; + + SCMutexLock(&feature_table_mutex); + + FeatureEntryType *feature = HashListTableLookup(feature_hash_table, &f, sizeof(f)); + + if (!feature) { + FeatureAddEntry(feature_name); + } + + SCMutexUnlock(&feature_table_mutex); +} + +bool RequiresFeature(const char *feature_name) +{ + FeatureEntryType t = { 0, feature_name }; + + SCMutexLock(&feature_table_mutex); + FeatureEntryType *feature = HashTableLookup(feature_hash_table, &t, sizeof(t)); + SCMutexUnlock(&feature_table_mutex); + + return feature != NULL; +} + +void FeatureTrackingRelease(void) +{ + if (feature_hash_table != NULL) { + HashTableFree(feature_hash_table); + feature_hash_table = NULL; + feature_table_id = 0; + } +} + +void FeatureTrackingRegister(void) +{ + FeatureInit(); +} diff --git a/src/feature.h b/src/feature.h new file mode 100644 index 0000000000..3bb48a097e --- /dev/null +++ b/src/feature.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2019 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Jeff Lucovsky + */ + +#ifndef __FEATURE_H__ +#define __FEATURE_H__ + +/* Provided feature names */ +#define FEATURE_OUTPUT_FILESTORE "output::file-store" + +void ProvidesFeature(const char *); +bool RequiresFeature(const char *); + +void FeatureTrackingRelease(void); +void FeatureTrackingRegister(void); + +#endif /* __FEATURE_H__ */