code: clean up
This commit is contained in:
@@ -31,8 +31,11 @@ elseif(ENABLE_SANITIZE_THREAD)
|
|||||||
endif()
|
endif()
|
||||||
# end of for ASAN
|
# end of for ASAN
|
||||||
|
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/third_party/cJSON/)
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/third_party/uthash/)
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/src/)
|
include_directories(${PROJECT_SOURCE_DIR}/src/)
|
||||||
|
|
||||||
|
aux_source_directory(${PROJECT_SOURCE_DIR}/third_party/cJSON/ SRCLIST)
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRCLIST)
|
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRCLIST)
|
||||||
|
|
||||||
# Shared Library Output
|
# Shared Library Output
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ void process_packet(char *user, struct pcap_pkthdr *h, u_char *pkt)
|
|||||||
|
|
||||||
// tcp/ip header detect example for user
|
// tcp/ip header detect example for user
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 1; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
example_detect(osfp_db, p);
|
example_detect(osfp_db, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
|
|
||||||
char iph[] = {
|
char iph[] = {
|
||||||
|
|||||||
171
src/osfp.c
171
src/osfp.c
@@ -1,3 +1,7 @@
|
|||||||
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
|
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
@@ -5,67 +9,6 @@
|
|||||||
#include "osfp_score_db.h"
|
#include "osfp_score_db.h"
|
||||||
#include "osfp_log.h"
|
#include "osfp_log.h"
|
||||||
|
|
||||||
#define OSFP_LOWEST_SCORE_LIMIT 20
|
|
||||||
|
|
||||||
static struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_class_score, const char *matched)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned int tmp_score;
|
|
||||||
unsigned int likely_score;
|
|
||||||
enum osfp_os_class_id likely_os_class;
|
|
||||||
struct osfp_result *result;
|
|
||||||
|
|
||||||
result = calloc(1, sizeof(struct osfp_result));
|
|
||||||
if (result == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
likely_score = 0;
|
|
||||||
likely_os_class = OSFP_OS_CLASS_OTHERS;
|
|
||||||
|
|
||||||
// likely os score
|
|
||||||
for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
|
|
||||||
tmp_score = os_class_score->scores[i];
|
|
||||||
|
|
||||||
if (likely_score < tmp_score) {
|
|
||||||
likely_score = tmp_score;
|
|
||||||
likely_os_class = i;
|
|
||||||
}
|
|
||||||
result->details[i].score = tmp_score;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likely_score == OSFP_PERCENTILE) {
|
|
||||||
// prefiltered
|
|
||||||
;
|
|
||||||
} else if (likely_score < OSFP_LOWEST_SCORE_LIMIT) {
|
|
||||||
// too low to tell os class
|
|
||||||
likely_os_class = OSFP_OS_CLASS_OTHERS;
|
|
||||||
} else {
|
|
||||||
// when the tied likely scores appear between win/apple-like/unix-like, we throw unknown
|
|
||||||
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 && i == OSFP_OS_CLASS_ANDROID) {
|
|
||||||
continue;
|
|
||||||
} else if (likely_os_class == OSFP_OS_CLASS_MAC_OS && i == OSFP_OS_CLASS_IOS) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
likely_os_class = OSFP_OS_CLASS_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result->likely_os_class = likely_os_class;
|
|
||||||
result->matched = matched;
|
|
||||||
return result;
|
|
||||||
exit:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *osfp_result_os_name_get(struct osfp_result *result)
|
const char *osfp_result_os_name_get(struct osfp_result *result)
|
||||||
{
|
{
|
||||||
enum osfp_os_class_id os_class;
|
enum osfp_os_class_id os_class;
|
||||||
@@ -157,7 +100,7 @@ void osfp_result_free(struct osfp_result *result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct osfp_result *osfp_ipv4_identify(struct osfp_db *db, struct iphdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len)
|
struct osfp_result *osfp_ip_identify(struct osfp_db *db, unsigned char *l3_hdr, unsigned char *l4_hdr, unsigned int l4_hdr_len, unsigned int ip_version)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct osfp_fingerprint fp;
|
struct osfp_fingerprint fp;
|
||||||
@@ -165,39 +108,24 @@ struct osfp_result *osfp_ipv4_identify(struct osfp_db *db, struct iphdr* l3_hdr,
|
|||||||
struct osfp_result *result;
|
struct osfp_result *result;
|
||||||
const char *matched;
|
const char *matched;
|
||||||
|
|
||||||
osfp_profile_cycle(c1);
|
|
||||||
osfp_profile_cycle(c2);
|
|
||||||
|
|
||||||
if (db == NULL || l3_hdr == NULL || l4_hdr == NULL || l4_hdr_len == 0) {
|
if (db == NULL || l3_hdr == NULL || l4_hdr == NULL || l4_hdr_len == 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
ret = osfp_fingerprinting(l3_hdr, l4_hdr, l4_hdr_len, &fp, ip_version);
|
||||||
ret = osfp_fingerprinting((unsigned char *)l3_hdr, (unsigned char *)l4_hdr, (unsigned int)l4_hdr_len, &fp, 4);
|
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_fingerprinting, c2 - c1);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
matched = osfp_score_db_prefilter(db->score_db, &fp, &os_class_score);
|
matched = osfp_score_db_prefilter(db->score_db, &fp, &os_class_score);
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_prefilter, c2 - c1);
|
|
||||||
if (matched == NULL) {
|
if (matched == NULL) {
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
ret = osfp_score_db_score(db->score_db, 0, &fp, &os_class_score);
|
ret = osfp_score_db_score(db->score_db, 0, &fp, &os_class_score);
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_score, c2 - c1);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
result = osfp_result_build(&os_class_score, matched);
|
result = osfp_result_build(&os_class_score, matched);
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_result_build, c2 - c1);
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@@ -207,89 +135,14 @@ exit:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct osfp_result *osfp_ipv4_identify(struct osfp_db *db, struct iphdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len)
|
||||||
|
{
|
||||||
|
return osfp_ip_identify(db, (unsigned char *)l3_hdr, (unsigned char *)l4_hdr, (unsigned int)l4_hdr_len, 4);
|
||||||
|
}
|
||||||
|
|
||||||
struct osfp_result *osfp_ipv6_identify(struct osfp_db *db, struct ip6_hdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len)
|
struct osfp_result *osfp_ipv6_identify(struct osfp_db *db, struct ip6_hdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len)
|
||||||
{
|
{
|
||||||
int ret;
|
return osfp_ip_identify(db, (unsigned char *)l3_hdr, (unsigned char *)l4_hdr, (unsigned int)l4_hdr_len, 6);
|
||||||
struct osfp_fingerprint fp;
|
|
||||||
struct osfp_os_class_score os_class_score;
|
|
||||||
struct osfp_result *result;
|
|
||||||
const char *matched;
|
|
||||||
|
|
||||||
osfp_profile_cycle(c1);
|
|
||||||
osfp_profile_cycle(c2);
|
|
||||||
|
|
||||||
if (db == NULL || l3_hdr == NULL || l4_hdr == NULL || l4_hdr_len == 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
ret = osfp_fingerprinting((unsigned char *)l3_hdr, (unsigned char *)l4_hdr, (unsigned int)l4_hdr_len, &fp, 6);
|
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_fingerprinting, c2 - c1);
|
|
||||||
if (ret != 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
matched = osfp_score_db_prefilter(db->score_db, &fp, &os_class_score);
|
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_prefilter, c2 - c1);
|
|
||||||
if (matched == NULL) {
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
ret = osfp_score_db_score(db->score_db, 0, &fp, &os_class_score);
|
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_score, c2 - c1);
|
|
||||||
if (ret != 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
osfp_profile_get_cycle(c1);
|
|
||||||
result = osfp_result_build(&os_class_score, matched);
|
|
||||||
osfp_profile_get_cycle(c2);
|
|
||||||
osfp_profile_counter_update(&osfp_profile_result_build, c2 - c1);
|
|
||||||
if (result == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
exit:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct osfp_result *osfp_json_identify(struct osfp_db *db, const char *json_str)
|
|
||||||
{
|
|
||||||
int ret = OSFP_EINVAL;
|
|
||||||
struct osfp_fingerprint fp;
|
|
||||||
struct osfp_os_class_score os_class_score;
|
|
||||||
struct osfp_result *result;
|
|
||||||
const char *matched;
|
|
||||||
|
|
||||||
if (db == NULL || json_str == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = osfp_fingerprint_from_json(&fp, (char *)json_str);
|
|
||||||
if (ret != 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
matched = osfp_score_db_prefilter(db->score_db, &fp, &os_class_score);
|
|
||||||
if (matched == NULL) {
|
|
||||||
ret = osfp_score_db_score(db->score_db, 0, &fp, &os_class_score);
|
|
||||||
if (ret != 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = osfp_result_build(&os_class_score, matched);
|
|
||||||
if (result == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
exit:
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct osfp_db *osfp_db_new(const char *fp_path)
|
struct osfp_db *osfp_db_new(const char *fp_path)
|
||||||
|
|||||||
21
src/osfp.h
21
src/osfp.h
@@ -32,6 +32,18 @@ struct osfp_db *osfp_db_new(const char *db_json_path);
|
|||||||
*/
|
*/
|
||||||
void osfp_db_free(struct osfp_db *db);
|
void osfp_db_free(struct osfp_db *db);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 通过 IP 头部和 TCP 头部识别操作系统。
|
||||||
|
*
|
||||||
|
* @param db 操作系统指纹库。
|
||||||
|
* @param l3_hdr 指向 IP 头部的指针。
|
||||||
|
* @param l4_hdr 指向 TCP 头部的指针。
|
||||||
|
* @param l4_hdr_len TCP 头部的长度(注意:包含TCP选项部分)。
|
||||||
|
* @param ip_version IP头版本号,4 或 6)。
|
||||||
|
* @return 指向操作系统识别结果的指针。
|
||||||
|
*/
|
||||||
|
struct osfp_result *osfp_ip_identify(struct osfp_db *db, unsigned char *l3_hdr, unsigned char *l4_hdr, unsigned int l4_hdr_len, unsigned int ip_version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 通过 IPv4 头部和 TCP 头部识别操作系统。
|
* @brief 通过 IPv4 头部和 TCP 头部识别操作系统。
|
||||||
*
|
*
|
||||||
@@ -54,15 +66,6 @@ struct osfp_result *osfp_ipv4_identify(struct osfp_db *db, struct iphdr* l3_hdr,
|
|||||||
*/
|
*/
|
||||||
struct osfp_result *osfp_ipv6_identify(struct osfp_db *db, struct ip6_hdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len);
|
struct osfp_result *osfp_ipv6_identify(struct osfp_db *db, struct ip6_hdr* l3_hdr, struct tcphdr *l4_hdr, size_t l4_hdr_len);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 通过 json 格式的指纹识别操作系统。
|
|
||||||
*
|
|
||||||
* @param db 操作系统指纹库。
|
|
||||||
* @param json_str 指纹字符串。
|
|
||||||
* @return 指向操作系统识别结果的指针(注意:内存需要使用者释放)。
|
|
||||||
*/
|
|
||||||
struct osfp_result *osfp_json_identify(struct osfp_db *db, const char *json_str);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取操作系统识别结果的操作系统名称。
|
* @brief 获取操作系统识别结果的操作系统名称。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
|
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
@@ -41,6 +47,70 @@ enum osfp_os_class_id osfp_os_class_name_to_id(char *name)
|
|||||||
return OSFP_OS_CLASS_MAX;
|
return OSFP_OS_CLASS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_class_score, const char *matched)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int tmp_score;
|
||||||
|
unsigned int likely_score;
|
||||||
|
enum osfp_os_class_id likely_os_class;
|
||||||
|
struct osfp_result *result;
|
||||||
|
|
||||||
|
result = calloc(1, sizeof(struct osfp_result));
|
||||||
|
if (result == NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
likely_score = 0;
|
||||||
|
likely_os_class = OSFP_OS_CLASS_OTHERS;
|
||||||
|
|
||||||
|
// likely os score
|
||||||
|
for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
|
||||||
|
tmp_score = os_class_score->scores[i];
|
||||||
|
|
||||||
|
if (likely_score < tmp_score) {
|
||||||
|
likely_score = tmp_score;
|
||||||
|
likely_os_class = i;
|
||||||
|
}
|
||||||
|
result->details[i].score = tmp_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prefiltered
|
||||||
|
if (likely_score == OSFP_PERCENTILE) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// too low to tell os class
|
||||||
|
if (likely_score < OSFP_LOWEST_SCORE_LIMIT) {
|
||||||
|
likely_os_class = OSFP_OS_CLASS_OTHERS;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the tied likely scores appear between win/apple-like/unix-like, we throw unknown
|
||||||
|
for (i = 0; i < OSFP_OS_CLASS_MAX; i++) {
|
||||||
|
if (likely_os_class == i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (likely_score != os_class_score->scores[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (likely_os_class == OSFP_OS_CLASS_LINUX && i == OSFP_OS_CLASS_ANDROID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (likely_os_class == OSFP_OS_CLASS_MAC_OS && i == OSFP_OS_CLASS_IOS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
likely_os_class = OSFP_OS_CLASS_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
result->likely_os_class = likely_os_class;
|
||||||
|
result->matched = matched;
|
||||||
|
return result;
|
||||||
|
exit:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void osfp_profile_counter_print(struct osfp_profile_counter *profile, const char *name)
|
void osfp_profile_counter_print(struct osfp_profile_counter *profile, const char *name)
|
||||||
{
|
{
|
||||||
printf("profile %s: avg: %lu max: %lu min: %lu curr: %lu total: %lu count: %lu\n",
|
printf("profile %s: avg: %lu max: %lu min: %lu curr: %lu total: %lu count: %lu\n",
|
||||||
|
|||||||
@@ -1,27 +1,6 @@
|
|||||||
#ifndef __OSFP_COMMON_H__
|
#ifndef __OSFP_COMMON_H__
|
||||||
#define __OSFP_COMMON_H__
|
#define __OSFP_COMMON_H__
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include "utarray.h"
|
|
||||||
#include "uthash.h"
|
|
||||||
#include "utlist.h"
|
|
||||||
#include "utringbuffer.h"
|
|
||||||
#include "utstack.h"
|
|
||||||
#include "utstring.h"
|
|
||||||
|
|
||||||
#include "cJSON.h"
|
|
||||||
|
|
||||||
static inline unsigned long long osfp_rdtsc(void)
|
static inline unsigned long long osfp_rdtsc(void)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
@@ -157,6 +136,7 @@ enum osfp_os_class_id {
|
|||||||
#define OSFP_OS_CLASS_FLAG_IOS OSFP_BIT_U32(OSFP_OS_CLASS_IOS)
|
#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_OS_CLASS_FLAG_ANDROID OSFP_BIT_U32(OSFP_OS_CLASS_ANDROID)
|
||||||
|
|
||||||
|
#define OSFP_LOWEST_SCORE_LIMIT 20
|
||||||
|
|
||||||
enum osfp_error_code {
|
enum osfp_error_code {
|
||||||
OSFP_NOERR,
|
OSFP_NOERR,
|
||||||
@@ -169,6 +149,9 @@ enum osfp_error_code {
|
|||||||
OSFP_ERR_FINGERPRINTING_UNSUPPORTED,
|
OSFP_ERR_FINGERPRINTING_UNSUPPORTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct osfp_os_class_score {
|
||||||
|
unsigned int scores[OSFP_OS_CLASS_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 结构体用于 osfp_result 中的详细结果。
|
* @brief 结构体用于 osfp_result 中的详细结果。
|
||||||
@@ -197,6 +180,7 @@ struct osfp_db {
|
|||||||
|
|
||||||
enum osfp_os_class_id osfp_os_class_name_to_id(char *name);
|
enum osfp_os_class_id osfp_os_class_name_to_id(char *name);
|
||||||
const char *osfp_os_class_id_to_name(enum osfp_os_class_id os_class);
|
const char *osfp_os_class_id_to_name(enum osfp_os_class_id os_class);
|
||||||
|
struct osfp_result *osfp_result_build(struct osfp_os_class_score *os_class_score, const char *matched);
|
||||||
char *osfp_read_file(char *fp_file);
|
char *osfp_read_file(char *fp_file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
|
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
@@ -221,14 +227,17 @@ int osfp_fingerprint_to_json_buf(struct osfp_fingerprint *fp, char *strbuf, unsi
|
|||||||
return strlen(strbuf) + 1;
|
return strlen(strbuf) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct osfp_fingerprint *osfp_fingerprint_from_cjson(cJSON *root)
|
struct osfp_fingerprint *osfp_fingerprint_from_cjson(void *cjson_obj)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
cJSON *root;
|
||||||
cJSON *field;
|
cJSON *field;
|
||||||
void *value_ptr;
|
void *value_ptr;
|
||||||
unsigned int value_len;
|
unsigned int value_len;
|
||||||
struct osfp_fingerprint *fp;
|
struct osfp_fingerprint *fp;
|
||||||
|
|
||||||
|
root = (cJSON *)cjson_obj;
|
||||||
|
|
||||||
if (root == NULL) {
|
if (root == NULL) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static inline unsigned int osfp_fingerprint_get_field_type(enum osfp_field_id fi
|
|||||||
return fp_fields[field_id].type;
|
return fp_fields[field_id].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct osfp_fingerprint *osfp_fingerprint_from_cjson(cJSON *root);
|
struct osfp_fingerprint *osfp_fingerprint_from_cjson(void *root);
|
||||||
int osfp_fingerprint_from_json(struct osfp_fingerprint *fp, char *json_str);
|
int osfp_fingerprint_from_json(struct osfp_fingerprint *fp, char *json_str);
|
||||||
int osfp_fingerprint_to_json_buf(struct osfp_fingerprint *fp, char *strbuf, unsigned int buf_len, unsigned int format);
|
int osfp_fingerprint_to_json_buf(struct osfp_fingerprint *fp, char *strbuf, unsigned int buf_len, unsigned int format);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
#include "osfp_log.h"
|
#include "osfp_log.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
|
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
@@ -301,7 +306,7 @@ int osfp_score_db_score(struct osfp_score_db *score_db, unsigned int flags, stru
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
coefficient = OSFP_PERCENTILE / PERFECT_SCORE_EXPECTED_RATE * score_db->field_weight[i] / total_weight;
|
coefficient = fdb->coefficient;
|
||||||
|
|
||||||
for (j = 0; j < OSFP_OS_CLASS_MAX; j++) {
|
for (j = 0; j < OSFP_OS_CLASS_MAX; j++) {
|
||||||
os_entry_count = score_db->os_entry_count[j];
|
os_entry_count = score_db->os_entry_count[j];
|
||||||
@@ -510,10 +515,10 @@ struct osfp_score_db *osfp_score_db_create(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
score_db->field_weight[i] = osfp_fingerprint_get_field_importance(i);
|
db->weight = osfp_fingerprint_get_field_importance(i);
|
||||||
// tcp options ordered and tcp options overlap
|
// tcp options ordered and tcp options overlap
|
||||||
if (i != OSFP_FIELD_TCP_OPTIONS_ORDERED) {
|
if (i != OSFP_FIELD_TCP_OPTIONS_ORDERED) {
|
||||||
score_db->total_weight += score_db->field_weight[i];
|
score_db->total_weight += db->weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
db->type = osfp_fingerprint_get_field_type(i);
|
db->type = osfp_fingerprint_get_field_type(i);
|
||||||
@@ -542,6 +547,11 @@ struct osfp_score_db *osfp_score_db_create(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < OSFP_FIELD_MAX; i++) {
|
||||||
|
db = &score_db->field_score_dbs[i];
|
||||||
|
db->coefficient = (OSFP_PERCENTILE / PERFECT_SCORE_EXPECTED_RATE) * ((float)db->weight / (float)score_db->total_weight);
|
||||||
|
}
|
||||||
|
|
||||||
return score_db;
|
return score_db;
|
||||||
exit:
|
exit:
|
||||||
if (score_db) {
|
if (score_db) {
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
#ifndef __OSFP_SCORE_DB_H__
|
#ifndef __OSFP_SCORE_DB_H__
|
||||||
#define __OSFP_SCORE_DB_H__
|
#define __OSFP_SCORE_DB_H__
|
||||||
|
|
||||||
|
#include "uthash.h"
|
||||||
|
|
||||||
#include "osfp.h"
|
#include "osfp.h"
|
||||||
#include "osfp_fingerprint.h"
|
#include "osfp_fingerprint.h"
|
||||||
#include "osfp_common.h"
|
#include "osfp_common.h"
|
||||||
|
|
||||||
struct osfp_os_class_score {
|
|
||||||
unsigned int scores[OSFP_OS_CLASS_MAX];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct osfp_field_value_count {
|
struct osfp_field_value_count {
|
||||||
unsigned int counts[OSFP_OS_CLASS_MAX];
|
unsigned int counts[OSFP_OS_CLASS_MAX];
|
||||||
};
|
};
|
||||||
@@ -18,6 +16,9 @@ struct osfp_field_score_db {
|
|||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int entry_count;
|
unsigned int entry_count;
|
||||||
|
|
||||||
|
unsigned int weight;
|
||||||
|
float coefficient;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
void *(*create)(void);
|
void *(*create)(void);
|
||||||
@@ -43,7 +44,6 @@ struct osfp_score_db {
|
|||||||
unsigned int os_entry_count[OSFP_OS_CLASS_MAX];
|
unsigned int os_entry_count[OSFP_OS_CLASS_MAX];
|
||||||
|
|
||||||
unsigned int total_weight;
|
unsigned int total_weight;
|
||||||
unsigned int field_weight[OSFP_FIELD_MAX];
|
|
||||||
|
|
||||||
struct osfp_field_score_db field_score_dbs[OSFP_FIELD_MAX];
|
struct osfp_field_score_db field_score_dbs[OSFP_FIELD_MAX];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
{
|
{
|
||||||
global: osfp*;GIT_VERSION_*;
|
global:
|
||||||
|
osfp_db_new;
|
||||||
|
osfp_db_free;
|
||||||
|
osfp_ip_identify;
|
||||||
|
osfp_ipv4_identify;
|
||||||
|
osfp_ipv6_identify;
|
||||||
|
osfp_result_os_name_get;
|
||||||
|
osfp_result_score_detail_export;
|
||||||
|
osfp_result_free;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|||||||
37
test/test.c
37
test/test.c
@@ -3,6 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
|
||||||
@@ -126,6 +127,40 @@ static void print_confusion_matrix(unsigned int *result, unsigned int os_class_m
|
|||||||
printf("miss rate: %u%%\n", 100 * missed / (matched + missed));
|
printf("miss rate: %u%%\n", 100 * missed / (matched + missed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct osfp_result *test_osfp_json_identify(struct osfp_db *db, const char *json_str)
|
||||||
|
{
|
||||||
|
int ret = OSFP_EINVAL;
|
||||||
|
struct osfp_fingerprint fp;
|
||||||
|
struct osfp_os_class_score os_class_score;
|
||||||
|
struct osfp_result *result;
|
||||||
|
const char *matched;
|
||||||
|
|
||||||
|
if (db == NULL || json_str == NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = osfp_fingerprint_from_json(&fp, (char *)json_str);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
matched = osfp_score_db_prefilter(db->score_db, &fp, &os_class_score);
|
||||||
|
if (matched == NULL) {
|
||||||
|
ret = osfp_score_db_score(db->score_db, 0, &fp, &os_class_score);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = osfp_result_build(&os_class_score, matched);
|
||||||
|
if (result == NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
exit:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void test_data_prepare()
|
void test_data_prepare()
|
||||||
{
|
{
|
||||||
@@ -229,7 +264,7 @@ void test_miss_rate()
|
|||||||
osfp_fingerprint_to_json_buf(&fp, str_buf, 2048, 0);
|
osfp_fingerprint_to_json_buf(&fp, str_buf, 2048, 0);
|
||||||
fprintf(log_file_ptr, "%s\n", str_buf);
|
fprintf(log_file_ptr, "%s\n", str_buf);
|
||||||
|
|
||||||
struct osfp_result *result = osfp_json_identify(osfp_db, fp_str);
|
struct osfp_result *result = test_osfp_json_identify(osfp_db, fp_str);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
identify_failed_count++;
|
identify_failed_count++;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
0
src/cJSON.c → third_party/cJSON/cJSON.c
vendored
0
src/cJSON.c → third_party/cJSON/cJSON.c
vendored
0
src/cJSON.h → third_party/cJSON/cJSON.h
vendored
0
src/cJSON.h → third_party/cJSON/cJSON.h
vendored
Reference in New Issue
Block a user