summaryrefslogtreecommitdiff
path: root/src/libosfp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libosfp.c')
-rw-r--r--src/libosfp.c205
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);
+ }
}