summaryrefslogtreecommitdiff
path: root/src/libosfp_score_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libosfp_score_db.c')
-rw-r--r--src/libosfp_score_db.c575
1 files changed, 0 insertions, 575 deletions
diff --git a/src/libosfp_score_db.c b/src/libosfp_score_db.c
deleted file mode 100644
index 58e85de..0000000
--- a/src/libosfp_score_db.c
+++ /dev/null
@@ -1,575 +0,0 @@
-#include "libosfp_common.h"
-
-#include "libosfp_fingerprint.h"
-#include "libosfp_default_fingerprints.h"
-#include "libosfp_score_db.h"
-#include "libosfp_log.h"
-
-#define LIBOSFP_PERCENTILE 100
-
-#define LIBOSFP_SCORE_DB_FIELD_UINT_VALUE_MAX 65536
-
-typedef struct libosfp_score_db_array_data {
- libosfp_score_t *array_head;
- unsigned int array_len;
-} libosfp_score_db_array_data_t;
-
-typedef struct libosfp_score_db_hash_element {
- char *key;
- unsigned int keylen;
- libosfp_score_t *score;
- UT_hash_handle hh;
-} libosfp_score_db_hash_element_t;
-
-typedef struct libosfp_score_db_hash_data {
- libosfp_score_db_hash_element_t *hash_head;
-} libosfp_score_db_hash_data_t;
-
-
-int libosfp_score_db_array_add(void *data, libosfp_score_t *score, void *value, unsigned int len)
-{
- int ret = -1, i;
- unsigned int index;
- libosfp_score_db_array_data_t *array_data = (libosfp_score_db_array_data_t *)data;
-
- if (array_data == NULL || score == NULL || value == NULL || len != sizeof(unsigned int)) {
- goto exit;
- }
-
- if (array_data->array_head == NULL || array_data->array_len == 0) {
- goto exit;
- }
-
- index = *(unsigned int *)value;
-
- if (index >= array_data->array_len) {
- goto exit;
- }
-
- for (i = 0; i < LIBOSFP_OS_CLASS_MAX; i++) {
- array_data->array_head[index].os_class_score[i] += score->os_class_score[i];
- }
-
- return 0;
-exit:
- return ret;
-}
-
-libosfp_score_t *libosfp_score_db_array_match(void *data, void *value, unsigned int len)
-{
- unsigned int index;
- libosfp_score_db_array_data_t *array_data = (libosfp_score_db_array_data_t *)data;
-
- if (array_data == NULL || value == NULL || len != sizeof(unsigned int)) {
- return NULL;
- }
-
- if (array_data->array_head == NULL || array_data->array_len == 0) {
- return NULL;
- }
-
- index = *(unsigned int *)value;
-
- if (index >= array_data->array_len) {
- return NULL;
- }
-
- return &((array_data->array_head)[index]);
-}
-
-void *libosfp_score_db_array_create(void)
-{
- libosfp_score_db_array_data_t *array_data = calloc(1, sizeof(libosfp_score_db_array_data_t));
- if (array_data == NULL) {
- return NULL;
- }
-
- array_data->array_head = calloc(LIBOSFP_SCORE_DB_FIELD_UINT_VALUE_MAX, sizeof(libosfp_score_t));
- if (array_data->array_head == NULL) {
- free(array_data);
- return NULL;
- }
-
- array_data->array_len = LIBOSFP_SCORE_DB_FIELD_UINT_VALUE_MAX;
-
- return (void *)array_data;
-}
-
-void libosfp_score_db_array_destroy(void *data) {
- libosfp_score_db_array_data_t *array_data = (libosfp_score_db_array_data_t *)data;
-
- if (array_data) {
- if (array_data->array_head) {
- free(array_data->array_head);
- }
- free(array_data);
- }
-}
-
-int libosfp_score_db_hash_add(void *data, libosfp_score_t *score, void *value, unsigned int len)
-{
- int ret = -1, i;
- libosfp_score_db_hash_data_t *hash_data = (libosfp_score_db_hash_data_t *)data;
- libosfp_score_db_hash_element_t *element = NULL;
-
- if (hash_data == NULL || score == NULL || value == NULL || len == 0) {
- goto exit;
- }
-
- HASH_FIND(hh, hash_data->hash_head, value, len, element);
- if (element == NULL) {
- element = (libosfp_score_db_hash_element_t *)calloc(1, sizeof(libosfp_score_db_hash_element_t));
- if (element == NULL) {
- goto exit;
- }
- element->key = strdup(value);
- element->keylen = len;
- element->score = (libosfp_score_t *)calloc(1, sizeof(libosfp_score_t));
- if (element->score == NULL) {
- free(element);
- element = NULL;
- goto exit;
- }
- HASH_ADD_KEYPTR(hh, hash_data->hash_head, element->key, element->keylen, element);
- }
-
- for (i = 0; i < LIBOSFP_OS_CLASS_MAX; i++) {
- element->score->os_class_score[i] += score->os_class_score[i];
- }
-
- return 0;
-exit:
- return ret;
-}
-
-libosfp_score_t *libosfp_score_db_hash_match(void *data, void *value, unsigned int len)
-{
- libosfp_score_db_hash_data_t *hash_data = (libosfp_score_db_hash_data_t *)data;
- libosfp_score_db_hash_element_t *element = NULL;
-
- if (data == NULL || value == NULL || len == 0) {
- return NULL;
- }
-
- if (hash_data->hash_head == NULL) {
- return NULL;
- }
-
- HASH_FIND(hh, hash_data->hash_head, value, len, element);
- if (element == NULL) {
- return NULL;
- }
-
- return element->score;
-}
-
-void *libosfp_score_db_hash_create(void)
-{
- return (void*)calloc(1, sizeof(libosfp_score_db_hash_data_t));
-}
-
-void libosfp_score_db_hash_destroy(void *data) {
- libosfp_score_db_hash_data_t *hash_data = (libosfp_score_db_hash_data_t *)data;
- libosfp_score_db_hash_element_t *element = NULL;
- libosfp_score_db_hash_element_t *tmp = NULL;
-
- if (hash_data) {
- if (hash_data->hash_head) {
- HASH_ITER(hh, hash_data->hash_head, element, tmp) {
- HASH_DELETE(hh, hash_data->hash_head, element);
- if (element) {
- if (element->key) {
- free(element->key);
- }
- if (element->score) {
- free(element->score);
- }
- free(element);
- }
- }
- }
- free(hash_data);
- }
-}
-
-libosfp_score_t *libosfp_score_db_filed_match(libosfp_field_score_db_t *db, void *value, unsigned int len)
-{
- if (db == NULL || value == NULL || len == 0) {
- return NULL;
- }
-
- return db->match(db->data, value, len);
-}
-
-char *libosfp_score_db_read_file(char *fp_file)
-{
- int ret = -1;
- char *file_buffer = NULL;
- unsigned int file_len = 0;
- FILE *fp = NULL;
- struct stat st;
-
- if (0 > stat(fp_file, &st)) {
- printf("stat() on '%s' failed.\n", fp_file);
- goto exit;
- }
-
- if (st.st_size == 0) {
- printf("Empty file: %s.\n", fp_file);
- goto exit;
- }
-
- file_len = (unsigned int)st.st_size;
- file_buffer = malloc(file_len);
- if (file_buffer == NULL) {
- printf("Not enough memory for file buffer. file name: %s\n",fp_file);
- goto exit;
- }
-
- fp = fopen(fp_file, "r");
- if (fp == NULL) {
- printf("Cannot open '%s' for reading.\n", fp_file);
- goto exit;
- }
-
- ret = fread(file_buffer, 1, file_len, fp);
- if (ret < 0) {
- free(file_buffer);
- fclose(fp);
- goto exit;
- }
-
- fclose(fp);
-
- return file_buffer;
-exit:
- return NULL;
-}
-
-int libosfp_score_db_load_field(libosfp_field_score_db_t *db, cJSON *field, libosfp_os_class_id_t os_class)
-{
- int ret = -1;
- libosfp_score_t score = {0};
-
- void *value_ptr;
- unsigned int value_len;
-
- switch (field->type) {
- case cJSON_Number:
- value_ptr = (void *)&field->valueint;
- value_len = sizeof(field->valueint);
- break;
- case cJSON_String:
- value_ptr = (void *)field->valuestring;
- value_len = strlen(field->valuestring) + 1;
- break;
- case cJSON_NULL:
- ret = 0;
- goto exit;
- default:
- goto exit;
- }
-
- score.os_class_score[os_class] = 1;
-
- ret = db->add(db->data, &score, value_ptr, value_len);
- if (ret != 0) {
- goto exit;
- }
-
- db->entry_count++;
-
- return 0;
-exit:
- return ret;
-}
-
-int libosfp_score_db_load_entry(libosfp_score_db_t *score_db, cJSON *entry)
-{
- int ret = -1, i;
- cJSON *field = NULL;
-
- if (score_db == NULL || entry == NULL) {
- goto exit;
- }
-
- field = cJSON_GetObjectItem(entry, libosfp_fingerprint_get_field_name(LIBOSFP_FIELD_OS));
- if (field == NULL || field->valuestring == NULL) {
- goto exit;
- }
-
- libosfp_os_class_id_t os_class = libosfp_os_class_name_to_id(field->valuestring);
- if (os_class >= LIBOSFP_OS_CLASS_MAX) {
- goto exit;
- }
-
- for (i = 0; i < LIBOSFP_FIELD_OS; i++) {
- libosfp_field_score_db_t *db = &score_db->field_score_dbs[i];
- if (db == NULL) {
- goto exit;
- }
-
- if (!db->enabled) {
- continue;
- }
-
- field = cJSON_GetObjectItem(entry, libosfp_fingerprint_get_field_name(i));
- if (field == NULL) {
- printf("json entry missing field: %s\n%s\n",
- libosfp_fingerprint_get_field_name(i), cJSON_Print(entry));
- continue;
- }
-
- ret = libosfp_score_db_load_field(db, field, os_class);
- if (ret != 0) {
- printf("json entry field load failed. field: %s\n%s\n",
- libosfp_fingerprint_get_field_name(i), cJSON_Print(entry));
- continue;
- }
- }
-
- score_db->entry_count++;
- score_db->os_class_entry_count[os_class]++;
-
- return 0;
-exit:
- return ret;
-}
-
-int libosfp_score_db_load(libosfp_score_db_t *score_db, char *fp_file)
-{
- int ret = LIBOSFP_EINVAL, i;
- const char *file_buffer;
- libosfp_field_score_db_t *field_score_db;
-
- cJSON *root = NULL;
- cJSON *entry = NULL;
-
- if (score_db == NULL) {
- goto exit;
- }
-
- if (fp_file == NULL) {
- file_buffer = g_default_fingerprints;
- } else {
- file_buffer = (const char *)libosfp_score_db_read_file(fp_file);
- if (file_buffer == NULL) {
- ret = LIBOSFP_ERR_SCORE_DB_READ_FILE;
- goto exit;
- }
- }
-
- root = cJSON_Parse(file_buffer);
-
- if (file_buffer != g_default_fingerprints) {
- free((char*)file_buffer);
- }
-
- if (root == NULL) {
- ret = LIBOSFP_ERR_SCORE_DB_PARSE_FILE;
- goto exit;
- }
-
- score_db->entry_count = cJSON_GetArraySize(root);
-
- for (i = 0; i < LIBOSFP_FIELD_MAX; i++) {
- field_score_db = &score_db->field_score_dbs[i];
- if (field_score_db->enabled) {
- score_db->perfect_score += libosfp_fingerprint_get_field_importance(i);
- }
- }
-
- for (i = 0; i < score_db->entry_count; i++) {
- entry = cJSON_GetArrayItem(root, i);
- if (entry) {
- ret = libosfp_score_db_load_entry(score_db, entry);
- if (ret != 0) {
- libosfp_log_debug("json entry load failed.\n%s\n", cJSON_Print(entry));
- continue;
- }
- }
- }
-
- cJSON_Delete(root);
-
- return LIBOSFP_NOERR;
-exit:
-
- return ret;
-}
-
-int libosfp_score_db_score(libosfp_score_db_t *score_db, unsigned int flags, libosfp_fingerprint_t *fp, libosfp_score_t *result_score)
-{
- int ret = LIBOSFP_EINVAL, i, j;
- unsigned int os_class_score;
- unsigned int likely_score;
- unsigned int perfect_score;
- unsigned int entry_count;
- unsigned int importance;
- libosfp_score_t *matched_score;
- libosfp_os_class_id_t likely_os_class;
- libosfp_fingerprint_field_t *field;
- libosfp_field_score_db_t *field_score_db;
-
- if (score_db == NULL || fp == NULL || result_score == NULL) {
- goto exit;
- }
-
- memset(result_score, 0, sizeof(libosfp_score_t));
-
- perfect_score = score_db->perfect_score;
- if (perfect_score == 0) {
- goto exit;
- }
-
- for (i = 0; i < LIBOSFP_FIELD_MAX; i++) {
- field_score_db = &score_db->field_score_dbs[i];
- if (!field_score_db->enabled) {
- continue;
- }
-
- field = &fp->fields[i];
- if (!field->enabled) {
- continue;
- }
-
- matched_score = libosfp_score_db_filed_match(field_score_db, field->value, field->value_len);
- if (matched_score == NULL) {
- continue;
- }
-
- importance = libosfp_fingerprint_get_field_importance(i);
-
- for (j = 0; j < LIBOSFP_OS_CLASS_MAX; j++) {
- if (0 == flags || flags & LIBOSFP_BIT_U32(j)) {
- result_score->os_class_score[j] += matched_score->os_class_score[j] * importance / perfect_score;
- }
- }
-
- if (i == LIBOSFP_FIELD_TCP_OPTIONS) {
- i++;
- }
- }
-
- likely_score = result_score->likely_score;
- likely_os_class = result_score->likely_os_class;
-
- for (i = 0; i < LIBOSFP_OS_CLASS_MAX; i++) {
- entry_count = score_db->os_class_entry_count[i];
- os_class_score = result_score->os_class_score[i];
-
- if (entry_count == 0) {
- continue;
- }
-
- // calc percentile score
- os_class_score = (LIBOSFP_PERCENTILE * os_class_score) / entry_count;
-
- // calc likely os class and score
- if (likely_score < os_class_score) {
- likely_score = os_class_score;
- likely_os_class = i;
- }
-
- result_score->os_class_score[i] = os_class_score;
- }
-
- result_score->likely_score = likely_score;
- result_score->likely_os_class = likely_os_class;
-
- return LIBOSFP_NOERR;
-exit:
- return ret;
-}
-
-void libosfp_score_db_debug_print(libosfp_score_db_t *score_db)
-{
- int i;
- printf("score_db:\n");
- printf("entry_count: %u\n", score_db->entry_count);
- printf("perfect_score: %u\n", score_db->perfect_score);
-
- for (i = 0; i < LIBOSFP_OS_CLASS_MAX; i++) {
- const char *name = libosfp_os_class_id_to_name(i);
- printf("os class %s ", name);
-
- printf("entry_count: %u\n", score_db->os_class_entry_count[i]);
- printf("os class %s entry_count: %u\n", libosfp_os_class_id_to_name(i), score_db->os_class_entry_count[i]);
- }
-
- for (i = 0; i < LIBOSFP_FIELD_MAX; i++) {
- printf("field %s enabled: %u\n", libosfp_fingerprint_get_field_name(i), score_db->field_score_dbs[i].enabled);
- printf("field %s type: %u\n", libosfp_fingerprint_get_field_name(i), score_db->field_score_dbs[i].type);
- printf("field %s entry_count: %u\n", libosfp_fingerprint_get_field_name(i), score_db->field_score_dbs[i].entry_count);
- printf("field %s enabled: %p\n", libosfp_fingerprint_get_field_name(i), score_db->field_score_dbs[i].data);
- }
-}
-
-libosfp_score_db_t *libosfp_score_db_create(void)
-{
- int i;
- libosfp_score_db_t *score_db;
- libosfp_field_score_db_t *db;
-
- score_db = calloc(1, sizeof(libosfp_score_db_t));
- if (score_db == NULL) {
- goto exit;
- }
-
- for (i = 0; i < LIBOSFP_FIELD_MAX; i++) {
- db = &score_db->field_score_dbs[i];
-
- db->enabled = libosfp_fingerprint_get_field_enabled(i);
- if (!db->enabled) {
- libosfp_log_warning("field disabled: %s", "");
- continue;
- }
-
- db->type = libosfp_fingerprint_get_field_type(i);
- switch (db->type) {
- case LIBOSFP_FIELD_TYPE_UINT:
- db->create = libosfp_score_db_array_create;
- db->destroy = libosfp_score_db_array_destroy;
- db->add = libosfp_score_db_array_add;
- db->match = libosfp_score_db_array_match;
- break;
- case LIBOSFP_FIELD_TYPE_STRING:
- db->create = libosfp_score_db_hash_create;
- db->destroy = libosfp_score_db_hash_destroy;
- db->add = libosfp_score_db_hash_add;
- db->match = libosfp_score_db_hash_match;
- break;
- default:
- libosfp_log_debug("unsupported type: %u", db->type);
- goto exit;
- }
-
- db->data = db->create();
- if (db->data == NULL) {
- libosfp_log_debug("create failed. field: %s", libosfp_fingerprint_get_field_name(i));
- goto exit;
- }
- }
-
- return score_db;
-exit:
- if (score_db) {
- libosfp_score_db_destroy(score_db);
- }
- return NULL;
-}
-
-void libosfp_score_db_destroy(libosfp_score_db_t *score_db)
-{
- int i;
- libosfp_field_score_db_t *db;
-
- if (score_db) {
- for (i = 0; i < LIBOSFP_FIELD_MAX; i++) {
- db = &score_db->field_score_dbs[i];
- db->destroy(db->data);
- db->data = NULL;
- }
- free(score_db);
- }
-}