diff options
Diffstat (limited to 'src/libosfp.c')
| -rw-r--r-- | src/libosfp.c | 205 |
1 files changed, 203 insertions, 2 deletions
diff --git a/src/libosfp.c b/src/libosfp.c index beb5c86..82a5834 100644 --- a/src/libosfp.c +++ b/src/libosfp.c @@ -1,6 +1,207 @@ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <malloc.h> + +#include <linux/in.h> +#include <linux/if_ether.h> +#include <linux/ip.h> +#include <linux/ipv6.h> +#include <linux/tcp.h> + #include "libosfp.h" +#include "libosfp_fingerprint.h" +#include "libosfp_score_db.h" +#include "libosfp_log.h" + +#define LIBOSFP_OS_CLASS_NAME_WINDOWS "Windows" +#define LIBOSFP_OS_CLASS_NAME_LINUX "Linux" +#define LIBOSFP_OS_CLASS_NAME_MAC_OS "Mac OS" +#define LIBOSFP_OS_CLASS_NAME_IOS "iOS" +#define LIBOSFP_OS_CLASS_NAME_ANDROID "Android" + +#define LIBOSFP_WRITE_STRING_TO_BUF(ret, buf, size, off, ...) do { \ + ret = snprintf((char *)buf + off, \ + size - off, \ + __VA_ARGS__); \ + if (ret >= 0) { \ + if ( (off + ret) >= size) { \ + off = size - 1; \ + } else { \ + off += ret; \ + } \ + } \ + } while (0) + + +const char *os_class_name[LIBOSFP_OS_CLASS_MAX] = { + LIBOSFP_OS_CLASS_NAME_WINDOWS, + LIBOSFP_OS_CLASS_NAME_LINUX, + LIBOSFP_OS_CLASS_NAME_MAC_OS, + LIBOSFP_OS_CLASS_NAME_IOS, + LIBOSFP_OS_CLASS_NAME_ANDROID +}; + +libosfp_os_class_id_t libosfp_os_class_name_to_id(char *name) +{ + libosfp_os_class_id_t os_class; + + if (0 == strncmp(name, LIBOSFP_OS_CLASS_NAME_WINDOWS, strlen(LIBOSFP_OS_CLASS_NAME_WINDOWS))) { + os_class = LIBOSFP_OS_CLASS_WINDOWS; + } else if (0 == strncmp(name, LIBOSFP_OS_CLASS_NAME_LINUX, strlen(LIBOSFP_OS_CLASS_NAME_LINUX))) { + os_class = LIBOSFP_OS_CLASS_Linux; + } else if (0 == strncmp(name, LIBOSFP_OS_CLASS_NAME_MAC_OS, strlen(LIBOSFP_OS_CLASS_NAME_MAC_OS))) { + os_class = LIBOSFP_OS_CLASS_MAC_OS; + } else if (0 == strncmp(name, LIBOSFP_OS_CLASS_NAME_IOS, strlen(LIBOSFP_OS_CLASS_NAME_IOS))) { + os_class = LIBOSFP_OS_CLASS_IOS; + } else if (0 == strncmp(name, LIBOSFP_OS_CLASS_NAME_ANDROID, strlen(LIBOSFP_OS_CLASS_NAME_ANDROID))) { + os_class = LIBOSFP_OS_CLASS_ANDROID; + } else { + os_class = LIBOSFP_OS_CLASS_MAX; + } + + return os_class; +} + +const char *libosfp_os_class_id_to_name(libosfp_os_class_id_t os_class) +{ + if (os_class < 0 || os_class >= LIBOSFP_OS_CLASS_MAX) { + return NULL; + } + + return os_class_name[os_class]; +} + +const char *libosfp_result_likely_os_class_name_get(libosfp_result_t *result) +{ + libosfp_os_class_id_t os_class; + + if (result == NULL) { + return NULL; + } + + os_class = result->likely_os_class; + if (os_class < 0 || os_class >= LIBOSFP_OS_CLASS_MAX) { + return NULL; + } + + return os_class_name[os_class]; +} + +unsigned int libosfp_result_likely_os_class_score_get(libosfp_result_t *result) +{ + if (result == NULL) { + return 0; + } + + return result->likely_score; +} + +int libosfp_result_to_buf(libosfp_result_t *result, char *strbuf, unsigned int buf_len) +{ + int ret, offset = 0, i; + + if (result == NULL || strbuf == NULL || buf_len == 0) { + return 0; + } + + LIBOSFP_WRITE_STRING_TO_BUF(ret, strbuf, buf_len, offset, + "Most likely os class: %s\nLikely score: %u/100\n", + os_class_name[result->likely_os_class], result->likely_score); + + LIBOSFP_WRITE_STRING_TO_BUF(ret, strbuf, buf_len, offset,"Details:\n"); + + for (i = 0; i < LIBOSFP_OS_CLASS_MAX; i++) { + LIBOSFP_WRITE_STRING_TO_BUF(ret, strbuf, buf_len, offset,"%s score: %u\n", + os_class_name[i], result->score.os_class_score[i]); + } + +exit: + return offset; +} + +libosfp_error_code_t libosfp_header_match(libosfp_context_t *libosfp_context, unsigned char *ip_hdr, unsigned char *tcp_hdr, libosfp_result_t *result) +{ + int ret = LIBOSFP_EINVAL; + libosfp_fingerprint_t fp = {0}; + + if (libosfp_context == NULL || ip_hdr == NULL || tcp_hdr == NULL || result == NULL) { + goto exit; + } + + ret = libosfp_fingerprinting(ip_hdr, tcp_hdr, &fp); + if (ret != 0) { + goto exit; + } + + ret = libosfp_score_db_score(libosfp_context, &fp, result); + if (ret != 0) { + goto exit; + } + + return LIBOSFP_NOERR; +exit: + return ret; +} + +libosfp_error_code_t libosfp_context_setup(libosfp_context_t *libosfp_context) +{ + int ret = LIBOSFP_EINVAL; + + if (libosfp_context == NULL) { + goto exit; + } + + ret = libosfp_score_db_load((libosfp_score_db_t *)libosfp_context->score_db, libosfp_context->fp_file); + if (ret != LIBOSFP_NOERR) { + goto exit; + } + + return LIBOSFP_NOERR; +exit: + return ret; +} + +libosfp_context_t *libosfp_context_create(char *fp_file) +{ + libosfp_context_t *libosfp_context = NULL; + + if (fp_file == NULL || 0 != access(fp_file, R_OK)) { + goto exit; + } + + libosfp_context = malloc(sizeof(libosfp_context_t)); + if (libosfp_context == NULL) { + goto exit; + } + + libosfp_context->fp_file = strdup((const char*)fp_file); + if (libosfp_context->fp_file == NULL) { + goto exit; + } + + libosfp_context->score_db = (void *)libosfp_score_db_create(); + if (libosfp_context->score_db == NULL) { + goto exit; + } + + return libosfp_context; +exit: + if (libosfp_context) { + libosfp_context_destroy(libosfp_context); + } + return NULL; +} -int libosfp_init(void) +void libosfp_context_destroy(libosfp_context_t *libosfp_context) { - return 0; + if (libosfp_context) { + if (libosfp_context->fp_file) { + free(libosfp_context->fp_file); + } + if (libosfp_context->score_db) { + libosfp_score_db_destroy(libosfp_context->score_db); + } + free(libosfp_context); + } } |
