diff options
Diffstat (limited to 'src/libosfp_score_db.c')
| -rw-r--r-- | src/libosfp_score_db.c | 575 |
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); - } -} |
