diff options
-rwxr-xr-x | autogen.sh | 5 | ||||
-rw-r--r-- | configure.seed (renamed from configure.ac) | 15 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 12 | ||||
-rw-r--r-- | src/include/ndpi_define.h.in (renamed from src/include/ndpi_define.h) | 4 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 2 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 87 | ||||
-rw-r--r-- | src/lib/protocols/fasttrack.c | 4 |
7 files changed, 94 insertions, 35 deletions
diff --git a/autogen.sh b/autogen.sh index 492ef3bf6..0f366966a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,5 +1,9 @@ #!/bin/sh +NDPI_MAJOR="2" +NDPI_MINOR="1" +NDPI_PATCH="0" +NDPI_VERSION_SHORT="$NDPI_MAJOR.$NDPI_MINOR.$NDPI_PATCH" /bin/rm -f configure config.h config.h.in src/lib/Makefile.in @@ -29,5 +33,6 @@ if test -z $AUTORECONF; then exit fi +cat configure.seed | sed "s/@NDPI_MAJOR@/$NDPI_MAJOR/g" | sed "s/@NDPI_MINOR@/$NDPI_MINOR/g" | sed "s/@NDPI_PATCH@/$NDPI_PATCH/g" | sed "s/@NDPI_VERSION_SHORT@/$NDPI_VERSION_SHORT/g" > configure.ac autoreconf -ivf ./configure $* diff --git a/configure.ac b/configure.seed index eec6878f5..2b2392a16 100644 --- a/configure.ac +++ b/configure.seed @@ -1,4 +1,4 @@ -AC_INIT([libndpi], [2.1.0]) +AC_INIT([libndpi], [@NDPI_VERSION_SHORT@]) AC_CONFIG_MACRO_DIR([m4]) @@ -10,6 +10,14 @@ AC_PROG_CC AM_PROG_CC_C_O AX_PTHREAD +NDPI_MAJOR="@NDPI_MAJOR@" +NDPI_MINOR="@NDPI_MINOR@" +NDPI_PATCH="@NDPI_PATCH@" + +AC_DEFINE_UNQUOTED(NDPI_MAJOR_RELEASE, "${NDPI_MAJOR}", [nDPI major release]) +AC_DEFINE_UNQUOTED(NDPI_MINOR_RELEASE, "${NDPI_MINOR}", [nDPI minor release]) +AC_DEFINE_UNQUOTED(NDPI_PATCH_LEVEL, "${NDPI_PATCH}", [nDPI patch level]) + if test -d ".git"; then : GIT_TAG=`git log -1 --format=%h` GIT_DATE=`git log -1 --format=%cd` @@ -92,9 +100,12 @@ AS_IF([test "x$enable_json_c" != "xno"], [ AC_CHECK_LIB(pthread, pthread_setaffinity_np, AC_DEFINE_UNQUOTED(HAVE_PTHREAD_SETAFFINITY_NP, 1, [libc has pthread_setaffinity_np])) -AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile tests/Makefile libndpi.pc]) +AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile tests/Makefile libndpi.pc src/include/ndpi_define.h]) AC_CONFIG_HEADERS(config.h) AC_SUBST(GIT_RELEASE) +AC_SUBST(NDPI_MAJOR) +AC_SUBST(NDPI_MINOR) +AC_SUBST(NDPI_PATCH) AC_SUBST(SVN_DATE) AC_SUBST(JSON_C_LIB) AC_SUBST(PCAP_INC) diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 03a73d66b..76285cb70 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -98,6 +98,18 @@ extern "C" { */ char* ndpi_strnstr(const char *s, const char *find, size_t slen); + /** + * Same as ndpi_strnstr but case insensitive + * + * @par s = string to parse + * @par find = string to match with -s- + * @par slen = max length to match between -s- and -find- + * @return a pointer to the beginning of the located substring; + * NULL if the substring is not found + * + */ + char* ndpi_strncasestr(const char *s, const char *find, size_t slen); + /** * Returns the nDPI protocol id for IP-based protocol detection diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h.in index 4878ff748..5a8a1527b 100644 --- a/src/include/ndpi_define.h +++ b/src/include/ndpi_define.h.in @@ -290,4 +290,8 @@ #define NDPI_MAX_DNS_REQUESTS 16 +#define NDPI_MAJOR @NDPI_MAJOR@ +#define NDPI_MINOR @NDPI_MINOR@ +#define NDPI_PATCH @NDPI_PATCH@ + #endif /* __NDPI_DEFINE_INCLUDE_FILE__ */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index b0efab6af..e5e9053e8 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -961,7 +961,7 @@ struct ndpi_flow_struct { char *url, *content_type; u_int8_t num_request_headers, num_response_headers; u_int8_t request_version; /* 0=1.0 and 1=1.1. Create an enum for this? */ - u_char response_status_code[4]; /* 200, 404, etc. */ + u_char response_status_code[5]; /* 200, 404, etc. */ } http; union { diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 71c1d4c23..ffb4ed909 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3817,7 +3817,7 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */ if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") && - memcmp(packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 && + strncasecmp((const char *)packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 && packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') { @@ -3836,7 +3836,7 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc } /* "Server:" header line in HTTP response */ if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 - && memcmp(packet->line[packet->parsed_lines].ptr, "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) { // some stupid clients omit a space and place the servername directly after the colon if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') { packet->server_line.ptr = @@ -3851,7 +3851,8 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc } /* "Host:" header line in HTTP request */ if(packet->line[packet->parsed_lines].len > 6 - && memcmp(packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, + "Host:", 5) == 0) { // some stupid clients omit a space and place the hostname directly after the colon if(packet->line[packet->parsed_lines].ptr[5] == ' ') { packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6]; @@ -3864,7 +3865,7 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc } /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */ if(packet->line[packet->parsed_lines].len > 17 - && memcmp(packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) { // some stupid clients omit a space and place the hostname directly after the colon if(packet->line[packet->parsed_lines].ptr[16] == ' ') { packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17]; @@ -3877,80 +3878,80 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc } /* "Content-Type:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 14 - && (memcmp(packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 - || memcmp(packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) { + && (strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 + || strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) { packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14]; packet->content_line.len = packet->line[packet->parsed_lines].len - 14; packet->http_num_headers++; } /* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */ if(packet->line[packet->parsed_lines].len > 13 - && memcmp(packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0) { packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13]; packet->content_line.len = packet->line[packet->parsed_lines].len - 13; packet->http_num_headers++; } /* "Accept:" header line in HTTP request. */ if(packet->line[packet->parsed_lines].len > 8 - && memcmp(packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) { packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8]; packet->accept_line.len = packet->line[packet->parsed_lines].len - 8; packet->http_num_headers++; } /* "Referer:" header line in HTTP request. */ if(packet->line[packet->parsed_lines].len > 9 - && memcmp(packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) { packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9]; packet->referer_line.len = packet->line[packet->parsed_lines].len - 9; packet->http_num_headers++; } /* "User-Agent:" header line in HTTP request. */ if(packet->line[packet->parsed_lines].len > 12 - && (memcmp(packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 - || memcmp(packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) { + && (strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 + || strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) { packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12]; packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12; packet->http_num_headers++; } /* "Content-Encoding:" header line in HTTP response (and request?). */ if(packet->line[packet->parsed_lines].len > 18 - && memcmp(packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) { packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18]; packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18; packet->http_num_headers++; } /* "Transfer-Encoding:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 19 - && memcmp(packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) { packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19]; packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19; packet->http_num_headers++; } /* "Content-Length:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 16 - && ((memcmp(packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) - || (memcmp(packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) { + && ((strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) + || (strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) { packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16]; packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16; packet->http_num_headers++; } /* "Cookie:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 8 - && memcmp(packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) { packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8]; packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8; packet->http_num_headers++; } /* "Origin:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 8 - && memcmp(packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) { packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8]; packet->http_origin.len = packet->line[packet->parsed_lines].len - 8; packet->http_num_headers++; } /* "X-Session-Type:" header line in HTTP. */ if(packet->line[packet->parsed_lines].len > 16 - && memcmp(packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) { + && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) { packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16]; packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16; packet->http_num_headers++; @@ -3961,19 +3962,19 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc * - https://tools.ietf.org/html/rfc7230 * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields */ - if((packet->line[packet->parsed_lines].len > 6 && ( memcmp(packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0 )) || - (packet->line[packet->parsed_lines].len > 8 && memcmp(packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) || - (packet->line[packet->parsed_lines].len > 9 && memcmp(packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) || - (packet->line[packet->parsed_lines].len > 12 && ( memcmp(packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) || - (packet->line[packet->parsed_lines].len > 15 && ( memcmp(packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) || - (packet->line[packet->parsed_lines].len > 17 && ( memcmp(packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 || - memcmp(packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) || - (packet->line[packet->parsed_lines].len > 27 && memcmp(packet->line[packet->parsed_lines].ptr, "Upgrade-Insecure-Requests: ", 27) == 0)) { + if((packet->line[packet->parsed_lines].len > 6 && ( strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0 )) || + (packet->line[packet->parsed_lines].len > 8 && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) || + (packet->line[packet->parsed_lines].len > 9 && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) || + (packet->line[packet->parsed_lines].len > 12 && ( strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) || + (packet->line[packet->parsed_lines].len > 15 && ( strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) || + (packet->line[packet->parsed_lines].len > 17 && ( strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 || + strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) || + (packet->line[packet->parsed_lines].len > 27 && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Upgrade-Insecure-Requests: ", 27) == 0)) { /* Just count. In the future, if needed, this if can be splited to parse these headers */ packet->http_num_headers++; } @@ -4715,6 +4716,30 @@ char* ndpi_strnstr(const char *s, const char *find, size_t slen) { /* ****************************************************** */ +/* + * Same as ndpi_strnstr but case-insensitive + */ +char* ndpi_strncasestr(const char *s, const char *find, size_t slen) { + char c, sc; + size_t len; + + if((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if(slen-- < 1 || (sc = *s++) == '\0') + return (NULL); + } while (sc != c); + if(len > slen) + return (NULL); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} + +/* ****************************************************** */ + int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len, const char *str, size_t str_len) { diff --git a/src/lib/protocols/fasttrack.c b/src/lib/protocols/fasttrack.c index cb2f20343..c432f6754 100644 --- a/src/lib/protocols/fasttrack.c +++ b/src/lib/protocols/fasttrack.c @@ -42,7 +42,9 @@ void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; - if (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { + if ( (packet->payload != NULL) + && (packet->payload_packet_len > 6) + && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)) { NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected 0d0a at the end of the packet.\n"); if (memcmp(packet->payload, "GIVE ", 5) == 0 && packet->payload_packet_len >= 8) { |