diff options
Diffstat (limited to 'src/lib/protocols/http.c')
-rw-r--r-- | src/lib/protocols/http.c | 551 |
1 files changed, 166 insertions, 385 deletions
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 09b816129..33ef9e2ed 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -26,116 +26,43 @@ #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HTTP #include "ndpi_api.h" -#include "lruc.h" - -/* global variables used for 1kxun protocol and iqiyi service */ +#include <stdlib.h> static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t category) { - +#ifdef DEBUG + printf("[%s] [http_dont_dissect_response: %u]->> %s\n", __FUNCTION__, + ndpi_struct->http_dont_dissect_response, flow->http.response_status_code); +#endif + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { /* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */ ndpi_search_tcp_or_udp(ndpi_struct, flow); /* If no custom protocol has been detected */ - if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) { ndpi_int_reset_protocol(flow); - ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP); + flow->http_upper_protocol = flow->guessed_host_protocol_id, flow->http_lower_protocol = NDPI_PROTOCOL_HTTP; } else - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN); - - flow->http_detected = 1, flow->guessed_category = category; - } -} - -#ifdef NDPI_CONTENT_CATEGORY_FLASH -static void flash_check_http_payload(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - const u_int8_t *pos; - - if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 10) > (packet->payload_packet_len)) - return; - - pos = &packet->payload[packet->empty_line_position] + 2; - - if(memcmp(pos, "FLV", 3) == 0 && pos[3] == 0x01 && (pos[4] == 0x01 || pos[4] == 0x04 || pos[4] == 0x05) - && pos[5] == 0x00 && pos[6] == 0x00 && pos[7] == 0x00 && pos[8] == 0x09) { - - NDPI_LOG_INFO(ndpi_struct, "found Flash content in HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_CATEGORY_FLASH); - } -} -#endif - -#ifdef NDPI_CONTENT_CATEGORY_AVI -static void avi_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - - - NDPI_LOG_DBG2(ndpi_struct, "called avi_check_http_payload: %u %u %u\n", - packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position); - - if(packet->empty_line_position_set == 0 && flow->l4.tcp.http_empty_line_seen == 0) - return; - - if(packet->empty_line_position_set != 0 && ((packet->empty_line_position + 20) > (packet->payload_packet_len)) - && flow->l4.tcp.http_empty_line_seen == 0) { - flow->l4.tcp.http_empty_line_seen = 1; - return; - } + flow->http_upper_protocol = NDPI_PROTOCOL_HTTP, flow->http_lower_protocol = NDPI_PROTOCOL_UNKNOWN; - if(flow->l4.tcp.http_empty_line_seen == 1) { - if(packet->payload_packet_len > 20 && memcmp(packet->payload, "RIFF", 4) == 0 - && memcmp(packet->payload + 8, "AVI LIST", 8) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found Avi content in HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_CATEGORY_AVI); + if(ndpi_struct->http_dont_dissect_response) + ndpi_set_detected_protocol(ndpi_struct, flow, flow->http_upper_protocol, flow->http_lower_protocol); + else { + flow->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN, flow->detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; + flow->packet.detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN, flow->packet.detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; } - flow->l4.tcp.http_empty_line_seen = 0; - return; - } - - /** - for reference see http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp - **/ - if(packet->empty_line_position_set != 0) { - - u_int32_t p = packet->empty_line_position + 2; - - // check for avi header - NDPI_LOG_DBG2(ndpi_struct, "p = %u\n", p); - - if((p + 16) <= packet->payload_packet_len && memcmp(&packet->payload[p], "RIFF", 4) == 0 - && memcmp(&packet->payload[p + 8], "AVI LIST", 8) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found Avi content in HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_CATEGORY_AVI); + } else { + if((!ndpi_struct->http_dont_dissect_response) && (flow->http.response_status_code == 0)) { + flow->http_upper_protocol = flow->detected_protocol_stack[0], flow->http_lower_protocol = flow->detected_protocol_stack[1]; + flow->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN, flow->detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; + flow->packet.detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN, flow->packet.detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; } } -} -#endif - -static void teamviewer_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - const u_int8_t *pos; - - NDPI_LOG_DBG2(ndpi_struct, "called teamviewer_check_http_payload: %u %u %u\n", - packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position); - - if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 5) > (packet->payload_packet_len)) - return; - - pos = &packet->payload[packet->empty_line_position] + 2; - if(pos[0] == 0x17 && pos[1] == 0x24) { - NDPI_LOG_INFO(ndpi_struct, "found TeamViewer content in HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER); - } + flow->http_detected = 1, flow->guessed_category = category; } static void rtsp_parse_packet_acceptline(struct ndpi_detection_module_struct @@ -171,10 +98,10 @@ static void setHttpUserAgent(struct ndpi_detection_module_struct *ndpi_struct, static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { if((flow->l4.tcp.http_stage == 0) || (flow->http.url && flow->http_detected)) { - char *double_col = strchr((char*)flow->host_server_name, ':'); - ndpi_protocol_match_result ret_match; - - if(double_col) double_col[0] = '\0'; + char *double_col = strchr((char*)flow->host_server_name, ':'); + ndpi_protocol_match_result ret_match; + + if(double_col) double_col[0] = '\0'; /** NOTE @@ -198,6 +125,14 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ struct ndpi_packet_struct *packet = &flow->packet; u_int8_t a; + if((!ndpi_struct->http_dont_dissect_response) && flow->http_detected && (flow->http.response_status_code != 0)) { + ndpi_set_detected_protocol(ndpi_struct, flow, flow->http_upper_protocol, flow->http_lower_protocol); +#ifdef DEBUG + printf("[%s] [http_dont_dissect_response: %u]->> %s\n", + __FUNCTION__, ndpi_struct->http_dont_dissect_response, flow->http.response_status_code); +#endif + return; + } #if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI) /* PPStream */ @@ -222,7 +157,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } #endif - if(!ndpi_struct->http_dont_dissect_response) { + /* Leave the statement below commented necessary in case of call to ndpi_get_partial_detection() */ + + /* if(!ndpi_struct->http_dont_dissect_response) */ { if((flow->http.url == NULL) && (packet->http_url_name.len > 0) && (packet->host_line.len > 0)) { @@ -238,25 +175,25 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } if(flow->packet.http_method.len < 3) - flow->http.method = HTTP_METHOD_UNKNOWN; + flow->http.method = NDPI_HTTP_METHOD_UNKNOWN; else { switch(flow->packet.http_method.ptr[0]) { - case 'O': flow->http.method = HTTP_METHOD_OPTIONS; break; - case 'G': flow->http.method = HTTP_METHOD_GET; break; - case 'H': flow->http.method = HTTP_METHOD_HEAD; break; + case 'O': flow->http.method = NDPI_HTTP_METHOD_OPTIONS; break; + case 'G': flow->http.method = NDPI_HTTP_METHOD_GET; break; + case 'H': flow->http.method = NDPI_HTTP_METHOD_HEAD; break; case 'P': switch(flow->packet.http_method.ptr[1]) { - case 'O': flow->http.method = HTTP_METHOD_POST; break; - case 'U': flow->http.method = HTTP_METHOD_PUT; break; + case 'O': flow->http.method = NDPI_HTTP_METHOD_POST; break; + case 'U': flow->http.method = NDPI_HTTP_METHOD_PUT; break; } break; - case 'D': flow->http.method = HTTP_METHOD_DELETE; break; - case 'T': flow->http.method = HTTP_METHOD_TRACE; break; - case 'C': flow->http.method = HTTP_METHOD_CONNECT; break; + case 'D': flow->http.method = NDPI_HTTP_METHOD_DELETE; break; + case 'T': flow->http.method = NDPI_HTTP_METHOD_TRACE; break; + case 'C': flow->http.method = NDPI_HTTP_METHOD_CONNECT; break; default: - flow->http.method = HTTP_METHOD_UNKNOWN; + flow->http.method = NDPI_HTTP_METHOD_UNKNOWN; break; } } @@ -277,8 +214,8 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) { /** Format examples: - Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) .... - Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0 + Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) .... + Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0 */ if(packet->user_agent_line.len > 7) { char ua[256]; @@ -308,22 +245,22 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(token && (token[0] == ' ')) token++; /* Skip space */ if(token - && ((strcmp(token, "U") == 0) - || (strncmp(token, "MSIE", 4) == 0))) { - token = strsep(&parent, ";"); - if(token && (token[0] == ' ')) token++; /* Skip space */ + && ((strcmp(token, "U") == 0) + || (strncmp(token, "MSIE", 4) == 0))) { + token = strsep(&parent, ";"); + if(token && (token[0] == ' ')) token++; /* Skip space */ - if(token && (strncmp(token, "Update", 6) == 0)) { - token = strsep(&parent, ";"); + if(token && (strncmp(token, "Update", 6) == 0)) { + token = strsep(&parent, ";"); - if(token && (token[0] == ' ')) token++; /* Skip space */ + if(token && (token[0] == ' ')) token++; /* Skip space */ - if(token && (strncmp(token, "AOL", 3) == 0)) { + if(token && (strncmp(token, "AOL", 3) == 0)) { - token = strsep(&parent, ";"); - if(token && (token[0] == ' ')) token++; /* Skip space */ - } - } + token = strsep(&parent, ";"); + if(token && (token[0] == ' ')) token++; /* Skip space */ + } + } } } @@ -340,7 +277,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } NDPI_LOG_DBG2(ndpi_struct, "User Agent Type line found %.*s\n", - packet->user_agent_line.len, packet->user_agent_line.ptr); + packet->user_agent_line.len, packet->user_agent_line.ptr); } /* check for host line */ @@ -348,37 +285,37 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ u_int len; NDPI_LOG_DBG2(ndpi_struct, "HOST line found %.*s\n", - packet->host_line.len, packet->host_line.ptr); + packet->host_line.len, packet->host_line.ptr); /* call ndpi_match_host_subprotocol to see if there is a match with known-host HTTP subprotocol */ if((ndpi_struct->http_dont_dissect_response) || flow->http_detected) { ndpi_protocol_match_result ret_match; - + ndpi_match_host_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len, &ret_match, NDPI_PROTOCOL_HTTP); } - + /* Copy result for nDPI apps */ if(!ndpi_struct->disable_metadata_export) { len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1); strncpy((char*)flow->host_server_name, (char*)packet->host_line.ptr, len); flow->host_server_name[len] = '\0'; } - + flow->server_id = flow->dst; if(packet->forwarded_line.ptr) { - len = ndpi_min(packet->forwarded_line.len, sizeof(flow->protos.http.nat_ip)-1); - if(!ndpi_struct->disable_metadata_export) { - strncpy((char*)flow->protos.http.nat_ip, (char*)packet->forwarded_line.ptr, len); - flow->protos.http.nat_ip[len] = '\0'; - } + len = ndpi_min(packet->forwarded_line.len, sizeof(flow->protos.http.nat_ip)-1); + if(!ndpi_struct->disable_metadata_export) { + strncpy((char*)flow->protos.http.nat_ip, (char*)packet->forwarded_line.ptr, len); + flow->protos.http.nat_ip[len] = '\0'; + } } - if(ndpi_struct->http_dont_dissect_response) + if(!ndpi_struct->http_dont_dissect_response) parseHttpSubprotocol(ndpi_struct, flow); /** @@ -403,26 +340,28 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ && ((ndpi_struct->http_dont_dissect_response) || flow->http_detected) && (packet->http_origin.len > 0)) { ndpi_protocol_match_result ret_match; - + ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)packet->http_origin.ptr, packet->http_origin.len, &ret_match, NDPI_PROTOCOL_HTTP); } - + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) { - NDPI_LOG_INFO(ndpi_struct, "found HTTP/%s\n", - ndpi_get_proto_name(ndpi_struct, packet->detected_protocol_stack[0])); + NDPI_LOG_INFO(ndpi_struct, "found HTTP/%s\n", + ndpi_get_proto_name(ndpi_struct, packet->detected_protocol_stack[0])); ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]); return; /* We have identified a sub-protocol so we're done */ } } } +#if 0 if(!ndpi_struct->http_dont_dissect_response && flow->http_detected) parseHttpSubprotocol(ndpi_struct, flow); +#endif if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_HTTP; @@ -430,50 +369,31 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ /* check for accept line */ if(packet->accept_line.ptr != NULL) { NDPI_LOG_DBG2(ndpi_struct, "Accept line found %.*s\n", - packet->accept_line.len, packet->accept_line.ptr); + packet->accept_line.len, packet->accept_line.ptr); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_RTSP) != 0) { rtsp_parse_packet_acceptline(ndpi_struct, flow); } } - /* search for line startin with "Icy-MetaData" */ - for (a = 0; a < packet->parsed_lines; a++) { - if(packet->line[a].len > 11 && memcmp(packet->line[a].ptr, "Icy-MetaData", 12) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found MPEG: Icy-MetaData\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_CATEGORY_MPEG); - return; - } - } - if(packet->content_line.ptr != NULL && packet->content_line.len != 0) { NDPI_LOG_DBG2(ndpi_struct, "Content Type line found %.*s\n", - packet->content_line.len, packet->content_line.ptr); + packet->content_line.len, packet->content_line.ptr); if((ndpi_struct->http_dont_dissect_response) || flow->http_detected) { ndpi_protocol_match_result ret_match; - + ndpi_match_content_subprotocol(ndpi_struct, flow, (char*)packet->content_line.ptr, packet->content_line.len, &ret_match, NDPI_PROTOCOL_HTTP); } } -} -static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - NDPI_LOG_DBG2(ndpi_struct, "called check_http_payload\n"); - -#ifdef NDPI_CONTENT_CATEGORY_FLASH - if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_CATEGORY_FLASH) != 0) - flash_check_http_payload(ndpi_struct, flow); -#endif -#ifdef NDPI_CONTENT_CATEGORY_AVI - if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_CATEGORY_AVI) != 0) - avi_check_http_payload(ndpi_struct, flow); -#endif + ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]); +} - teamviewer_check_http_payload(ndpi_struct, flow); +static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + /* Add here your paylod code check */ } /** @@ -486,22 +406,22 @@ static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, #define STATIC_STRING_L(a) {.str=a, .len=sizeof(a)-1 } static struct l_string { - const char *str; - size_t len; + const char *str; + size_t len; } http_methods[] = { - STATIC_STRING_L("GET "), - STATIC_STRING_L("POST "), - STATIC_STRING_L("OPTIONS "), - STATIC_STRING_L("HEAD "), - STATIC_STRING_L("PUT "), - STATIC_STRING_L("DELETE "), - STATIC_STRING_L("CONNECT "), - STATIC_STRING_L("PROPFIND "), - STATIC_STRING_L("REPORT ") }; + STATIC_STRING_L("GET "), + STATIC_STRING_L("POST "), + STATIC_STRING_L("OPTIONS "), + STATIC_STRING_L("HEAD "), + STATIC_STRING_L("PUT "), + STATIC_STRING_L("DELETE "), + STATIC_STRING_L("CONNECT "), + STATIC_STRING_L("PROPFIND "), + STATIC_STRING_L("REPORT ") }; static const char *http_fs = "CDGHOPR"; static uint8_t non_ctrl(uint8_t c) { - return c < 32 ? '.':c; + return c < 32 ? '.':c; } static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -510,9 +430,9 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd int i; NDPI_LOG_DBG2(ndpi_struct, "====>>>> HTTP: %c%c%c%c [len: %u]\n", - non_ctrl(packet->payload[0]), non_ctrl(packet->payload[1]), - non_ctrl(packet->payload[2]), non_ctrl(packet->payload[3]), - packet->payload_packet_len); + non_ctrl(packet->payload[0]), non_ctrl(packet->payload[1]), + non_ctrl(packet->payload[2]), non_ctrl(packet->payload[3]), + packet->payload_packet_len); /* Check first char */ if(!strchr(http_fs,packet->payload[0])) return 0; @@ -520,43 +440,24 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd FIRST PAYLOAD PACKET FROM CLIENT **/ for(i=0; i < sizeof(http_methods)/sizeof(http_methods[0]); i++) { - if(packet->payload_packet_len >= http_methods[i].len && - memcmp(packet->payload,http_methods[i].str,http_methods[i].len) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "HTTP: %sFOUND\n",http_methods[i].str); - return http_methods[i].len; - } + if(packet->payload_packet_len >= http_methods[i].len && + memcmp(packet->payload,http_methods[i].str,http_methods[i].len) == 0) { + NDPI_LOG_DBG2(ndpi_struct, "HTTP: %sFOUND\n",http_methods[i].str); + return http_methods[i].len; + } } return 0; } static void http_bitmask_exclude_other(struct ndpi_flow_struct *flow) { -#ifdef NDPI_CONTENT_CATEGORY_MPEG - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_MPEG); -#endif -#ifdef NDPI_CONTENT_CATEGORY_QUICKTIME - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_QUICKTIME); -#endif -#ifdef NDPI_CONTENT_CATEGORY_WINDOWSMEDIA - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_WINDOWSMEDIA); -#endif -#ifdef NDPI_CONTENT_CATEGORY_REALMEDIA - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_REALMEDIA); -#endif -#ifdef NDPI_CONTENT_CATEGORY_AVI - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_AVI); -#endif -#ifdef NDPI_CONTENT_CATEGORY_OGG - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_OGG); -#endif - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX); } /*************************************************************************************************/ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int16_t filename_start; /* the filename in the request method line, e.g., "GET filename_start..."*/ @@ -576,6 +477,20 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) { NDPI_LOG_INFO(ndpi_struct, "found HTTP response\n"); + + if(packet->payload_packet_len >= 12) { + char buf[4]; + + /* Set server HTTP response code */ + strncpy(buf, (char*)&packet->payload[9], 3); + buf[3] = '\0'; + + flow->http.response_status_code = atoi(buf); + /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */ + if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509)) + flow->http.response_status_code = 0; /* Out of range */ + } + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); check_content_type_and_change_protocol(ndpi_struct, flow); return; @@ -586,7 +501,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct flow->l4.tcp.http_stage = 1; return; } - + if((packet->payload_packet_len == 40) && (flow->l4.tcp.http_stage == 0)) { /* -> QR O06L0072-6L91-4O43-857J-K8OO172L6L51 @@ -600,11 +515,11 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct && (packet->payload[21] == '-') && (packet->payload[26] == '-') && (packet->payload[39] == 0x0A) - ) - flow->l4.tcp.http_stage = 1; - return; + ) + flow->l4.tcp.http_stage = 1; + return; } - + if((packet->payload_packet_len == 23) && (memcmp(packet->payload, "<policy-file-request/>", 23) == 0)) { /* <policy-file-request/> @@ -617,35 +532,31 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); if(ndpi_struct->ookla_cache == NULL) - ndpi_struct->ookla_cache = lruc_new(4*1024, 1024); + ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024); - if(ndpi_struct->ookla_cache != NULL) { - u_int8_t *dummy = (u_int8_t*)ndpi_malloc(sizeof(u_int8_t)); - - if(dummy) { - if(packet->tcp->source == htons(8080)) - lruc_set((lruc*)ndpi_struct->ookla_cache, (void*)&packet->iph->saddr, 4, dummy, 1); - else - lruc_set((lruc*)ndpi_struct->ookla_cache, (void*)&packet->iph->daddr, 4, dummy, 1); - } + if(packet->iph != NULL && ndpi_struct->ookla_cache != NULL) { + if(packet->tcp->source == htons(8080)) + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr); + else + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr); } return; } - + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); http_bitmask_exclude_other(flow); return; } NDPI_LOG_DBG2(ndpi_struct, - "Filename HTTP found: %d, we look for line info..\n", filename_start); + "Filename HTTP found: %d, we look for line info..\n", filename_start); ndpi_parse_packet_line_info(ndpi_struct, flow); if(packet->parsed_lines <= 1) { NDPI_LOG_DBG2(ndpi_struct, - "Found just one line, we will look further for the next packet...\n"); + "Found just one line, we will look further for the next packet...\n"); packet->http_method.ptr = packet->line[0].ptr; packet->http_method.len = filename_start - 1; @@ -656,10 +567,10 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct } NDPI_LOG_DBG2(ndpi_struct, - "Found more than one line, we look further for the next packet...\n"); + "Found more than one line, we look further for the next packet...\n"); if(packet->line[0].len >= (9 + filename_start) - && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { /* Request line complete. Ex. "GET / HTTP/1.1" */ + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { /* Request line complete. Ex. "GET / HTTP/1.1" */ packet->http_url_name.ptr = &packet->payload[filename_start]; packet->http_url_name.len = packet->line[0].len - (filename_start + 9); @@ -669,14 +580,13 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct // Set the HTTP requested version: 0=HTTP/1.0 and 1=HTTP/1.1 if(memcmp(&packet->line[0].ptr[packet->line[0].len - 1], "1", 1) == 0) - flow->http.request_version = 1; + flow->http.request_version = 1; else - flow->http.request_version = 0; + flow->http.request_version = 0; /* Set the first found headers in request */ flow->http.num_request_headers = packet->http_num_headers; - /* Check for Ookla */ if((packet->referer_line.len > 0) && ndpi_strnstr((const char *)packet->referer_line.ptr, "www.speedtest.net", packet->referer_line.len)) { @@ -686,22 +596,22 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct /* Check for additional field introduced by Steam */ int x = 1; if(packet->line[x].len >= 11 && (memcmp(packet->line[x].ptr, "x-steam-sid", 11)) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found STEAM\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM); - check_content_type_and_change_protocol(ndpi_struct, flow); - return; + NDPI_LOG_INFO(ndpi_struct, "found STEAM\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM); + check_content_type_and_change_protocol(ndpi_struct, flow); + return; } /* Check for additional field introduced by Facebook */ x = 1; while(packet->line[x].len != 0) { - if(packet->line[x].len >= 12 && (memcmp(packet->line[x].ptr, "X-FB-SIM-HNI", 12)) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found FACEBOOK\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FACEBOOK); - check_content_type_and_change_protocol(ndpi_struct, flow); - return; - } - x++; + if(packet->line[x].len >= 12 && (memcmp(packet->line[x].ptr, "X-FB-SIM-HNI", 12)) == 0) { + NDPI_LOG_INFO(ndpi_struct, "found FACEBOOK\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FACEBOOK); + check_content_type_and_change_protocol(ndpi_struct, flow); + return; + } + x++; } #if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI) @@ -746,23 +656,23 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct } } #endif - + if((packet->http_url_name.len > 7) - && (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) { + && (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) { NDPI_LOG_INFO(ndpi_struct, "found HTTP_PROXY\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY); check_content_type_and_change_protocol(ndpi_struct, flow); } if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) { - /* nathan@getoffmalawn.com */ + /* nathan@getoffmalawn.com */ NDPI_LOG_INFO(ndpi_struct, "found HTTP_CONNECT\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT); check_content_type_and_change_protocol(ndpi_struct, flow); } NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found, we will look for sub-protocols (content and host)...\n"); + "HTTP START Found, we will look for sub-protocols (content and host)...\n"); if(packet->host_line.ptr != NULL) { /** @@ -775,11 +685,11 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct if(ndpi_struct->http_dont_dissect_response) { if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) /* No subprotocol found */ NDPI_LOG_INFO(ndpi_struct, "found HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); } else { flow->http_detected = 1; NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found, we will look further for the response...\n"); + "HTTP START Found, we will look further for the response...\n"); flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 } @@ -790,23 +700,21 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct NDPI_EXCLUDE_PROTO(ndpi_struct, flow); http_bitmask_exclude_other(flow); - } else if((flow->l4.tcp.http_stage == 1) || (flow->l4.tcp.http_stage == 2)) { - NDPI_LOG_DBG2(ndpi_struct, "HTTP stage %u: \n", flow->l4.tcp.http_stage); - + if((packet->payload_packet_len == 34) && (flow->l4.tcp.http_stage == 1)) { if((packet->payload[5] == ' ') && (packet->payload[9] == ' ')) { goto ookla_found; } } - + if((packet->payload_packet_len > 6) && memcmp(packet->payload, "HELLO ", 6) == 0) { - /* This looks like Ookla */ + /* This looks like Ookla */ goto ookla_found; } else - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OOKLA); - + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OOKLA); + /** At first check, if this is for sure a response packet (in another direction. If not, if HTTP is detected do nothing now and return, otherwise check the second packet for the HTTP request @@ -817,7 +725,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct return; NDPI_LOG_DBG2(ndpi_struct, - " SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP...UNKNOWN TRAFFIC, HERE FOR HTTP again.. \n"); + " SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP...UNKNOWN TRAFFIC, HERE FOR HTTP again.. \n"); ndpi_parse_packet_line_info(ndpi_struct, flow); @@ -839,14 +747,14 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct } // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark if(packet->line[0].len >= 9 - && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { NDPI_LOG_INFO(ndpi_struct, "found HTTP\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); check_content_type_and_change_protocol(ndpi_struct, flow); NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found in 2. packet, we will look further for the response....\n"); + "HTTP START Found in 2. packet, we will look further for the response....\n"); flow->http_detected = 1; } @@ -879,9 +787,8 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct ndpi_parse_packet_line_info(ndpi_struct, flow); check_content_type_and_change_protocol(ndpi_struct, flow); - if(packet->packet_direction == 1 /* server -> client */){ - flow->http.num_response_headers += packet->http_num_headers; /* flow structs are initialized with zeros */ - } + if(packet->packet_direction == 1 /* server -> client */) + flow->http.num_response_headers += packet->http_num_headers; /* flow structs are initialized with zeros */ if(packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) { NDPI_LOG_DBG2(ndpi_struct, "empty line. check_http_payload\n"); @@ -905,8 +812,8 @@ void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, } if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { - return; - } + return; + } NDPI_LOG_DBG(ndpi_struct, "search HTTP\n"); ndpi_check_http_tcp(ndpi_struct, flow); @@ -917,7 +824,7 @@ void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod, struct ndpi_flow_struct *flow) { if(!flow) - return(HTTP_METHOD_UNKNOWN); + return(NDPI_HTTP_METHOD_UNKNOWN); else return(flow->http.method); } @@ -935,7 +842,7 @@ char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod, /* ********************************* */ char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod, - struct ndpi_flow_struct *flow) { + struct ndpi_flow_struct *flow) { if((!flow) || (!flow->http.content_type)) return(""); else @@ -953,130 +860,4 @@ void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; - -#if 0 - ndpi_set_bitmask_protocol_detection("HTTP_Proxy", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_HTTP_PROXY, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - -#ifdef NDPI_CONTENT_CATEGORY_MPEG - ndpi_set_bitmask_protocol_detection("MPEG", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_MPEG, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_FLASH - ndpi_set_bitmask_protocol_detection("Flash", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_FLASH, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_QUICKTIME - ndpi_set_bitmask_protocol_detection("QuickTime", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_QUICKTIME, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_REALMEDIA - ndpi_set_bitmask_protocol_detection("RealMedia", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_REALMEDIA, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_WINDOWSMEDIA - ndpi_set_bitmask_protocol_detection("WindowsMedia", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_WINDOWSMEDIA, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_MMS - ndpi_set_bitmask_protocol_detection("MMS", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_MMS, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif - - ndpi_set_bitmask_protocol_detection("Xbox", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_XBOX, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_QQ, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - -#ifdef NDPI_CONTENT_CATEGORY_AVI - ndpi_set_bitmask_protocol_detection("AVI", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_AVI, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif -#ifdef NDPI_CONTENT_CATEGORY_OGG - ndpi_set_bitmask_protocol_detection("OggVorbis", ndpi_struct, detection_bitmask, *id, - NDPI_CONTENT_CATEGORY_OGG, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -#endif - - /* Update excluded protocol bitmask */ - NDPI_BITMASK_SET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, - ndpi_struct->callback_buffer[a].detection_bitmask); - - /*Delete protocol from excluded protocol bitmask*/ - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, NDPI_PROTOCOL_UNKNOWN); - - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, NDPI_PROTOCOL_QQ); - -#ifdef NDPI_CONTENT_CATEGORY_FLASH - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_FLASH); -#endif - - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, NDPI_CONTENT_CATEGORY_MMS); - - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX); - - NDPI_BITMASK_SET(ndpi_struct->generic_http_packet_bitmask, ndpi_struct->callback_buffer[a].detection_bitmask); - - NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->generic_http_packet_bitmask, NDPI_PROTOCOL_UNKNOWN); - - /* Update callback_buffer index */ - a++; - -#endif } |