summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzhuzhenjun <[email protected]>2023-09-27 15:43:32 +0800
committerzhuzhenjun <[email protected]>2023-09-27 19:40:42 +0800
commit1a559eba9916e4e39f660cf803ab7196cdd7c342 (patch)
treeaa6ebd9ec47c7a7a427086752913ff6d8f694c58 /src
parent15d4a2d27198005b557b62dbfbb03c49d5b5220c (diff)
v0.0.4
Diffstat (limited to 'src')
-rw-r--r--src/osfp.c21
-rw-r--r--src/osfp.h6
-rw-r--r--src/osfp_common.h1
-rw-r--r--src/osfp_log.c12
-rw-r--r--src/osfp_log.h8
-rw-r--r--src/osfp_score_db.c43
-rw-r--r--src/osfp_score_db.h4
7 files changed, 63 insertions, 32 deletions
diff --git a/src/osfp.c b/src/osfp.c
index 1a847ec..87685ba 100644
--- a/src/osfp.c
+++ b/src/osfp.c
@@ -6,11 +6,13 @@
#include "osfp_log.h"
#define OSFP_DEFAULT_RESULT_BUFLEN_MAX 512
+#define OSFP_LOWEST_SCORE_LIMIT 20
static struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_class_score)
{
int i;
unsigned int tmp_score;
+ unsigned int sum_score;
unsigned int likely_score;
enum osfp_os_class_id likely_os_class;
struct osfp_result *result;
@@ -22,6 +24,7 @@ static struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_clas
likely_score = 0;
likely_os_class = OSFP_OS_CLASS_OTHERS;
+ sum_score = 0;
for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
tmp_score = os_class_score->scores[i];
@@ -31,27 +34,37 @@ static struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_clas
likely_os_class = i;
}
result->detail.scores[i] = tmp_score;
+ sum_score += tmp_score;
+ }
+
+ if (sum_score) {
+ for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
+ result->detail.possibility[i] = OSFP_PERCENTILE * result->detail.scores[i] / sum_score;
+ }
}
result->likely_score = likely_score;
result->likely_os_class = likely_os_class;
+ result->likely_possibility = result->detail.possibility[likely_os_class];
- if (likely_score < 10) {
+ if (likely_score < OSFP_LOWEST_SCORE_LIMIT) {
result->likely_os_class = OSFP_OS_CLASS_OTHERS;
result->likely_score = 0;
+ result->likely_possibility = 0;
} else {
for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
if (likely_os_class == i) {
continue;
}
if (likely_score == os_class_score->scores[i]) {
- if (likely_os_class == OSFP_OS_CLASS_LINUX && os_class_score->scores[i] == OSFP_OS_CLASS_ANDROID) {
+ if (likely_os_class == OSFP_OS_CLASS_LINUX && i == OSFP_OS_CLASS_ANDROID) {
continue;
- } else if (likely_os_class == OSFP_OS_CLASS_MAC_OS && os_class_score->scores[i] == OSFP_OS_CLASS_IOS) {
+ } else if (likely_os_class == OSFP_OS_CLASS_MAC_OS && i == OSFP_OS_CLASS_IOS) {
continue;
} else {
result->likely_os_class = OSFP_OS_CLASS_UNKNOWN;
result->likely_score = 0;
+ result->likely_possibility = 0;
break;
}
}
@@ -103,6 +116,7 @@ char *osfp_result_score_detail_export(struct osfp_result *result)
if (os_score) {
cJSON_AddStringToObject(os_score, "name", osfp_os_class_id_to_name(result->likely_os_class));
cJSON_AddNumberToObject(os_score, "score", result->likely_score);
+ //cJSON_AddNumberToObject(os_score, "possibility", result->likely_possibility);
}
array = cJSON_AddArrayToObject(root, "detail");
@@ -112,6 +126,7 @@ char *osfp_result_score_detail_export(struct osfp_result *result)
if (os_score) {
cJSON_AddStringToObject(os_score, "name", osfp_os_class_id_to_name(i));
cJSON_AddNumberToObject(os_score, "score", result->detail.scores[i]);
+ //cJSON_AddNumberToObject(os_score, "possibility", result->detail.possibility[i]);
cJSON_AddItemToArray(array, os_score);
}
}
diff --git a/src/osfp.h b/src/osfp.h
index afe629c..0a4c7e6 100644
--- a/src/osfp.h
+++ b/src/osfp.h
@@ -27,8 +27,9 @@ enum osfp_os_class_id {
OSFP_OS_CLASS_MAX,
};
-struct osfp_os_class_score {
+struct osfp_os_result_detail {
unsigned int scores[OSFP_OS_CLASS_MAX];
+ unsigned int possibility[OSFP_OS_CLASS_MAX];
};
struct osfp_result {
@@ -36,8 +37,9 @@ struct osfp_result {
enum osfp_os_class_id likely_os_class;
unsigned int likely_score;
+ unsigned int likely_possibility;
- struct osfp_os_class_score detail;
+ struct osfp_os_result_detail detail;
};
struct osfp_db {
diff --git a/src/osfp_common.h b/src/osfp_common.h
index ed300af..5d1d7bf 100644
--- a/src/osfp_common.h
+++ b/src/osfp_common.h
@@ -139,6 +139,7 @@ enum osfp_error_code {
#define OSFP_OS_CLASS_FLAG_IOS OSFP_BIT_U32(OSFP_OS_CLASS_IOS)
#define OSFP_OS_CLASS_FLAG_ANDROID OSFP_BIT_U32(OSFP_OS_CLASS_ANDROID)
+#define OSFP_PERCENTILE 100
const char *osfp_os_class_id_to_name(enum osfp_os_class_id os_class);
enum osfp_os_class_id osfp_os_class_name_to_id(char *name);
diff --git a/src/osfp_log.c b/src/osfp_log.c
index 1c65eb7..66f28d2 100644
--- a/src/osfp_log.c
+++ b/src/osfp_log.c
@@ -4,7 +4,7 @@
/* The maximum length of the log message */
#define OSFP_MAX_LOG_MSG_LEN 2048
-unsigned int osfp_log_level = OSFP_LOG_LEVEL_INFO;
+unsigned int g_osfp_log_level = OSFP_LOG_LEVEL_WARNING;
void osfp_log_message(unsigned int x, const char *file, const int line, const char *func, const char *msg)
{
@@ -32,11 +32,15 @@ void osfp_log_message(unsigned int x, const char *file, const int line, const ch
break;
}
+ if (fprintf(stdout, "%s\n", buffer) < 0) {
+ printf("Error writing to stream using fprintf\n");
+ }
+ fflush(stdout);
}
void osfp_log(unsigned int x, const char *file, const int line, const char *func, const char *fmt, ...)
{
- if (osfp_log_level >= x ) {
+ if (g_osfp_log_level <= x ) {
char msg[OSFP_MAX_LOG_MSG_LEN];
va_list ap;
va_start(ap, fmt);
@@ -46,8 +50,8 @@ void osfp_log(unsigned int x, const char *file, const int line, const char *func
}
}
-void osfp_log_level_set(osfp_log_level_t level)
+void osfp_log_level_set(enum osfp_log_level level)
{
- osfp_log_level = level;
+ g_osfp_log_level = level;
}
diff --git a/src/osfp_log.h b/src/osfp_log.h
index 15f372b..3e51667 100644
--- a/src/osfp_log.h
+++ b/src/osfp_log.h
@@ -1,14 +1,14 @@
#ifndef __OSFP_LOG_H__
#define __OSFP_LOG_H__
-typedef enum osfp_log_level {
+enum osfp_log_level {
OSFP_LOG_LEVEL_DEBUG,
OSFP_LOG_LEVEL_INFO,
OSFP_LOG_LEVEL_WARNING,
OSFP_LOG_LEVEL_ERROR
-} osfp_log_level_t;
+};
-#ifndef DEBUG
+#ifndef DEBUGLOG
#define osfp_log_debug(...) do { } while (0)
#else
#define osfp_log_debug(...) osfp_log(OSFP_LOG_LEVEL_DEBUG, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
@@ -18,7 +18,7 @@ typedef enum osfp_log_level {
#define osfp_log_error(...) osfp_log(OSFP_LOG_LEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__,__VA_ARGS__)
-void osfp_log_level_set(osfp_log_level_t level);
+void osfp_log_level_set(enum osfp_log_level level);
void osfp_log(unsigned int x, const char *file, const int line, const char *func, const char *fmt, ...);
#endif
diff --git a/src/osfp_score_db.c b/src/osfp_score_db.c
index 4aecc7c..c5f5d1f 100644
--- a/src/osfp_score_db.c
+++ b/src/osfp_score_db.c
@@ -5,7 +5,8 @@
#include "osfp_score_db.h"
#include "osfp_log.h"
-#define OSFP_PERCENTILE 100
+#define PERFECT_SCORE_EXPECTED_RATE 0.5f
+#define FIELD_VALUE_DUP_RATE_MAX 0.5f
#define OSFP_SCORE_DB_FIELD_UINT_VALUE_MAX 65536
@@ -209,30 +210,31 @@ char *osfp_score_db_read_file(char *fp_file)
struct stat st;
if (0 > stat(fp_file, &st)) {
- printf("stat() on '%s' failed.\n", fp_file);
+ osfp_log_error("stat() failed on '%s'.\n", fp_file);
goto exit;
}
if (st.st_size == 0) {
- printf("Empty file: %s.\n", fp_file);
+ osfp_log_error("Empty file: '%s'.\n", fp_file);
goto exit;
}
file_len = (unsigned int)st.st_size;
file_buffer = malloc(file_len + 1);
if (file_buffer == NULL) {
- printf("Not enough memory for file buffer. file name: %s\n",fp_file);
+ osfp_log_error("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);
+ osfp_log_error("Cannot open '%s' for reading.\n", fp_file);
goto exit;
}
ret = fread(file_buffer, 1, file_len, fp);
if (ret < 0) {
+ osfp_log_error("fread() failed on '%s'.\n", fp_file);
free(file_buffer);
fclose(fp);
goto exit;
@@ -318,14 +320,14 @@ int osfp_score_db_load_entry(struct osfp_score_db *score_db, cJSON *entry)
field = cJSON_GetObjectItem(entry, osfp_fingerprint_get_field_name(i));
if (field == NULL) {
- printf("json entry missing field: %s\n%s\n",
+ osfp_log_info("json entry missing field: %s\n%s\n",
osfp_fingerprint_get_field_name(i), cJSON_Print(entry));
continue;
}
ret = osfp_score_db_load_field(db, field, os_class);
if (ret != 0) {
- printf("json entry field load failed. field: %s\n%s\n",
+ osfp_log_info("json entry field load failed. field: %s\n%s\n",
osfp_fingerprint_get_field_name(i), cJSON_Print(entry));
continue;
}
@@ -353,12 +355,14 @@ int osfp_score_db_load(struct osfp_score_db *score_db, char *fp_file)
file_buffer = osfp_score_db_read_file(fp_file);
if (file_buffer == NULL) {
+ osfp_log_error("read file: '%s'\n", fp_file);
ret = OSFP_ERR_SCORE_DB_READ_FILE;
goto exit;
}
root = cJSON_Parse(file_buffer);
if (root == NULL) {
+ osfp_log_error("parse json: '%s'\n", fp_file);
ret = OSFP_ERR_SCORE_DB_PARSE_FILE;
goto exit;
}
@@ -378,11 +382,13 @@ int osfp_score_db_load(struct osfp_score_db *score_db, char *fp_file)
for (i = 0; i < OSFP_FIELD_MAX; i++) {
field_score_db = &score_db->field_score_dbs[i];
- if (field_score_db->enabled) {
+ if (field_score_db->enabled && i != OSFP_FIELD_TCP_OPTIONS) {
score_db->perfect_score += osfp_fingerprint_get_field_importance(i);
}
}
+ score_db->perfect_score = score_db->perfect_score * PERFECT_SCORE_EXPECTED_RATE;
+
ret = OSFP_NOERR;
exit:
if (root) {
@@ -441,18 +447,15 @@ int osfp_score_db_score(struct osfp_score_db *score_db, unsigned int flags, stru
for (j = 0; j < OSFP_OS_CLASS_MAX; j++) {
entry_count = score_db->os_class_entry_count[j];
tmp_score = os_class_score_matched->scores[j];
+ tmp_score = tmp_score < (entry_count * FIELD_VALUE_DUP_RATE_MAX) ? tmp_score : (entry_count * FIELD_VALUE_DUP_RATE_MAX);
if (entry_count == 0 || tmp_score == 0) {
continue;
}
if (0 == flags || flags & OSFP_BIT_U32(j)) {
- printf("%s %s: ((%d * %u / %u) * %u ) / %u\n", osfp_fingerprint_get_field_name(i), osfp_os_class_id_to_name(j), OSFP_PERCENTILE, importance, perfect_score, os_class_score_matched->scores[j], entry_count);
- result_score->scores[j] += ((OSFP_PERCENTILE * importance / perfect_score) * os_class_score_matched->scores[j]) / entry_count;
+ osfp_log_debug("%s %s: ((%d * %u / %u) * %u ) / %u\n", osfp_fingerprint_get_field_name(i), osfp_os_class_id_to_name(j), OSFP_PERCENTILE, importance, perfect_score, os_class_score_matched->scores[j], entry_count);
+ result_score->scores[j] += ((OSFP_PERCENTILE * importance / perfect_score) * tmp_score) / entry_count;
}
}
-
- if (i == OSFP_FIELD_TCP_OPTIONS) {
- i++;
- }
}
return OSFP_NOERR;
@@ -499,7 +502,7 @@ struct osfp_score_db *osfp_score_db_create(void)
db->enabled = osfp_fingerprint_get_field_enabled(i);
if (!db->enabled) {
- osfp_log_warning("field disabled: %s", "");
+ osfp_log_info("fingerprint field disabled: %s", osfp_fingerprint_get_field_name(i));
continue;
}
@@ -518,13 +521,13 @@ struct osfp_score_db *osfp_score_db_create(void)
db->match = osfp_score_db_hash_match;
break;
default:
- osfp_log_debug("unsupported type: %u", db->type);
+ osfp_log_debug("fingerprint field unsupported type: %u", db->type);
goto exit;
}
db->data = db->create();
if (db->data == NULL) {
- osfp_log_debug("create failed. field: %s", osfp_fingerprint_get_field_name(i));
+ osfp_log_debug("field db create failed. field: %s", osfp_fingerprint_get_field_name(i));
goto exit;
}
}
@@ -545,8 +548,10 @@ void osfp_score_db_destroy(struct osfp_score_db *score_db)
if (score_db) {
for (i = 0; i < OSFP_FIELD_MAX; i++) {
db = &score_db->field_score_dbs[i];
- db->destroy(db->data);
- db->data = NULL;
+ if (db->destroy && db->data) {
+ db->destroy(db->data);
+ db->data = NULL;
+ }
}
free(score_db);
}
diff --git a/src/osfp_score_db.h b/src/osfp_score_db.h
index 68b7896..cd72467 100644
--- a/src/osfp_score_db.h
+++ b/src/osfp_score_db.h
@@ -4,6 +4,10 @@
#include "osfp.h"
#include "osfp_fingerprint.h"
+struct osfp_os_class_score {
+ unsigned int scores[OSFP_OS_CLASS_MAX];
+};
+
struct osfp_field_score_db {
unsigned int enabled;
unsigned int type;