diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2020-11-17 19:29:10 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2020-11-17 19:29:10 +0100 |
commit | 54dd72676d54b35b821eac6b9dddecd4ba62ee0a (patch) | |
tree | de68090353d2f3911cfc9a4923ed7169d4a2e272 | |
parent | a03e0c8ba8c9230a3890d6fbd813fcf051086e7f (diff) |
Provide functionality do deal with tokens from JSMN.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | dependencies/nDPIsrvd.h | 105 | ||||
-rw-r--r-- | examples/c-captured/c-captured.c | 41 |
2 files changed, 134 insertions, 12 deletions
diff --git a/dependencies/nDPIsrvd.h b/dependencies/nDPIsrvd.h index 4889abfa9..dcadc61ca 100644 --- a/dependencies/nDPIsrvd.h +++ b/dependencies/nDPIsrvd.h @@ -43,6 +43,13 @@ struct nDPIsrvd_socket jsmntok_t tokens[128]; int current_token; int tokens_found; + struct + { + char const * key; + int key_length; + char const * value; + int value_length; + } key_value; } jsmn; }; @@ -155,6 +162,68 @@ static inline enum nDPIsrvd_read_return nDPIsrvd_read(struct nDPIsrvd_socket * c return READ_OK; } +static inline int token_is_key(struct nDPIsrvd_socket const * const sock) +{ + return sock->jsmn.current_token % 2; +} + +static inline char const * token_get(struct nDPIsrvd_socket const * const sock) +{ + return sock->buffer.json_string + sock->jsmn.tokens[sock->jsmn.current_token].start; +} + +static inline int token_size(struct nDPIsrvd_socket const * const sock) +{ + return sock->jsmn.tokens[sock->jsmn.current_token].end - sock->jsmn.tokens[sock->jsmn.current_token].start; +} + +static inline int token_is_start(struct nDPIsrvd_socket const * const sock) +{ + return sock->jsmn.current_token == 0; +} + +static inline int token_is_end(struct nDPIsrvd_socket const * const sock) +{ + return sock->jsmn.current_token == sock->jsmn.tokens_found; +} + +static inline int token_is_key_value_pair(struct nDPIsrvd_socket const * const sock) +{ + return sock->jsmn.current_token > 0 && sock->jsmn.current_token < sock->jsmn.tokens_found; +} + +static inline int token_is_jsmn_type(struct nDPIsrvd_socket const * const sock, jsmntype_t type_to_check) +{ + if (token_is_key_value_pair(sock) == 0) + { + return 0; + } + + return sock->jsmn.tokens[sock->jsmn.current_token].type == type_to_check; +} + +static inline int key_equals(struct nDPIsrvd_socket const * const sock, char const * const name) +{ + if (sock->jsmn.key_value.key == NULL || sock->jsmn.key_value.key_length == 0) + { + return 0; + } + + return (int)strlen(name) == sock->jsmn.key_value.key_length && + strncmp(name, sock->jsmn.key_value.key, sock->jsmn.key_value.key_length) == 0; +} + +static inline int value_equals(struct nDPIsrvd_socket const * const sock, char const * const name) +{ + if (sock->jsmn.key_value.value == NULL || sock->jsmn.key_value.value_length == 0) + { + return 0; + } + + return (int)strlen(name) == sock->jsmn.key_value.value_length && + strncmp(name, sock->jsmn.key_value.value, sock->jsmn.key_value.value_length) == 0; +} + static inline enum nDPIsrvd_parse_return nDPIsrvd_parse(struct nDPIsrvd_socket * const sock, json_callback cb, void * user_data) @@ -204,6 +273,10 @@ static inline enum nDPIsrvd_parse_return nDPIsrvd_parse(struct nDPIsrvd_socket * return PARSE_JSMN_ERROR; } + sock->jsmn.key_value.key = NULL; + sock->jsmn.key_value.key_length = 0; + sock->jsmn.key_value.value = NULL; + sock->jsmn.key_value.value_length = 0; sock->jsmn.current_token = 0; if (cb(sock, user_data) != CALLBACK_OK) { @@ -213,9 +286,34 @@ static inline enum nDPIsrvd_parse_return nDPIsrvd_parse(struct nDPIsrvd_socket * for (sock->jsmn.current_token = 1; sock->jsmn.current_token < sock->jsmn.tokens_found; sock->jsmn.current_token++) { - if (cb(sock, user_data) != CALLBACK_OK) + if (token_is_key(sock) == 1) { - return PARSE_CALLBACK_ERROR; + sock->jsmn.key_value.key = token_get(sock); + sock->jsmn.key_value.key_length = token_size(sock); + + if (sock->jsmn.key_value.key == NULL || sock->jsmn.key_value.value != NULL) + { + return PARSE_JSMN_ERROR; + } + } + else + { + sock->jsmn.key_value.value = token_get(sock); + sock->jsmn.key_value.value_length = token_size(sock); + + if (sock->jsmn.key_value.key == NULL || sock->jsmn.key_value.value == NULL) + { + return PARSE_JSMN_ERROR; + } + if (cb(sock, user_data) != CALLBACK_OK) + { + return PARSE_CALLBACK_ERROR; + } + + sock->jsmn.key_value.key = NULL; + sock->jsmn.key_value.key_length = 0; + sock->jsmn.key_value.value = NULL; + sock->jsmn.key_value.value_length = 0; } } @@ -224,6 +322,9 @@ static inline enum nDPIsrvd_parse_return nDPIsrvd_parse(struct nDPIsrvd_socket * return PARSE_CALLBACK_ERROR; } + sock->jsmn.current_token = -1; + sock->jsmn.tokens_found = 0; + memmove(sock->buffer.raw, sock->buffer.raw + sock->buffer.json_string_length, sock->buffer.used - sock->buffer.json_string_length); diff --git a/examples/c-captured/c-captured.c b/examples/c-captured/c-captured.c index d2ca51c2c..4ddb9e1e7 100644 --- a/examples/c-captured/c-captured.c +++ b/examples/c-captured/c-captured.c @@ -10,6 +10,8 @@ #include "nDPIsrvd.h" #include "jsmn/jsmn.h" +//#define VERBOSE 1 + static char serv_listen_addr[INET_ADDRSTRLEN] = DISTRIBUTOR_HOST; static uint16_t serv_listen_port = DISTRIBUTOR_PORT; @@ -17,26 +19,45 @@ static enum nDPIsrvd_callback_return nDPIsrvd_json_callback(struct nDPIsrvd_sock { (void)user_data; - if (sock->jsmn.current_token == 0) { + if (token_is_start(sock) == 1) + { +#ifdef VERBOSE /* Start of a JSON string. */ printf("JSON "); +#endif } - else if (sock->jsmn.current_token == sock->jsmn.tokens_found) + else if (token_is_end(sock) == 1) { +#ifdef VERBOSE /* End of a JSON string. */ - printf(" EoF\n"); + printf("EoF\n"); +#endif } - else if (sock->jsmn.current_token % 2 == 1) + else if (token_is_key_value_pair(sock) == 1) { - printf("[%.*s : ", - sock->jsmn.tokens[sock->jsmn.current_token].end - sock->jsmn.tokens[sock->jsmn.current_token].start, - sock->buffer.json_string + sock->jsmn.tokens[sock->jsmn.current_token].start); + if (key_equals(sock, "flow_event_name") == 1) + { + if (value_equals(sock, "guessed") == 1) + { + printf("Guessed flow.\n"); + } + else if (value_equals(sock, "not-detected") == 1) + { + printf("Not detected flow.\n"); + } + } +#ifdef VERBOSE + printf("[%.*s : %.*s] ", + sock->jsmn.key_value.key_length, + sock->jsmn.key_value.key, + sock->jsmn.key_value.value_length, + sock->jsmn.key_value.value); +#endif } else { - printf("%.*s] ", - sock->jsmn.tokens[sock->jsmn.current_token].end - sock->jsmn.tokens[sock->jsmn.current_token].start, - sock->buffer.json_string + sock->jsmn.tokens[sock->jsmn.current_token].start); + fprintf(stderr, "%s\n", "Internal error, exit .."); + return CALLBACK_ERROR; } return CALLBACK_OK; |