diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_api.h | 527 | ||||
-rw-r--r-- | src/include/ndpi_define.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_protocol_ids.h | 30 | ||||
-rw-r--r-- | src/include/ndpi_protocols.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 22 | ||||
-rw-r--r-- | src/lib/Makefile.am | 4 | ||||
-rw-r--r-- | src/lib/ndpi_content_match.c.inc | 289 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 282 | ||||
-rw-r--r-- | src/lib/protocols/bittorrent.c | 243 | ||||
-rw-r--r-- | src/lib/protocols/dhcp.c | 30 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 61 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 29 | ||||
-rw-r--r-- | src/lib/protocols/sip.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/socks4.c | 96 | ||||
-rw-r--r-- | src/lib/protocols/socks45.c | 155 | ||||
-rw-r--r-- | src/lib/protocols/socks5.c | 92 | ||||
-rw-r--r-- | src/lib/protocols/ssl.c | 42 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 16 | ||||
-rw-r--r-- | src/lib/protocols/tcp_udp.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/tor.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/veohtv.c | 130 |
21 files changed, 1113 insertions, 959 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 364fd0101..a07c96e63 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -1,8 +1,7 @@ /* * ndpi_api.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -32,47 +31,100 @@ extern "C" { #endif - /** - * This function returns the size of the flow struct - * @return the size of the flow struct +#define NDPI_DETECTION_ONLY_IPV4 ( 1 << 0 ) +#define NDPI_DETECTION_ONLY_IPV6 ( 1 << 1 ) + +#define ADD_TO_DETECTION_BITMASK 1 +#define NO_ADD_TO_DETECTION_BITMASK 0 +#define SAVE_DETECTION_BITMASK_AS_UNKNOWN 1 +#define NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN 0 + + + /** + * Check if a string is encoded with punycode + * ( https://tools.ietf.org/html/rfc3492 ) + * + * @par buff = pointer to the string to ckeck + * @par len = len of the string + * @return 1 if the string is punycoded; + * else 0 + * + */ + int check_punycode_string(char * buff , int len); + + + /** + * Get the size of the flow struct + * + * @return the size of the flow struct + * */ u_int32_t ndpi_detection_get_sizeof_ndpi_flow_struct(void); + - /** - * This function returns the size of the id struct - * @return the size of the id struct + /** + * Get the size of the id struct + * + * @return the size of the id struct + * */ u_int32_t ndpi_detection_get_sizeof_ndpi_id_struct(void); - /* Public malloc/free */ - void* ndpi_malloc(size_t size); - void* ndpi_calloc(unsigned long count, size_t size); - void ndpi_free(void *ptr); - void *ndpi_realloc(void *ptr, size_t old_size, size_t new_size); - char *ndpi_strdup(const char *s); /** - * Find the first occurrence of find in s, where the search is limited to the - * first slen characters of s. + * nDPI personal allocation and free functions + **/ + void * ndpi_malloc(size_t size); + void * ndpi_calloc(unsigned long count, size_t size); + void * ndpi_realloc(void *ptr, size_t old_size, size_t new_size); + char * ndpi_strdup(const char *s); + void ndpi_free(void *ptr); + + + /** + * Search the first occurrence of substring -find- in -s- + * The search is limited to the first -slen- characters of the string + * + * @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_strnstr(const char *s, const char *find, size_t slen); + /** - * This function returns the nDPI protocol id for IP-based protocol detection + * Returns the nDPI protocol id for IP-based protocol detection + * + * @par ndpi_struct = the struct created for the protocol detection + * @par pin = IP host address (MUST BE in network byte order): + * See man(7) ip for details + * @return the nDPI protocol ID + * */ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin); + /** - * Same as ndpi_network_ptree_match - */ - u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host); + * Init single protocol match + * + * @par ndpi_mod = the struct created for the protocol detection + * @par match = the struct passed to match the protocol + * + */ + void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_match *match); + /** - * This function returns a new initialized detection module. - * @param ticks_per_second the timestamp resolution per second (like 1000 for millisecond resolution) - * @param __ndpi_malloc function pointer to a memory allocator - * @param ndpi_debug_printf a function pointer to a debug output function, use NULL in productive envionments - * @return the initialized detection module + * Returns a new initialized detection module + * + * @par ticks_per_second = the timestamp resolution per second (like 1000 for millisecond resolution) + * @par __ndpi_malloc = function pointer to a nDPI memory allocator + * @par ndpi_debug_printf = function pointer to a nDPI debug output function (use NULL in productive envionments) + * @return the initialized detection module + * */ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, void* (*__ndpi_malloc)(size_t size), @@ -81,47 +133,97 @@ extern "C" { /** - * This function frees the memory allocated in the specified flow - * @param flow to free + * Frees the memory allocated in the specified flow + * + * @par flow = the flow to deallocate + * */ void ndpi_free_flow(struct ndpi_flow_struct *flow); + /** - * This function enables cache support in nDPI used for some protocol such as Skype - * @param host host name - * @param port port number + * Enables cache support. + * In nDPI is used for some protocol (i.e. Skype) + * + * @par ndpi_mod = the struct created for the protocol detection + * @par host = string for the host name + * @par port = unsigned int for the port number + * */ void ndpi_enable_cache(struct ndpi_detection_module_struct *ndpi_mod, char* host, u_int port); + /** - * This function destroys the detection module - * @param ndpi_struct the to clearing detection module - * @param ndpi_free function pointer to a memory free function + * Destroys the detection module + * + * @par ndpi_struct = the struct to clearing for the detection module + * @par ndpi_free = function pointer to a nDPI memory free function + * */ - void - ndpi_exit_detection_module(struct ndpi_detection_module_struct - *ndpi_struct, void (*ndpi_free) (void *ptr)); + void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct, void (*ndpi_free) (void *ptr)); + /** - * This function sets the protocol bitmask2 - * @param ndpi_struct the detection module - * @param detection_bitmask the protocol bitmask + * Sets a single protocol bitmask + * This function does not increment the index of the callback_buffer + * + * @par label = string for the protocol name + * @par ndpi_struct = the detection module + * @par detection_bitmask = the protocol bitmask + * @par idx = the index of the callback_buffer + * @par func = function pointer of the protocol search + * @par ndpi_selection_bitmask = the protocol selected bitmask + * @par b_save_bitmask_unknow = if set as "true" save the detection bitmask as unknow + * @par b_add_detection_bitmask = if set as "true" add the protocol bitmask to the detection bitmask + * */ - void - ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct, - const NDPI_PROTOCOL_BITMASK * detection_bitmask); + void ndpi_set_bitmask_protocol_detection(char *label, struct ndpi_detection_module_struct *ndpi_struct, + const NDPI_PROTOCOL_BITMASK *detection_bitmask, + const u_int32_t idx, + u_int16_t ndpi_protocol_id, + void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow), + const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask, + u_int8_t b_save_bitmask_unknow, + u_int8_t b_add_detection_bitmask); + + /** - * This function will processes one packet and returns the ID of the detected protocol. - * This is the main packet processing function. + * Sets the protocol bitmask2 + * + * @par ndpi_struct = the detection module + * @par detection_bitmask = the protocol bitmask to set + * + */ + void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct, + const NDPI_PROTOCOL_BITMASK * detection_bitmask); + + + /** + * Function to be called before we give up with detection for a given flow. + * This function reduces the NDPI_UNKNOWN_PROTOCOL detection + * + * @par ndpi_struct = the detection module + * @par flow = the flow given for the detection module + * @return the detected protocol even if the flow is not completed; + * + */ + ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + + + /** + * Processes one packet and returns the ID of the detected protocol. + * This is the MAIN PACKET PROCESSING FUNCTION. + * + * @par ndpi_struct = the detection module + * @par flow = pointer to the connection state machine + * @par packet = unsigned char pointer to the Layer 3 (IP header) + * @par packetlen = the length of the packet + * @par current_tick = the current timestamp for the packet + * @par src = pointer to the source subscriber state machine + * @par dst = pointer to the destination subscriber state machine + * @return the detected ID of the protocol * - * @param ndpi_struct the detection module - * @param flow void pointer to the connection state machine - * @param packet the packet as unsigned char pointer with the length of packetlen. the pointer must point to the Layer 3 (IP header) - * @param packetlen the length of the packet - * @param current_tick the current timestamp for the packet - * @param src void pointer to the source subscriber state machine - * @param dst void pointer to the destination subscriber state machine - * @return returns the detected ID of the protocol */ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, @@ -131,106 +233,313 @@ extern "C" { struct ndpi_id_struct *src, struct ndpi_id_struct *dst); + + /** + * Get the main protocol of the passed flows for the detected module + * + * + * @par ndpi_struct = the detection module + * @par flow = the flow given for the detection module + * @return the ID of the master protocol detected + * + */ u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -#define NDPI_DETECTION_ONLY_IPV4 ( 1 << 0 ) -#define NDPI_DETECTION_ONLY_IPV6 ( 1 << 1 ) - + /** - * query the pointer to the layer 4 packet + * Query the pointer to the layer 4 packet + * + * @par l3 = pointer to the layer 3 data + * @par l3_len = length of the layer 3 data + * @par l4_return = address to the pointer of the layer 4 data if return value == 0, else undefined + * @par l4_len_return = length of the layer 4 data if return value == 0, else undefined + * @par l4_protocol_return = protocol of the layer 4 data if return value == 0, undefined otherwise + * @par flags = limit operation on ipv4 or ipv6 packets. Possible values: NDPI_DETECTION_ONLY_IPV4 - NDPI_DETECTION_ONLY_IPV6 - 0 (any) + * @return 0 if layer 4 data could be found correctly; + else != 0 * - * @param l3 pointer to the layer 3 data - * @param l3_len length of the layer 3 data - * @param l4_return filled with the pointer the layer 4 data if return value == 0, undefined otherwise - * @param l4_len_return filled with the length of the layer 4 data if return value == 0, undefined otherwise - * @param l4_protocol_return filled with the protocol of the layer 4 data if return value == 0, undefined otherwise - * @param flags limit operation on ipv4 or ipv6 packets, possible values are NDPI_DETECTION_ONLY_IPV4 or NDPI_DETECTION_ONLY_IPV6; 0 means any - * @return 0 if correct layer 4 data could be found, != 0 otherwise */ - u_int8_t ndpi_detection_get_l4(const u_int8_t * l3, u_int16_t l3_len, const u_int8_t ** l4_return, u_int16_t * l4_len_return, - u_int8_t * l4_protocol_return, u_int32_t flags); + u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return, u_int16_t *l4_len_return, + u_int8_t *l4_protocol_return, u_int32_t flags); + +#if 0 /** * returns true if the protocol history of the flow of the last packet given to the detection * contains the given protocol. * * @param ndpi_struct the detection module * @return 1 if protocol has been found, 0 otherwise + * */ u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - u_int16_t protocol_id); - ndpi_protocol ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport); + struct ndpi_flow_struct *flow, + u_int16_t protocol_id); +#endif + + /** + * Search and return the protocol based on matched ports + * + * @par ndpi_struct = the detection module + * @par shost = source address in host byte order + * @par sport = source port number + * @par dhost = destination address in host byte order + * @par dport = destination port number + * @return the struct ndpi_protocol that match the port base protocol + * + */ + ndpi_protocol ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct/* , u_int8_t proto */, + u_int32_t shost, + u_int16_t sport, + u_int32_t dhost, + u_int16_t dport); + + + /** + * Search and return the protocol guessed that is undetected + * + * @par ndpi_struct = the detection module + * @par proto = the l4 protocol number + * @par shost = source address in host byte order + * @par sport = source port number + * @par dhost = destination address in host byte order + * @par dport = destination port number + * @return the struct ndpi_protocol that match the port base protocol + * + */ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport); + u_int8_t proto, + u_int32_t shost, + u_int16_t sport, + u_int32_t dhost, + u_int16_t dport); + + + /** + * Check if the string passed match with a protocol + * + * @par ndpi_struct = the detection module + * @par string_to_match = the string to match + * @par string_to_match_len = the length of the string + * @par is_host_match = value of the second field of struct ndpi_automa + * @return the ID of the matched subprotocol + * + */ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, - char *string_to_match, u_int string_to_match_len); + char *string_to_match, + u_int string_to_match_len, + u_int8_t is_host_match); + + + /** + * Check if the host passed match with a protocol + * + * @par ndpi_struct = the detection module + * @par flow = the flow where match the host + * @par string_to_match = the string to match + * @par string_to_match_len = the length of the string + * @par master_protocol_id = value of the ID associated to the master protocol detected + * @return the ID of the matched subprotocol + * + */ int ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len, + struct ndpi_flow_struct *flow, + char *string_to_match, + u_int string_to_match_len, u_int16_t master_protocol_id); + + + /** + * Check if the string content passed match with a protocol + * + * @par ndpi_struct = the detection module + * @par flow = the flow where match the host + * @par string_to_match = the string to match + * @par string_to_match_len = the length of the string + * @par master_protocol_id = value of the ID associated to the master protocol detected + * @return the ID of the matched subprotocol + * + */ int ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - char *string_to_match, u_int string_to_match_len, + char *string_to_match, + u_int string_to_match_len, u_int16_t master_protocol_id); + + + /** + * Check if the string -bigram_to_match- match with a bigram of -automa- + * + * @par ndpi_struct = the detection module + * @par automa = the struct ndpi_automa for the bigram + * @par bigram_to_match = the bigram string to match + * @return 0 + * + */ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct, - ndpi_automa *automa, char *bigram_to_match); + ndpi_automa *automa, + char *bigram_to_match); + + + /** + * Write the protocol name in the buffer -buf- as master_protocol.protocol + * + * @par ndpi_mod = the detection module + * @par proto = the struct ndpi_protocol contain the protocols name + * @par buf = the buffer to write the name of the protocols + * @par buf_len = the length of the buffer + * @return the buffer contains the master_protocol and protocol name + * + */ char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len); + + + /** + * Get the protocol name associated to the ID + * + * @par mod = the detection module + * @par proto_id = the ID of the protocol + * @return the buffer contains the master_protocol and protocol name + * + */ char* ndpi_get_proto_name(struct ndpi_detection_module_struct *mod, u_int16_t proto_id); + + + /** + * Return the protocol breed ID associated to the protocol + * + * @par ndpi_struct = the detection module + * @par proto = the ID of the protocol + * @return the breed ID associated to the protocol + * + */ ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t proto); + + + /** + * Return the string name of the protocol breed + * + * @par ndpi_struct = the detection module + * @par breed_id = the breed ID associated to the protocol + * @return the string name of the breed ID + * + */ char* ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_struct, ndpi_protocol_breed_t breed_id); + + + /** + * Return the ID of the protocol + * + * @par ndpi_mod = the detection module + * @par proto = the ID of the protocol + * @return the string name of the breed ID + * + */ int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_mod, char *proto); + + + /** + * Write the list of the supported protocols + * + * @par ndpi_mod = the detection module + */ void ndpi_dump_protocols(struct ndpi_detection_module_struct *mod); - int matchStringProtocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - char *string_to_match, u_int string_to_match_len); + + /** + * Read a file and load the protocols + * + * Format: <tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto> + * + * Example: + * tcp:80,tcp:3128@HTTP + * udp:139@NETBIOS + * + * @par ndpi_mod = the detection module + * @par path = the path of the file + * @return 0 if the file is loaded correctly; + * -1 else + * + */ int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path); + + + /** + * Get the total number of the supported protocols + * + * @par ndpi_mod = the detection module + * @return the number of protocols + * + */ u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_mod); + + + /** + * Get the nDPI version release + * + * @return the NDPI_GIT_RELEASE + * + */ char* ndpi_revision(void); - void ndpi_set_automa(struct ndpi_detection_module_struct *ndpi_struct, void* automa); -#define ADD_TO_DETECTION_BITMASK 1 -#define NO_ADD_TO_DETECTION_BITMASK 0 -#define SAVE_DETECTION_BITMASK_AS_UNKNOWN 1 -#define NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN 0 /** - * This function sets a single protocol bitmask - * @param label Protocol name - * @param ndpi_struct the detection module - * @param detection_bitmask the protocol bitmask - * @param idx the index of the callback_buffer - * @param func void function point of the protocol search - * @param ndpi_selection_bitmask the protocol selected bitmask - * @param b_save_bitmask_unknow set true if you want save the detection bitmask as unknow - * @param b_add_detection_bitmask set true if you want add the protocol bitmask to the detection bitmask - * NB: this function does not increment the index of the callback_buffer - */ - void ndpi_set_bitmask_protocol_detection(char * label, struct ndpi_detection_module_struct *ndpi_struct, - const NDPI_PROTOCOL_BITMASK * detection_bitmask, - const u_int32_t idx, - u_int16_t ndpi_protocol_id, - void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow), - const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask, - u_int8_t b_save_bitmask_unknow, - u_int8_t b_add_detection_bitmask); + * Set the automa for the protocol search + * + * @par ndpi_struct = the detection module + * @par automa = the automa to match + * + */ + void ndpi_set_automa(struct ndpi_detection_module_struct *ndpi_struct, void* automa); + #ifdef NDPI_PROTOCOL_HTTP - /* - API used to retrieve information for HTTP flows + /** + * Retrieve information for HTTP flows + * + * @par ndpi_mod = the detection module + * @par flow = the detected flow + * @return the HTTP method information about the flow + * */ - ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod, - struct ndpi_flow_struct *flow); - - char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod, - struct ndpi_flow_struct *flow); + ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod, struct ndpi_flow_struct *flow); + - char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod, - struct ndpi_flow_struct *flow); + /** + * Get the HTTP url + * + * @par ndpi_mod = the detection module + * @par flow = the detected flow + * @return the HTTP method information about the flow + * + */ + char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod, struct ndpi_flow_struct *flow); + + + /** + * Get the HTTP content-type + * + * @par ndpi_mod = the detection module + * @par flow = the detected flow + * @return the HTTP method information about the flow + * + */ + char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod, struct ndpi_flow_struct *flow); #endif + #ifdef NDPI_PROTOCOL_TOR + /** + * Check if the flow could be detected as TOR protocol + * + * @par ndpi_struct = the detection module + * @par flow = the detected flow + * @par certificate = the ssl certificate + * @return 1 if the flow is TOR; + * 0 else + * + */ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *certificate); #endif diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h index 266c76968..3fa0b34e6 100644 --- a/src/include/ndpi_define.h +++ b/src/include/ndpi_define.h @@ -156,7 +156,6 @@ /* misc definitions */ #define NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE 0x10000 -#define NDPI_ENABLE_DEBUG_MESSAGES 1 /* TODO: rebuild all memory areas to have a more aligned memory block here */ diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h index 7dcd86528..59707896b 100644 --- a/src/include/ndpi_protocol_ids.h +++ b/src/include/ndpi_protocol_ids.h @@ -49,14 +49,14 @@ #define NDPI_PROTOCOL_IP_ICMPV6 102 #define NDPI_PROTOCOL_HTTP 7 -#define NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV 60 +#define NDPI_PROTOCOL_HTTP_DOWNLOAD 60 #define NDPI_PROTOCOL_SSL_NO_CERT 64 /* SSL without certificate (Skype, Ultrasurf?) - ntop.org */ #define NDPI_PROTOCOL_SSL 91 #define NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC 110 #define NDPI_PROTOCOL_HTTP_CONNECT 130 #define NDPI_PROTOCOL_HTTP_PROXY 131 -#define NDPI_PROTOCOL_SOCKS5 172 /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_PROTOCOL_SOCKS4 173 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_PROTOCOL_SOCKS 172 /* Tomasz Bujlow <tomasz@skatnet.dk> */ + #define NDPI_PROTOCOL_FTP_CONTROL 1 /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_PROTOCOL_MAIL_POP 2 @@ -203,7 +203,7 @@ #define NDPI_PROTOCOL_TEREDO 214 #define NDPI_PROTOCOL_HEP 216 /* Sipcapture.org QXIP BV */ #define NDPI_PROTOCOL_UBNTAC2 217 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */ -#define NDPI_PROTOCOL_MS_LYNC 220 +#define NDPI_PROTOCOL_MS_LYNC 173 @@ -232,15 +232,15 @@ #define NDPI_SERVICE_APPLE_ICLOUD 143 #define NDPI_SERVICE_APPLE_ITUNES 145 #define NDPI_SERVICE_TUENTI 149 -#define NDPI_SERVICE_WIKIPEDIA 176 /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_MSN NDPI_PROTOCOL_MSN /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_AMAZON 178 /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_EBAY 179 /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_CNN 180 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_WIKIPEDIA 176 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_MSN NDPI_PROTOCOL_MSN /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_AMAZON 178 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_EBAY 179 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_CNN 180 /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_SERVICE_DROPBOX NDPI_PROTOCOL_DROPBOX /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_SKYPE NDPI_PROTOCOL_SKYPE /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_VIBER NDPI_PROTOCOL_VIBER /* Tomasz Bujlow <tomasz@skatnet.dk> */ -#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_SKYPE NDPI_PROTOCOL_SKYPE /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_VIBER NDPI_PROTOCOL_VIBER +#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_SERVICE_PANDORA 187 #define NDPI_PROTOCOL_EAQ 190 #define NDPI_SERVICE_TIMMEU 191 @@ -268,8 +268,10 @@ #define NDPI_SERVICE_HOTSPOT_SHIELD 215 #define NDPI_SERVICE_OCS 218 #define NDPI_SERVICE_OFFICE_365 219 -#define NDPI_PROTOCOL_COAP 221 -#define NDPI_PROTOCOL_MQTT 222 +#define NDPI_SERVICE_CLOUDFLARE 220 +#define NDPI_SERVICE_MS_ONE_DRIVE 221 +#define NDPI_PROTOCOL_COAP 222 +#define NDPI_PROTOCOL_MQTT 223 /* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */ #define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MQTT diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index b4ca6dba2..b6ceed257 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -299,6 +299,7 @@ void init_snmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int void init_socrates_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_sopcast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_soulseek_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_spotify_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ssh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ssl_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index dcf3e0749..4fe8d5712 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -875,7 +875,7 @@ struct ndpi_flow_struct { u_int16_t protocol_stack_info; /* init parameter, internal used to set up timestamp,... */ - u_int16_t guessed_protocol_id, guessed_host_proto_id; + u_int16_t guessed_protocol_id, guessed_host_protocol_id; u_int8_t protocol_id_already_guessed:1, host_already_guessed:1, init_finished:1, setup_packet_direction:1, packet_direction:1; @@ -901,11 +901,13 @@ struct ndpi_flow_struct { */ struct ndpi_id_struct *server_id; /* HTTP host or DNS query */ - u_char host_server_name[256]; + u_char host_server_name[192]; /* Via HTTP User-Agent */ u_char detected_os[32]; /* Via HTTP X-Forwarded-For */ u_char nat_ip[24]; + /* Bittorrent hash */ + u_char bittorent_hash[20]; /* This structure below will not not stay inside the protos @@ -992,10 +994,8 @@ struct ndpi_flow_struct { #ifdef NDPI_PROTOCOL_FLORENSIA u_int32_t florensia_stage:1; #endif -#ifdef NDPI_PROTOCOL_SOCKS5 +#ifdef NDPI_PROTOCOL_SOCKS u_int32_t socks5_stage:2; // 0 - 3 -#endif -#ifdef NDPI_PROTOCOL_SOCKS4 u_int32_t socks4_stage:2; // 0 - 3 #endif #ifdef NDPI_PROTOCOL_EDONKEY @@ -1032,4 +1032,16 @@ struct ndpi_flow_struct { struct ndpi_id_struct *dst; }; +typedef struct { + char *string_to_match, *proto_name; + int protocol_id; + ndpi_protocol_breed_t protocol_breed; +} ndpi_protocol_match; + +typedef struct { + u_int32_t network; + u_int8_t cidr; + u_int8_t value; +} ndpi_network; + #endif/* __NDPI_TYPEDEFS_H__ */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b2d3e3d64..2e8b0551a 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -111,8 +111,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/skype.c \ protocols/smb.c \ protocols/snmp.c \ - protocols/socks4.c \ - protocols/socks5.c \ + protocols/socks45.c \ protocols/socrates.c \ protocols/sopcast.c \ protocols/soulseek.c \ @@ -140,7 +139,6 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/twitter.c \ protocols/ubntac2.c \ protocols/usenet.c \ - protocols/veohtv.c \ protocols/viber.c \ protocols/vhua.c \ protocols/vmware.c \ diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 74b21b536..411a3961d 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -18,23 +18,62 @@ * */ -typedef struct { - char *string_to_match, *proto_name; - int protocol_id; - ndpi_protocol_breed_t protocol_breed; -} ndpi_protocol_match; - -typedef struct { - u_int32_t network; - u_int8_t cidr; - u_int8_t value; -} ndpi_network; - /* ****************************************************** */ static ndpi_network host_protocol_list[] = { /* + Microsoft Corporation (MS One Drive) + 204.79.195.0/24 + 204.79.196.0/23 + 134.170.0.0/16 + 131.253.12.0/22 + 131.253.16.0/23 + 131.253.18.0/24 + 65.54.191.0/24 + */ + { 0xCC4FC300 /* 204.79.195.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0xCC4FC400 /* 204.79.196.0/23 */, 23, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0x86AA0000 /* 134.170.0.0/16 */, 16, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0x83FD0C00 /* 131.253.12.0/22 */, 22, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0x83FD1000 /* 131.253.16.0/23 */, 23, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0x83FD1200 /* 131.253.18.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE }, + { 0x4136BF00 /* 65.54.191.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE }, + + + /* + Amazon-EU-AWS Elastic Compute Cloud, EC2 (also used by Netflix) + 46.137.128.0/18 + */ + { 0x2E898000 /* 46.137.128.0/18 */, 18, NDPI_SERVICE_AMAZON }, + + /* + Amazon-EU (also used by Netflix) + 176.34.184.0/21 + */ + { 0xB022B800 /* 176.34.184.0/21 */, 21, NDPI_SERVICE_AMAZON }, + + /* + Netflix + 23.246.0.0/18 + 23.21.190.124/32 + */ + { 0x17F60000 /* 23.246.0.0/18 */, 18, NDPI_SERVICE_NETFLIX }, + { 0x1715BE7C /* 23.21.190.124/32 */, 32, NDPI_SERVICE_NETFLIX }, + + /* + Cloudflare + 104.16.0.0/12 + 173.245.48.0/20 + 162.158.0.0/15 + 141.101.125.0/24 CLOUDFLARE-EU CDN network + */ + { 0x68100000 /* 104.16.0.0/12 */, 12, NDPI_SERVICE_CLOUDFLARE }, + { 0xADF53000 /* 173.245.48.0/20 */, 20, NDPI_SERVICE_CLOUDFLARE }, + { 0xA29E0000 /* 162.158.0.0/15 */, 15, NDPI_SERVICE_CLOUDFLARE }, + { 0x8D657D00 /* 141.101.125.0/24 */, 24, NDPI_SERVICE_CLOUDFLARE }, + + /* OFFICE 365 13.107.1.0/24 13.107.3.0/24 @@ -81,10 +120,16 @@ static ndpi_network host_protocol_list[] = { { 0x4272A000 /* 66.114.160.0 */, 20, NDPI_PROTOCOL_WEBEX }, /* - Viber - 54.171.62.0/24 + Viber Media AWS-VIBER-MEDIA (NET-54-169-63-160-1) 54.169.63.160 - 54.169.63.191 + Viber Media S a r l AWS-VIBER-MEDIA-S-A-R-L (NET-54-93-255-64-1) 54.93.255.64 - 54.93.255.127 + Crittercism AWS-VIBER-MEDIA (NET-52-0-252-0-1) 52.0.252.0 - 52.0.255.255 + 54.169.63.160/27 + 54.93.255.64/26 + 52.0.252.0/22 */ - { 0x36AB3E00 /* 54.171.62.0 */, 24, NDPI_PROTOCOL_VIBER }, + { 0x36A93FA0 /* 54.169.63.160 */, 27, NDPI_PROTOCOL_VIBER }, + { 0x365DFF40 /* 54.93.255.64 */, 26, NDPI_PROTOCOL_VIBER }, + { 0x3400FC00 /* 52.0.252.0 */, 22, NDPI_PROTOCOL_VIBER }, /* Apple (FaceTime, iMessage,...) @@ -107,12 +152,15 @@ static ndpi_network host_protocol_list[] = { 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15 111.221.64.0 - 111.221.127.255 91.190.216.0/21 (AS198015 Skype Communications Sarl) + 40.126.129.109/32 */ { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE }, { 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE }, { 0x9D360000 /* 157.54.0.0 */, 15, NDPI_PROTOCOL_SKYPE }, { 0x6FDD4000 /* 111.221.64.0 */, 18, NDPI_PROTOCOL_SKYPE }, { 0x5BBED800 /* 91.190.216.0 */, 21, NDPI_PROTOCOL_SKYPE }, + { 0x287F816D /* 40.126.129.109 */, 32, NDPI_PROTOCOL_SKYPE }, + /* route: 5.42.160.0/19 @@ -124,10 +172,15 @@ static ndpi_network host_protocol_list[] = { /* Google 173.194.0.0/16 + 74.125.0.0/16 64.233.160.0/19 + 216.58.192.0/19 */ { 0xADC20000 /* 173.194.0.0 */, 16, NDPI_SERVICE_GOOGLE }, + { 0x4A7D0000 /* 74.125.0.0 */, 16, NDPI_SERVICE_GOOGLE }, { 0x40E91600 /* 64.233.160.0 */, 19, NDPI_SERVICE_GOOGLE }, + { 0xD83AC000 /* 216.58.192.0 */, 19, NDPI_SERVICE_GOOGLE }, + /* Ubuntu One 91.189.89.0/21 (255.255.248.0) @@ -153,155 +206,7 @@ static ndpi_network host_protocol_list[] = { { 0x959AA400 /* 149.154.164.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM}, { 0x959AA800 /* 149.154.168.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM}, - /* Skype */ - { 0x17600000, 14, NDPI_PROTOCOL_SKYPE }, - { 0x17613000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x17614000, 19, NDPI_PROTOCOL_SKYPE }, - { 0x17616000, 19, NDPI_PROTOCOL_SKYPE }, - { 0x17622000, 21, NDPI_PROTOCOL_SKYPE }, - { 0x17622800, 22, NDPI_PROTOCOL_SKYPE }, - { 0x17623800, 21, NDPI_PROTOCOL_SKYPE }, - { 0x17624000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x17640000, 15, NDPI_PROTOCOL_SKYPE }, - { 0x17660000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x17674000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x17678000, 17, NDPI_PROTOCOL_SKYPE }, - { 0x40040000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x41340000, 14, NDPI_PROTOCOL_SKYPE }, - { 0x4134A000, 19, NDPI_PROTOCOL_SKYPE }, - { 0x41362800, 24, NDPI_PROTOCOL_SKYPE }, - { 0x41364200, 23, NDPI_PROTOCOL_SKYPE }, - { 0x41364400, 24, NDPI_PROTOCOL_SKYPE }, - { 0x41365200, 24, NDPI_PROTOCOL_SKYPE }, - { 0x41365500, 24, NDPI_PROTOCOL_SKYPE }, - { 0x41365A00, 23, NDPI_PROTOCOL_SKYPE }, - { 0x41372C00, 24, NDPI_PROTOCOL_SKYPE }, - { 0x41377500, 24, NDPI_PROTOCOL_SKYPE }, - { 0x4137E600, 24, NDPI_PROTOCOL_SKYPE }, - { 0x4137E700, 24, NDPI_PROTOCOL_SKYPE }, - { 0x42779000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x46250000, 17, NDPI_PROTOCOL_SKYPE }, - { 0x46258000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x46259600, 23, NDPI_PROTOCOL_SKYPE }, - { 0x5EF54000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x5EF54C00, 23, NDPI_PROTOCOL_SKYPE }, - { 0x5EF55200, 24, NDPI_PROTOCOL_SKYPE }, - { 0x68280000, 13, NDPI_PROTOCOL_SKYPE }, - { 0x68920000, 19, NDPI_PROTOCOL_SKYPE }, - { 0x68928000, 17, NDPI_PROTOCOL_SKYPE }, - { 0x68D00000, 13, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD1000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD1000, 21, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD1700, 24, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4000, 18, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4000, 21, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4200, 24, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4500, 24, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4600, 24, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD4E00, 23, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD5000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD6000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD7000, 21, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD7800, 22, NDPI_PROTOCOL_SKYPE }, - { 0x6FDD7C00, 22, NDPI_PROTOCOL_SKYPE }, - { 0x83FD0100, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD0500, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD0600, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD0800, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD0C00, 22, NDPI_PROTOCOL_SKYPE }, - { 0x83FD1200, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD1500, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD1800, 21, NDPI_PROTOCOL_SKYPE }, - { 0x83FD2000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x83FD2100, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD2200, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD3D00, 24, NDPI_PROTOCOL_SKYPE }, - { 0x83FD3E00, 23, NDPI_PROTOCOL_SKYPE }, - { 0x83FD8000, 17, NDPI_PROTOCOL_SKYPE }, - { 0x84F50000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x84F59C00, 22, NDPI_PROTOCOL_SKYPE }, - { 0x84F5A000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x86AA0000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x86AA8000, 21, NDPI_PROTOCOL_SKYPE }, - { 0x86AA8800, 21, NDPI_PROTOCOL_SKYPE }, - { 0x86AAD900, 24, NDPI_PROTOCOL_SKYPE }, - { 0x89740000, 15, NDPI_PROTOCOL_SKYPE }, - { 0x89748000, 19, NDPI_PROTOCOL_SKYPE }, - { 0x8974A000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x89870000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x8A5B0000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x8A5B0000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x8A5B1000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x8A5B2000, 20, NDPI_PROTOCOL_SKYPE }, - { 0x9D370000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x9D380000, 16, NDPI_PROTOCOL_SKYPE }, - { 0x9D3C1700, 24, NDPI_PROTOCOL_SKYPE }, - { 0x9D3C1F00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xA7DCF000, 22, NDPI_PROTOCOL_SKYPE }, - { 0xA83D0000, 16, NDPI_PROTOCOL_SKYPE }, - { 0xA83E0000, 15, NDPI_PROTOCOL_SKYPE }, - { 0xA83F8000, 17, NDPI_PROTOCOL_SKYPE }, - { 0xBFE80000, 13, NDPI_PROTOCOL_SKYPE }, - { 0xC030E100, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC0549F00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC054A000, 23, NDPI_PROTOCOL_SKYPE }, - { 0xC0C59D00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC1954000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xC1DD7100, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC6310800, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC6C88200, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC6CEA400, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC71E1000, 20, NDPI_PROTOCOL_SKYPE }, - { 0xC73C1C00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC74AD200, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC7675A00, 23, NDPI_PROTOCOL_SKYPE }, - { 0xC7677A00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xC7F23000, 21, NDPI_PROTOCOL_SKYPE }, - { 0xCA59E000, 21, NDPI_PROTOCOL_SKYPE }, - { 0xCC4F8700, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCC4FB300, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCC4FC300, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCC4FC500, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCC4FFC00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCC5F6000, 20, NDPI_PROTOCOL_SKYPE }, - { 0xCC988C00, 23, NDPI_PROTOCOL_SKYPE }, - { 0xCE8AA800, 21, NDPI_PROTOCOL_SKYPE }, - { 0xCEBFE000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E0000, 16, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E0000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E2000, 20, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E2900, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E3000, 20, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E3A00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E3E00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E4000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E4800, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E4D00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E6000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E6200, 24, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E8000, 17, NDPI_PROTOCOL_SKYPE }, - { 0xCF2E8000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xCF2EE000, 20, NDPI_PROTOCOL_SKYPE }, - { 0xCF448000, 18, NDPI_PROTOCOL_SKYPE }, - { 0xCF52FA00, 23, NDPI_PROTOCOL_SKYPE }, - { 0xD0448800, 21, NDPI_PROTOCOL_SKYPE }, - { 0xD04C2D00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD04C2E00, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD0540000, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD0540100, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD0540200, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD0540300, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD1017000, 23, NDPI_PROTOCOL_SKYPE }, - { 0xD1B98000, 22, NDPI_PROTOCOL_SKYPE }, - { 0xD1B9F000, 22, NDPI_PROTOCOL_SKYPE }, - { 0xD1F0C000, 19, NDPI_PROTOCOL_SKYPE }, - { 0xD5C78000, 18, NDPI_PROTOCOL_SKYPE }, - { 0xD820B400, 22, NDPI_PROTOCOL_SKYPE }, - { 0xD820F000, 22, NDPI_PROTOCOL_SKYPE }, - { 0xD820F200, 24, NDPI_PROTOCOL_SKYPE }, - { 0xD821F000, 22, NDPI_PROTOCOL_SKYPE }, - { 0xD4A10800, 24, NDPI_PROTOCOL_SKYPE }, - + /* TOR */ { 0x012A1231, 32, NDPI_PROTOCOL_TOR }, { 0x01E69FA1, 32, NDPI_PROTOCOL_TOR }, { 0x020DE985, 32, NDPI_PROTOCOL_TOR }, @@ -7363,6 +7268,7 @@ ndpi_protocol_match host_match[] = { { ".ebaystratus.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".ebayimg.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, + { "fbstatic-a.akamaihd.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { ".fbcdn.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */ { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7392,11 +7298,14 @@ ndpi_protocol_match host_match[] = { { ".skypeassets.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, { ".skypedata.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, { ".skypeecs-", /* no final . */ "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".skypeforbusiness.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".lync.com", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, { ".tuenti.com", "Tuenti", NDPI_SERVICE_TUENTI, NDPI_PROTOCOL_ACCEPTABLE }, { ".twttr.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, { "twitter.", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, { "twimg.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, { ".viber.com", "Viber", NDPI_SERVICE_VIBER, NDPI_PROTOCOL_ACCEPTABLE }, + { ".cdn.viber.com", "Viber", NDPI_SERVICE_VIBER, NDPI_PROTOCOL_ACCEPTABLE }, { "wikipedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, { "wikimedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, { "mediawiki.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7450,9 +7359,14 @@ ndpi_protocol_match host_match[] = { { "tim-geoportal.geoportal3d.com.br", "TIM_PortasAbertas", NDPI_SERVICE_TIMPORTASABERTAS, NDPI_PROTOCOL_ACCEPTABLE }, { ".m4u.com.br", "TIM_Recarga", NDPI_SERVICE_TIMRECARGA, NDPI_PROTOCOL_ACCEPTABLE }, { ".deezer.com", "Deezer", NDPI_SERVICE_DEEZER, NDPI_PROTOCOL_ACCEPTABLE }, + { ".microsoft.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, + { "bn1301.storage.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, + { "skyapi.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, + { "d.docs.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, { "update.microsoft.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, { ".windowsupdate.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, + { "worldofwarcraft.com", "WorldOfWarcraft", NDPI_PROTOCOL_WORLDOFWARCRAFT, NDPI_PROTOCOL_FUN }, { ".anchorfree.", "HotspotShield", NDPI_SERVICE_HOTSPOT_SHIELD, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, { "hotspotshield.com", "HotspotShield", NDPI_SERVICE_HOTSPOT_SHIELD, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, @@ -7462,20 +7376,27 @@ ndpi_protocol_match host_match[] = { { ".ocs.fr", "OCS", NDPI_SERVICE_OCS, NDPI_PROTOCOL_FUN }, { ".labgency.ws", "OCS", NDPI_SERVICE_OCS, NDPI_PROTOCOL_FUN }, - { "crl.microsoft.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { "evsecure-ocsp.verisign.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { "evsecure-aia.verisign.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { "evsecure-crl.verisign.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { "sa.symcb.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { "sd.symcb.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".omniroot.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".verisign.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".symcb.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".symcd.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".verisign.net", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".geotrust.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".entrust.net", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".public-trust.com", "OFFICE_365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "crl.microsoft.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "evsecure-ocsp.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "evsecure-aia.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "evsecure-crl.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "sa.symcb.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { "sd.symcb.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".omniroot.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".symcb.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".symcd.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".verisign.net", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".geotrust.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".entrust.net", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".public-trust.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + + /* http://www.urlquery.net/report.php?id=1453233646161 */ + { "lifedom.top", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, + { "coby.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, + { "amanda.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, + + { NULL, 0 } }; @@ -7522,6 +7443,18 @@ ndpi_protocol_match content_match[] = { { "video/webm", NULL, NDPI_CONTENT_WEBM, NDPI_PROTOCOL_FUN }, { "application/x-rtsp-tunnelled", NULL, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_FUN }, { "application/vnd.apple.mpegurl", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "application/x-tar", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "application/octet-stream", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "application/mac-binary", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "/x-bzip", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "/x-gzip", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "/x-zip", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "/zip", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "binhex", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "/base64", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "application/gnutar", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { "application/x-compressed", NULL, NDPI_PROTOCOL_HTTP_DOWNLOAD, NDPI_PROTOCOL_ACCEPTABLE }, + { NULL, 0 } }; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 8fa52fc77..8d40fe9aa 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -38,6 +38,25 @@ #include "third_party/include/ndpi_patricia.h" #include "third_party/src/ndpi_patricia.c" + +/* implementation of the punycode check function */ +int check_punycode_string(char * buffer , int len) +{ + int i = 0; + + while(i++ < len) + { + if( buffer[i] == 'x' && + buffer[i+1] == 'n' && + buffer[i+2] == '-' && + buffer[i+3] == '-' ) + // is a punycode string + return 1; + } + // not a punycode string + return 0; +} + /* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */ /* find or insert datum into search tree */ void * @@ -306,7 +325,7 @@ void* ndpi_calloc(unsigned long count, size_t size) { /* ****************************************** */ -void ndpi_free(void *ptr) { _ndpi_free(ptr); } +void ndpi_free(void *ptr) { _ndpi_free(ptr); } /* ****************************************** */ @@ -577,30 +596,36 @@ static int ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct /* ******************************************************************** */ -static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_mod) { - int i; +void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, + ndpi_protocol_match *match) { + u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }; + ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; - for(i=0; host_match[i].string_to_match != NULL; i++) { - u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }; - ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; + ndpi_add_host_url_subprotocol(ndpi_mod, match->string_to_match, + match->protocol_id, match->protocol_breed); - ndpi_add_host_url_subprotocol(ndpi_mod, host_match[i].string_to_match, - host_match[i].protocol_id, host_match[i].protocol_breed); + if(ndpi_mod->proto_defaults[match->protocol_id].protoName == NULL) { + ndpi_mod->proto_defaults[match->protocol_id].protoName = ndpi_strdup(match->proto_name); + ndpi_mod->proto_defaults[match->protocol_id].protoId = match->protocol_id; + ndpi_mod->proto_defaults[match->protocol_id].protoBreed = match->protocol_breed; + } - if(ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName == NULL) { - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName = ndpi_strdup(host_match[i].proto_name); - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId = host_match[i].protocol_id; - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed = host_match[i].protocol_breed; - } + ndpi_set_proto_defaults(ndpi_mod, + ndpi_mod->proto_defaults[match->protocol_id].protoBreed, + ndpi_mod->proto_defaults[match->protocol_id].protoId, + no_master, no_master, + ndpi_mod->proto_defaults[match->protocol_id].protoName, + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); +} - ndpi_set_proto_defaults(ndpi_mod, - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed, - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId, - no_master, no_master, - ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName, - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); - } +/* ******************************************************************** */ + +static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_mod) { + int i; + + for(i=0; host_match[i].string_to_match != NULL; i++) + ndpi_init_protocol_match(ndpi_mod, &host_match[i]); #ifdef DEBUG ac_automata_display(ndpi_mod->host_automa.ac_automa, 'n'); @@ -842,7 +867,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BITTORRENT, no_master, no_master, "BitTorrent", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_a, 51413, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 6771, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEREDO, no_master, @@ -954,9 +979,9 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "TVUplayer", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); - ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HTTP_DOWNLOAD, no_master, - no_master, "HTTP_APPLICATION_VEOHTV", + no_master, "HTTPDownload", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQLIVE, @@ -1137,11 +1162,6 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "IAX", ndpi_build_default_ports(ports_a, 4569, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 4569, 0, 0, 0, 0) /* UDP */); - ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP, - no_master, - no_master, "TFTP", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AFP, no_master, no_master, "AFP", @@ -1160,8 +1180,8 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SIP, no_master, no_master, "SIP", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 5060, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 5060, 5061, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 5060, 5061, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TRUPHONE, no_master, no_master, "TruPhone", @@ -1443,16 +1463,16 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "Collectd", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0) /* UDP */); - ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS5, + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS, no_master, - no_master, "SOCKS5", + no_master, "SOCKS", ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0) /* UDP */); - ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS4, + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP, no_master, - no_master, "SOCKS4", + no_master, "TFTP", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP, no_master, no_master, "RTMP", @@ -1476,28 +1496,33 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ, no_master, no_master, "ZeroMQ", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) ); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_VHUA, no_master, no_master, "VHUA", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 58267, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 58267, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_STARCRAFT, no_master, no_master, "Starcraft", - ndpi_build_default_ports(ports_a, 1119, 0, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 1119, 0, 0, 0, 0)); /* UDP */ + ndpi_build_default_ports(ports_a, 1119, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 1119, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_UBNTAC2, no_master, no_master, "UBNTAC2", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MS_LYNC, no_master, no_master, "Lync", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER, + no_master, + no_master, "Viber", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 7985, 7987, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_COAP, no_master, no_master, "COAP", @@ -1565,13 +1590,13 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str /* ******************************************* */ -u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host /* network byte order */) { - struct in_addr pin; +/* u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host /\* network byte order *\/) { */ +/* struct in_addr pin; */ - pin.s_addr = host; +/* pin.s_addr = host; */ - return(ndpi_network_ptree_match(ndpi_struct, &pin)); -} +/* return(ndpi_network_ptree_match(ndpi_struct, &pin)); */ +/* } */ /* ******************************************* */ @@ -1635,7 +1660,7 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp struct in_addr pin; int bits = 32; char *ptr = strrchr(value, '/'); - + if (ptr) { ptr[0] = '\0'; @@ -1643,12 +1668,12 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp if (atoi(ptr)>=0 && atoi(ptr)<=32) bits = atoi(ptr); } - + inet_pton(AF_INET, value, &pin); - + if((node = add_to_ptree(ndpi_struct->protocols_ptree, AF_INET, &pin, bits)) != NULL) node->value.user_value = protocol_id; - + return 0; } @@ -1865,7 +1890,7 @@ char * strsep(char **sp, char *sep) int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, u_int8_t do_add) { - + char *at, *proto, *elem; ndpi_proto_defaults_t *def; int subprotocol_id, i; @@ -1980,7 +2005,7 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, */ int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path) { - + FILE *fd = fopen(path, "r"); int i; @@ -2133,6 +2158,9 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* SOULSEEK */ init_soulseek_dissector(ndpi_struct, &a, detection_bitmask); + /* SOCKS */ + init_socks_dissector(ndpi_struct, &a, detection_bitmask); + /* IRC */ init_irc_dissector(ndpi_struct, &a, detection_bitmask); @@ -2277,9 +2305,6 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* SHOUTCAST */ init_shoutcast_dissector(ndpi_struct, &a, detection_bitmask); - /* VEOHTV */ - init_veohtv_dissector(ndpi_struct, &a, detection_bitmask); - /* KERBEROS */ init_kerberos_dissector(ndpi_struct, &a, detection_bitmask); @@ -3022,7 +3047,7 @@ void check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_struct, } for(a = 0; a < ndpi_struct->callback_buffer_size_udp; a++) { - if((func != ndpi_struct->callback_buffer_tcp_payload[a].func) + if((func != ndpi_struct->callback_buffer_udp[a].func) && (ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) == ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, @@ -3129,7 +3154,7 @@ void check_ndpi_flow_func(struct ndpi_detection_module_struct *ndpi_struct, ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const struct ndpi_iphdr *iph, - struct ndpi_ipv6hdr *iph6, + struct ndpi_ipv6hdr *iph6, struct ndpi_tcphdr *tcp, struct ndpi_udphdr *udp, u_int8_t src_to_dst_direction, @@ -3147,7 +3172,7 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru flow->packet.tcp = tcp, flow->packet.udp = udp; flow->packet.payload = payload, flow->packet.payload_packet_len = payload_len; - + if(src_to_dst_direction) flow->src = src, flow->dst = dst; else @@ -3171,11 +3196,6 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru if(flow->packet.payload_packet_len != 0) { ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD; - - if(!flow->protocol_id_already_guessed) { - flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, l4_proto, sport, dport); - flow->protocol_id_already_guessed = 1; - } } if(flow->packet.tcp_retransmission == 0) @@ -3188,40 +3208,54 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru a = flow->packet.detected_protocol_stack[0]; if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, a) == 0) a = NDPI_PROTOCOL_UNKNOWN; - + if(a != NDPI_PROTOCOL_UNKNOWN) { int i; for(i=0; (i<sizeof(flow->host_server_name)) && (flow->host_server_name[i] != '\0'); i++) flow->host_server_name[i] = tolower(flow->host_server_name[i]); - + flow->host_server_name[i] ='\0'; } ret_protocols: if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) { ret.master_protocol = flow->detected_protocol_stack[1], ret.protocol = flow->detected_protocol_stack[0]; - + if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; } else ret.protocol = flow->detected_protocol_stack[0]; - if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) - && flow->packet.iph - && (!flow->host_already_guessed)) { - - if((flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, - (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) { - flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); + return(ret); +} + +/* ********************************************************************************* */ + +ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; + + if(flow == NULL) return(ret); + + /* TODO: add the remaining stage_XXXX protocols */ + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + if(flow->http_detected) + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN); + else if((flow->packet.l4_protocol == IPPROTO_TCP) && (flow->l4.tcp.ssl_stage > 1)) { + if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) + ndpi_int_change_protocol(ndpi_struct, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_SSL); + else + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL, NDPI_PROTOCOL_UNKNOWN); + } else { + flow->detected_protocol_stack[1] = flow->guessed_protocol_id, flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id; + + if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) + flow->detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; } - - flow->host_already_guessed = 1; } - if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) - ret.protocol = flow->guessed_host_proto_id; - + ret.master_protocol = flow->detected_protocol_stack[1], ret.protocol = flow->detected_protocol_stack[0]; return(ret); } @@ -3303,6 +3337,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct u_int8_t protocol; u_int32_t saddr, daddr; + flow->protocol_id_already_guessed = 1; + #ifdef NDPI_DETECTION_SUPPORT_IPV6 if(flow->packet.iphv6 != NULL) { protocol = flow->packet.iphv6->ip6_ctlun.ip6_un1.ip6_un1_nxt, saddr = 0, daddr = 0; @@ -3319,11 +3355,10 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct else sport = dport = 0; flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport); - flow->protocol_id_already_guessed = 1; - if((protocol != IPPROTO_TCP) && (protocol != IPPROTO_UDP)) { - flow->detected_protocol_stack[0] = flow->guessed_protocol_id; - goto ret_protocols; + if(flow->packet.iph) { + if((flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) + flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); } } @@ -3351,20 +3386,6 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct } else ret.protocol = flow->detected_protocol_stack[0]; - if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) - && flow->packet.iph - && (!flow->host_already_guessed)) { - - if((flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) { - flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); - } - - flow->host_already_guessed = 1; - } - - if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) - ret.protocol = flow->guessed_host_proto_id; - return(ret); } @@ -3906,27 +3927,27 @@ void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_s packet->detected_protocol_stack[0] = upper_detected_protocol, packet->detected_protocol_stack[1] = lower_detected_protocol; } -/* - * this function checks whether a protocol can be found in the - * history. Actually it accesses the packet stack since this is what - * leaves the library but it could also use the flow stack. - */ -u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct * ndpi_struct, - struct ndpi_flow_struct *flow, - u_int16_t protocol_id) { - u_int8_t a; - struct ndpi_packet_struct *packet = &flow->packet; +/* /\* */ +/* * this function checks whether a protocol can be found in the */ +/* * history. Actually it accesses the packet stack since this is what */ +/* * leaves the library but it could also use the flow stack. */ +/* *\/ */ +/* u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct * ndpi_struct, */ +/* struct ndpi_flow_struct *flow, */ +/* u_int16_t protocol_id) { */ +/* u_int8_t a; */ +/* struct ndpi_packet_struct *packet = &flow->packet; */ - if(!packet) - return 0; +/* if(!packet) */ +/* return 0; */ - for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) { - if(packet->detected_protocol_stack[a] == protocol_id) - return 1; - } +/* for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) { */ +/* if(packet->detected_protocol_stack[a] == protocol_id) */ +/* return 1; */ +/* } */ - return 0; -} +/* return 0; */ +/* } */ /* generic function for changing the protocol * @@ -3938,6 +3959,9 @@ void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) { + if(upper_detected_protocol == lower_detected_protocol) + lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN; + ndpi_int_change_flow_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol); ndpi_int_change_packet_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol); } @@ -4128,7 +4152,7 @@ u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_ch /* ****************************************************** */ ndpi_protocol ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct /* NOTUSED */, - u_int8_t proto, + /* u_int8_t proto, */ u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport) { ndpi_protocol p = NDPI_PROTOCOL_NULL; @@ -4188,7 +4212,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct return(ret); } - ret = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport); + ret = ndpi_find_port_based_protocol(ndpi_struct/* , proto */, shost, sport, dhost, dport); if(ret.protocol != NDPI_PROTOCOL_UNKNOWN) return(ret); @@ -4323,10 +4347,11 @@ char* ndpi_strnstr(const char *s, const char *find, size_t slen) { /* ****************************************************** */ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, - char *string_to_match, u_int string_to_match_len) { + char *string_to_match, u_int string_to_match_len, + u_int8_t is_host_match) { int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN; AC_TEXT_t ac_input_text; - ndpi_automa *automa = &ndpi_struct->host_automa; + ndpi_automa *automa = is_host_match ? &ndpi_struct->host_automa : &ndpi_struct->content_automa; if((automa->ac_automa == NULL) || (string_to_match_len == 0)) return(NDPI_PROTOCOL_UNKNOWN); @@ -4347,8 +4372,9 @@ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_stru static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len, - u_int16_t master_protocol_id) { - int matching_protocol_id = ndpi_match_string_subprotocol(ndpi_struct, string_to_match, string_to_match_len); + u_int16_t master_protocol_id, + u_int8_t is_host_match) { + int matching_protocol_id = ndpi_match_string_subprotocol(ndpi_struct, string_to_match, string_to_match_len, is_host_match); struct ndpi_packet_struct *packet = &flow->packet; AC_TEXT_t ac_input_text; @@ -4360,7 +4386,7 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str strncpy(m, string_to_match, len); m[len] = '\0'; - printf("[NDPI] ndpi_match_host_subprotocol(%s): %s\n", + printf("[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m, ndpi_struct->proto_defaults[matching_protocol_id].protoName); } #endif @@ -4392,7 +4418,7 @@ int ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_struct u_int16_t master_protocol_id) { return(ndpi_automa_match_string_subprotocol(ndpi_struct, flow, string_to_match, string_to_match_len, - master_protocol_id)); + master_protocol_id, 1)); } /* ****************************************************** */ @@ -4403,7 +4429,7 @@ int ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str u_int16_t master_protocol_id) { return(ndpi_automa_match_string_subprotocol(ndpi_struct, flow, string_to_match, string_to_match_len, - master_protocol_id)); + master_protocol_id, 0)); } /* ****************************************************** */ diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 99420b85e..8213d3b45 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -25,15 +25,53 @@ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_BITTORRENT -#define NDPI_PROTOCOL_UNSAFE_DETECTION 0 -#define NDPI_PROTOCOL_SAFE_DETECTION 1 +#define NDPI_PROTOCOL_UNSAFE_DETECTION 0 +#define NDPI_PROTOCOL_SAFE_DETECTION 1 + +#define NDPI_PROTOCOL_PLAIN_DETECTION 0 +#define NDPI_PROTOCOL_WEBSEED_DETECTION 2 + + +struct ndpi_utp_hdr { + u_int8_t h_version:4, h_type:4, next_extension; + u_int16_t connection_id; + u_int32_t ts_usec, tdiff_usec, window_size; + u_int16_t sequence_nr, ack_nr; +}; + +static u_int8_t is_utp_pkt(const u_int8_t *payload, u_int payload_len) { + struct ndpi_utp_hdr *h = (struct ndpi_utp_hdr*)payload; + + if(payload_len < sizeof(struct ndpi_utp_hdr)) return(0); + if(h->h_version != 1) return(0); + if(h->h_type > 4) return(0); + if(h->next_extension > 2) return(0); + if(ntohl(h->window_size) > 65565) return(0); + + return(1); +} -#define NDPI_PROTOCOL_PLAIN_DETECTION 0 -#define NDPI_PROTOCOL_WEBSEED_DETECTION 2 static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + int bt_offset, int check_hash, const u_int8_t save_detection, const u_int8_t encrypted_connection/* , */ /* ndpi_protocol_type_t protocol_type */) { + if(check_hash) { + const char *bt_hash = NULL; /* 20 bytes long */ + const char *peer_id = NULL; /* 20 bytes long */ + + if(bt_offset == -1) { + const char *bt_magic = ndpi_strnstr((const char *)flow->packet.payload, + "BitTorrent protocol", flow->packet.payload_packet_len); + + if(bt_magic) + bt_hash = &bt_magic[19], peer_id = &bt_magic[39]; + } else + bt_hash = (const char*)&flow->packet.payload[28], peer_id = (const char*)&flow->packet.payload[48]; + + if(bt_hash) memcpy(flow->bittorent_hash, bt_hash, 20); + } + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN); } @@ -43,61 +81,57 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module struct ndpi_packet_struct *packet = &flow->packet; u_int16_t a = 0; - if (packet->payload_packet_len == 1 && packet->payload[0] == 0x13) { + if(packet->payload_packet_len == 1 && packet->payload[0] == 0x13) { /* reset stage back to 0 so we will see the next packet here too */ flow->bittorrent_stage = 0; return 0; } - if (flow->packet_counter == 2 && packet->payload_packet_len > 20) { - if (memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) { + if(flow->packet_counter == 2 && packet->payload_packet_len > 20) { + if(memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 19, 1, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ /* NDPI_REAL_PROTOCOL */); return 1; } } - - if (packet->payload_packet_len > 20) { + if(packet->payload_packet_len > 20) { /* test for match 0x13+"BitTorrent protocol" */ - if (packet->payload[0] == 0x13) { - if (memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) { - NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, - ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); + if(packet->payload[0] == 0x13) { + if(memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 20, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; } } } - if (packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) { + if(packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain webseed BitTorrent protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } /* seen Azureus as server for webseed, possibly other servers existing, to implement */ /* is Server: hypertracker Bittorrent? */ /* no asymmetric detection possible for answer of pattern "GET /data?fid=". */ - if (packet->payload_packet_len > 60 + if(packet->payload_packet_len > 60 && memcmp(packet->payload, "GET /data?fid=", 14) == 0 && memcmp(&packet->payload[54], "&size=", 6) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ /* NDPI_CORRELATED_PROTOCOL */); return 1; } - if (packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0 + if(packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0 || memcmp(packet->payload, "POST ", 5) == 0)) { const u_int8_t *ptr = &packet->payload[4]; u_int16_t len = packet->payload_packet_len - 4; @@ -107,32 +141,30 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module /* parse complete get packet here into line structure elements */ ndpi_parse_packet_line_info(ndpi_struct, flow); /* answer to this pattern is HTTP....Server: hypertracker */ - if (packet->user_agent_line.ptr != NULL + if(packet->user_agent_line.ptr != NULL && ((packet->user_agent_line.len > 8 && memcmp(packet->user_agent_line.ptr, "Azureus ", 8) == 0) || (packet->user_agent_line.len >= 10 && memcmp(packet->user_agent_line.ptr, "BitTorrent", 10) == 0) || (packet->user_agent_line.len >= 11 && memcmp(packet->user_agent_line.ptr, "BTWebClient", 11) == 0))) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Azureus /Bittorrent user agent line detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } - if (packet->user_agent_line.ptr != NULL - && (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0) - && (packet->parsed_lines > 8 && packet->line[8].ptr != 0 - && packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) { + if(packet->user_agent_line.ptr != NULL + && (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0) + && (packet->parsed_lines > 8 && packet->line[8].ptr != 0 + && packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bittorrent Shareaza detected.\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } /* this is a self built client, not possible to catch asymmetrically */ - if ((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0)) + if((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0)) && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 12 && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 ", @@ -160,15 +192,13 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module && packet->line[8].len > 22 && memcmp(packet->line[8].ptr, "Cache-Control: no-cache", 23) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bitcomet LTS detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; - } /* FlashGet pattern */ - if (packet->parsed_lines == 8 + if(packet->parsed_lines == 8 && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", @@ -187,13 +217,12 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module && packet->line[6].len > 21 && memcmp(packet->line[6].ptr, "Connection: Keep-Alive", 22) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; - } - if (packet->parsed_lines == 7 + + if(packet->parsed_lines == 7 && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", @@ -209,19 +238,17 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module && packet->line[5].len > 21 && memcmp(packet->line[5].ptr, "Connection: Keep-Alive", 22) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; - } /* answer to this pattern is not possible to implement asymmetrically */ while (1) { - if (len < 50 || ptr[0] == 0x0d) { + if(len < 50 || ptr[0] == 0x0d) { goto ndpi_end_bt_tracker_check; } - if (memcmp(ptr, "info_hash=", 10) == 0) { + if(memcmp(ptr, "info_hash=", 10) == 0) { break; } len--; @@ -237,40 +264,40 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module /* parse bt hash */ for (a = 0; a < 20; a++) { - if (len < 3) { + if(len < 3) { goto ndpi_end_bt_tracker_check; } - if (*ptr == '%') { + if(*ptr == '%') { u_int8_t x1 = 0xFF; u_int8_t x2 = 0xFF; - if (ptr[1] >= '0' && ptr[1] <= '9') { + if(ptr[1] >= '0' && ptr[1] <= '9') { x1 = ptr[1] - '0'; } - if (ptr[1] >= 'a' && ptr[1] <= 'f') { + if(ptr[1] >= 'a' && ptr[1] <= 'f') { x1 = 10 + ptr[1] - 'a'; } - if (ptr[1] >= 'A' && ptr[1] <= 'F') { + if(ptr[1] >= 'A' && ptr[1] <= 'F') { x1 = 10 + ptr[1] - 'A'; } - if (ptr[2] >= '0' && ptr[2] <= '9') { + if(ptr[2] >= '0' && ptr[2] <= '9') { x2 = ptr[2] - '0'; } - if (ptr[2] >= 'a' && ptr[2] <= 'f') { + if(ptr[2] >= 'a' && ptr[2] <= 'f') { x2 = 10 + ptr[2] - 'a'; } - if (ptr[2] >= 'A' && ptr[2] <= 'F') { + if(ptr[2] >= 'A' && ptr[2] <= 'F') { x2 = 10 + ptr[2] - 'A'; } - if (x1 == 0xFF || x2 == 0xFF) { + if(x1 == 0xFF || x2 == 0xFF) { goto ndpi_end_bt_tracker_check; } ptr += 3; len -= 3; - } else if (*ptr >= 32 && *ptr < 127) { + } else if(*ptr >= 32 && *ptr < 127) { ptr++; len--; } else { @@ -280,15 +307,14 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, " BT stat: tracker info hash parsed\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; } ndpi_end_bt_tracker_check: - if (packet->payload_packet_len == 80) { + if(packet->payload_packet_len == 80) { /* Warez 80 Bytes Packet * +----------------+---------------+-----------------+-----------------+ * |20 BytesPattern | 32 Bytes Value| 12 BytesPattern | 16 Bytes Data | @@ -306,30 +332,28 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module }; /* did not see this pattern anywhere */ - if ((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0) + if((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0) && (memcmp(&packet->payload[52], pattern_12_bytes, 12) == 0)) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; } } - else if (packet->payload_packet_len > 50) { - if (memcmp(packet->payload, "GET", 3) == 0) { + else if(packet->payload_packet_len > 50) { + if(memcmp(packet->payload, "GET", 3) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); /* haven't fount this pattern anywhere */ - if (packet->host_line.ptr != NULL + if(packet->host_line.ptr != NULL && packet->host_line.len >= 9 && memcmp(packet->host_line.ptr, "ip2p.com:", 9) == 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected due to Host: ip2p.com: pattern\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } } @@ -341,17 +365,16 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module /*Search for BitTorrent commands*/ static void ndpi_int_search_bittorrent_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; - if (packet->payload_packet_len == 0) { + if(packet->payload_packet_len == 0) { return; } - if (flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) { + if(flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) { /* exclude stage 0 detection from next run */ flow->bittorrent_stage = 1; - if (ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) { + if(ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) { NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG, "stage 0 has detected something, returning\n"); return; @@ -367,6 +390,7 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st { struct ndpi_packet_struct *packet = &flow->packet; int no_bittorrent = 0; + char *bt_proto = NULL; /* This is broadcast */ if(packet->iph @@ -378,10 +402,10 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st return; } - if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) { + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) { /* check for tcp retransmission here */ - if ((packet->tcp != NULL) + if((packet->tcp != NULL) && (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) { ndpi_int_search_bittorrent_tcp(ndpi_struct, flow); } @@ -400,9 +424,8 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st if(packet->payload_packet_len >= 23 /* min header size */) { if(strncmp((const char*)packet->payload, bt_search, strlen(bt_search)) == 0) { - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return; } else { /* Check if this is protocol v0 */ @@ -414,27 +437,31 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st u_int8_t v1_extension = packet->payload[1]; u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]); - if((packet->payload[0]== 0x60) + if(is_utp_pkt(packet->payload, packet->payload_packet_len)) + goto bittorrent_found; + else if((packet->payload[0]== 0x60) && (packet->payload[1]== 0x0) && (packet->payload[2]== 0x0) && (packet->payload[3]== 0x0) && (packet->payload[4]== 0x0)) { /* Heuristic */ + bt_proto = ndpi_strnstr((const char *)&packet->payload[20], "BitTorrent protocol", packet->payload_packet_len-20); goto bittorrent_found; } else if(((v1_version & 0x0f) == 1) && ((v1_version >> 4) < 5 /* ST_NUM_STATES */) && (v1_extension < 3 /* EXT_NUM_EXT */) && (v1_window_size < 32768 /* 32k */) ) { + bt_proto = ndpi_strnstr((const char *)&packet->payload[20], "BitTorrent protocol", packet->payload_packet_len-20); goto bittorrent_found; - } else if((v0_flags < 6 /* ST_NUM_STATES */) - && (v0_extension < 3 /* EXT_NUM_EXT */)) { + } else if((v0_flags < 6 /* ST_NUM_STATES */) && (v0_extension < 3 /* EXT_NUM_EXT */)) { u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4]))); u_int32_t now; now = (u_int32_t)time(NULL); if((ts < (now+86400)) && (ts > (now-86400))) { + bt_proto = ndpi_strnstr((const char *)&packet->payload[20], "BitTorrent protocol", packet->payload_packet_len-20); goto bittorrent_found; } } @@ -444,24 +471,28 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st flow->bittorrent_stage++; if(flow->bittorrent_stage < 10) { - if(packet->payload_packet_len > 19 /* min size */) { - if(ndpi_strnstr((const char *)packet->payload, ":target20:", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, ":find_node1:", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, "d1:ad2:id20:", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, ":info_hash20:", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, ":filter64", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, "d1:rd2:id20:", packet->payload_packet_len) - || ndpi_strnstr((const char *)packet->payload, "BitTorrent protocol", packet->payload_packet_len) - ) { - bittorrent_found: - NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, - ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); - ndpi_add_connection_as_bittorrent(ndpi_struct, flow, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); - return; - } - } + /* We have detected bittorrent but we need to wait until we get a hash */ + + if(packet->payload_packet_len > 19 /* min size */) { + if(ndpi_strnstr((const char *)packet->payload, ":target20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":find_node1:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, "d1:ad2:id20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":info_hash20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":filter64", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, "d1:rd2:id20:", packet->payload_packet_len) + || (bt_proto = ndpi_strnstr((const char *)packet->payload, "BitTorrent protocol", packet->payload_packet_len)) + ) { + bittorrent_found: + if(bt_proto && (packet->payload_packet_len > 47)) + memcpy(flow->bittorent_hash, &bt_proto[27], 20); + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, + ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 0, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); + return; + } + } return; } diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index cb78c9429..8ffc04d51 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -35,27 +35,27 @@ static void ndpi_int_dhcp_add_connection(struct ndpi_detection_module_struct *nd void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_packet_struct *packet = &flow->packet; -// struct ndpi_id_struct *src=ndpi_struct->src; -// struct ndpi_id_struct *dst=ndpi_struct->dst; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; - /* this detection also works for asymmetric dhcp traffic */ + /* this detection also works for asymmetric dhcp traffic */ - /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */ - if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67) - || packet->udp->source == htons(68)) - && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) - && get_u_int32_t(packet->payload, 236) == htonl(0x63825363) - && get_u_int16_t(packet->payload, 240) == htons(0x3501)) { + /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */ + if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67) + || packet->udp->source == htons(68)) + && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) + && get_u_int32_t(packet->payload, 236) == htonl(0x63825363) + && get_u_int16_t(packet->payload, 240) == htons(0x3501)) { - NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); + NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); - ndpi_int_dhcp_add_connection(ndpi_struct, flow); - return; - } + ndpi_int_dhcp_add_connection(ndpi_struct, flow); + return; + } - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP); } diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 8749f4d5e..c975465ea 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -60,43 +60,46 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd if((s_port == 53 || d_port == 53 || d_port == 5355) && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header))) { - struct ndpi_dns_packet_header *dns_header = (struct ndpi_dns_packet_header*) &flow->packet.payload[x]; + struct ndpi_dns_packet_header dns_header; int invalid = 0; - dns_header->tr_id = ntohs(dns_header->tr_id); - dns_header->flags = ntohs(dns_header->flags); - dns_header->num_queries = ntohs(dns_header->num_queries); - dns_header->num_answers = ntohs(dns_header->num_answers); - dns_header->authority_rrs = ntohs(dns_header->authority_rrs); - dns_header->additional_rrs = ntohs(dns_header->additional_rrs); + memcpy(&dns_header, (struct ndpi_dns_packet_header*) &flow->packet.payload[x], sizeof(struct ndpi_dns_packet_header)); + dns_header.tr_id = ntohs(dns_header.tr_id); + dns_header.flags = ntohs(dns_header.flags); + dns_header.num_queries = ntohs(dns_header.num_queries); + dns_header.num_answers = ntohs(dns_header.num_answers); + dns_header.authority_rrs = ntohs(dns_header.authority_rrs); + dns_header.additional_rrs = ntohs(dns_header.additional_rrs); /* 0x0000 QUERY */ - if((dns_header->flags & FLAGS_MASK) == 0x0000) + if((dns_header.flags & FLAGS_MASK) == 0x0000) is_query = 1; /* 0x8000 RESPONSE */ - else if((dns_header->flags & FLAGS_MASK) != 0x8000) + else if((dns_header.flags & FLAGS_MASK) != 0x8000) is_query = 0; else invalid = 1; - if(is_query) { - /* DNS Request */ - if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) - && (((dns_header->flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) - || ((dns_header->num_answers == 0) && (dns_header->authority_rrs == 0)))) { - /* This is a good query */ - } else - invalid = 1; - } else { - /* DNS Reply */ - if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ - && (((dns_header->num_answers > 0) && (dns_header->num_answers <= NDPI_MAX_DNS_REQUESTS)) - || ((dns_header->authority_rrs > 0) && (dns_header->authority_rrs <= NDPI_MAX_DNS_REQUESTS)) - || ((dns_header->additional_rrs > 0) && (dns_header->additional_rrs <= NDPI_MAX_DNS_REQUESTS))) - ) { - /* This is a good reply */ - } else - invalid = 1; + if(!invalid) { + if(is_query) { + /* DNS Request */ + if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) + && (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) + || ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) { + /* This is a good query */ + } else + invalid = 1; + } else { + /* DNS Reply */ + if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ + && (((dns_header.num_answers > 0) && (dns_header.num_answers <= NDPI_MAX_DNS_REQUESTS)) + || ((dns_header.authority_rrs > 0) && (dns_header.authority_rrs <= NDPI_MAX_DNS_REQUESTS)) + || ((dns_header.additional_rrs > 0) && (dns_header.additional_rrs <= NDPI_MAX_DNS_REQUESTS))) + ) { + /* This is a good reply */ + } else + invalid = 1; + } } if(invalid) { @@ -106,7 +109,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd } /* extract host name server */ - ret_code = (is_query == 0) ? 0 : (dns_header->flags & 0x0F); + ret_code = (is_query == 0) ? 0 : (dns_header.flags & 0x0F); int j = 0; int off = sizeof(struct ndpi_dns_packet_header) + 1; while((flow->packet.payload[off] != '\0')) @@ -119,7 +122,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd } flow->host_server_name[j] = '\0'; - flow->protos.dns.num_answers = (u_int8_t) (dns_header->num_answers + dns_header->authority_rrs + dns_header->additional_rrs); + flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs); flow->protos.dns.ret_code = ret_code; if(j > 0) diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index ced34c099..caac7390b 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -37,18 +37,14 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd /* If no custom protocol has been detected */ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { - if(protocol != NDPI_PROTOCOL_HTTP) { - ndpi_search_tcp_or_udp(ndpi_struct, flow); - ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); - } else { + if(protocol == NDPI_PROTOCOL_HTTP) ndpi_int_reset_protocol(flow); - ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); - } + + ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } flow->http_detected = 1; } - } #ifdef NDPI_CONTENT_FLASH @@ -202,21 +198,14 @@ static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struc /* NOTE - + If http_dont_dissect_response = 1 dissection of HTTP response mime types won't happen - */ - - if(!ndpi_struct->http_dont_dissect_response) { - if(flow->http.url && flow->http_detected) - ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)&flow->http.url[7], - strlen((const char *)&flow->http.url[7]), - NDPI_PROTOCOL_HTTP); - } else - ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, - strlen((const char *)flow->host_server_name), - NDPI_PROTOCOL_HTTP); - } + */ + ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, + strlen((const char *)flow->host_server_name), + NDPI_PROTOCOL_HTTP); + } } /* diff --git a/src/lib/protocols/sip.c b/src/lib/protocols/sip.c index 3d79561ac..94386d61e 100644 --- a/src/lib/protocols/sip.c +++ b/src/lib/protocols/sip.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * + * */ @@ -31,7 +31,7 @@ static void ndpi_int_sip_add_connection(struct ndpi_detection_module_struct *ndp u_int8_t due_to_correlation) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SIP, NDPI_PROTOCOL_UNKNOWN); } - + #if !defined(WIN32) static inline #else @@ -41,7 +41,7 @@ void ndpi_search_sip_handshake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; - + // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; const u_int8_t *packet_payload = packet->payload; @@ -92,7 +92,7 @@ void ndpi_search_sip_handshake(struct ndpi_detection_module_struct * maybe it could be deleted, if somebody sees it in the first direction, * please delete this comment. */ - + /* if (memcmp(packet_payload, "SIP/2.0 200 OK", 14) == 0 || memcmp(packet_payload, "sip/2.0 200 OK", 14) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 0K.\n"); @@ -121,7 +121,7 @@ void ndpi_search_sip_handshake(struct ndpi_detection_module_struct } if ((memcmp(packet_payload, "CANCEL ", 7) == 0 || memcmp(packet_payload, "cancel ", 7) == 0) - && (memcmp(&packet_payload[4], "SIP:", 7) == 0 || memcmp(&packet_payload[4], "sip:", 7) == 0)) { + && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip CANCEL.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; diff --git a/src/lib/protocols/socks4.c b/src/lib/protocols/socks4.c deleted file mode 100644 index 87bc3a634..000000000 --- a/src/lib/protocols/socks4.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * socks4.c - * - * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> - * - * The signature is based on the Libprotoident library. - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#include "ndpi_api.h" - -#ifdef NDPI_PROTOCOL_SOCKS4 -static void ndpi_int_socks4_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS4, NDPI_PROTOCOL_UNKNOWN); -} - -static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - u_int32_t payload_len = packet->payload_packet_len; - - /* Break after 20 packets. */ - if (flow->packet_counter > 20) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS4.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS4); - return; - } - - /* Check if we so far detected the protocol in the request or not. */ - if (flow->socks4_stage == 0) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage 0: \n"); - - /*Octets 3 and 4 contain the port number, port 80 and 25 for now. */ - if ((payload_len == 9) && - (((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x50)) - || - ((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x19)))) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS4 request detected, we will look further for the response...\n"); - - /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->socks4_stage = packet->packet_direction + 1; - } - - } else { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage %u: \n", flow->socks4_stage); - - /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ - if ((flow->socks4_stage - packet->packet_direction) == 1) { - return; - } - - /* This is a packet in another direction. Check if we find the proper response. */ - if (payload_len == 0) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS4.\n"); - ndpi_int_socks4_add_connection(ndpi_struct, flow); - } else { - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS4, resetting the stage to 0...\n"); - flow->socks4_stage = 0; - } - - } -} - -void ndpi_search_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - - NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 detection...\n"); - - /* skip marked packets */ - if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS4) { - if (packet->tcp_retransmission == 0) { - ndpi_check_socks4(ndpi_struct, flow); - } - } -} - -#endif diff --git a/src/lib/protocols/socks45.c b/src/lib/protocols/socks45.c new file mode 100644 index 000000000..7ad0868d2 --- /dev/null +++ b/src/lib/protocols/socks45.c @@ -0,0 +1,155 @@ +/* + * socks4.c + * + * Copyright (C) 2016 - ntop.org + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SOCKS +static void ndpi_int_socks_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS, NDPI_PROTOCOL_UNKNOWN); +} + +static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if(flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS4.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if(flow->socks4_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage 0: \n"); + + /*Octets 3 and 4 contain the port number, port 80 and 25 for now. */ + if((payload_len == 9) && + (((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x50)) + || + ((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x19)))) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS4 request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->socks4_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage %u: \n", flow->socks4_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if((flow->socks4_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if(payload_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS4.\n"); + ndpi_int_socks_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS4, resetting the stage to 0...\n"); + flow->socks4_stage = 0; + } + + } +} + +static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if(flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS5.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if(flow->socks5_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage 0: \n"); + + if((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS5 request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->socks5_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage %u: \n", flow->socks5_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if((flow->socks5_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS5.\n"); + ndpi_int_socks_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS5, resetting the stage to 0...\n"); + flow->socks5_stage = 0; + } + + } +} + +void ndpi_search_socks(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_SOCKS, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS) { + if(packet->tcp_retransmission == 0) { + ndpi_check_socks4(ndpi_struct, flow); + + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS) + ndpi_check_socks5(ndpi_struct, flow); + } + } +} + +void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("SOCKS", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_SOCKS, + ndpi_search_socks, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif diff --git a/src/lib/protocols/socks5.c b/src/lib/protocols/socks5.c deleted file mode 100644 index f7cf89dfc..000000000 --- a/src/lib/protocols/socks5.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * socks5.c - * - * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> - * - * The signature is based on the Libprotoident library. - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#include "ndpi_api.h" - -#ifdef NDPI_PROTOCOL_SOCKS5 -static void ndpi_int_socks5_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS5, NDPI_PROTOCOL_UNKNOWN); -} - -static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - u_int32_t payload_len = packet->payload_packet_len; - - /* Break after 20 packets. */ - if (flow->packet_counter > 20) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS5.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS5); - return; - } - - /* Check if we so far detected the protocol in the request or not. */ - if (flow->socks5_stage == 0) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage 0: \n"); - - if ((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS5 request detected, we will look further for the response...\n"); - - /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->socks5_stage = packet->packet_direction + 1; - } - - } else { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage %u: \n", flow->socks5_stage); - - /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ - if ((flow->socks5_stage - packet->packet_direction) == 1) { - return; - } - - /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS5.\n"); - ndpi_int_socks5_add_connection(ndpi_struct, flow); - } else { - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS5, resetting the stage to 0...\n"); - flow->socks5_stage = 0; - } - - } -} - -void ndpi_search_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - - NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 detection...\n"); - - /* skip marked packets */ - if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS5) { - if (packet->tcp_retransmission == 0) { - ndpi_check_socks5(ndpi_struct, flow); - } - } -} - -#endif diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c index bc0aa4f3c..2269ae782 100644 --- a/src/lib/protocols/ssl.c +++ b/src/lib/protocols/ssl.c @@ -92,11 +92,12 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp ((ch) >= '{' && (ch) <= '~')) static void stripCertificateTrailer(char *buffer, int buffer_len) { - int i; + + int i, is_puny; // printf("->%s<-\n", buffer); - for(i=0; i<buffer_len; i++) { + for(i = 0; i < buffer_len; i++) { // printf("%c [%d]\n", buffer[i], buffer[i]); if((buffer[i] != '.') @@ -110,21 +111,28 @@ static void stripCertificateTrailer(char *buffer, int buffer_len) { } } - if(i > 0) i--; - - while(i > 0) { - if(!ndpi_isalpha(buffer[i])) { - buffer[i] = '\0'; - buffer_len = i; - i--; - } else - break; - } - - for(i=buffer_len; i>0; i--) { - if(buffer[i] == '.') break; - else if(ndpi_isdigit(buffer[i])) - buffer[i] = '\0', buffer_len = i; + /* check for punycode encoding */ + is_puny = check_punycode_string(buffer, buffer_len); + + // not a punycode string - need more checks + if(is_puny == 0) { + + if(i > 0) i--; + + while(i > 0) { + if(!ndpi_isalpha(buffer[i])) { + buffer[i] = '\0'; + buffer_len = i; + i--; + } else + break; + } + + for(i = buffer_len; i > 0; i--) { + if(buffer[i] == '.') break; + else if(ndpi_isdigit(buffer[i])) + buffer[i] = '\0', buffer_len = i; + } } } diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index 69e1cad52..e21f9331b 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -27,7 +27,7 @@ #ifdef NDPI_PROTOCOL_STUN -#define MAX_NUM_STUN_PKTS 6 +#define MAX_NUM_STUN_PKTS 10 struct stun_packet_header { @@ -55,8 +55,13 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * u_int16_t msg_type, msg_len; struct stun_packet_header *h = (struct stun_packet_header*)payload; - if(payload_length < sizeof(struct stun_packet_header)) - return(NDPI_IS_NOT_STUN); + if(payload_length < sizeof(struct stun_packet_header)) { + if(flow->num_stun_udp_pkts > 0) { + *is_whatsapp = 1; + return NDPI_IS_STUN; /* This is WhatsApp Voice */ + } else + return(NDPI_IS_NOT_STUN); + } if((strncmp((const char*)payload, (const char*)"RSP/", 4) == 0) && (strncmp((const char*)&payload[7], (const char*)" STUN_", 6) == 0)) { @@ -215,10 +220,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * #endif - if( - ((flow->num_stun_udp_pkts > 0) && (msg_type == 0x0800)) - || ((msg_type == 0x0800) && (msg_len == 106)) - ) { + if((flow->num_stun_udp_pkts > 0) && (msg_type <= 0x00FF)) { *is_whatsapp = 1; return NDPI_IS_STUN; /* This is WhatsApp Voice */ } else diff --git a/src/lib/protocols/tcp_udp.c b/src/lib/protocols/tcp_udp.c index 9f9febfeb..2c6792551 100644 --- a/src/lib/protocols/tcp_udp.c +++ b/src/lib/protocols/tcp_udp.c @@ -30,6 +30,7 @@ u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struc u_int16_t sport, u_int16_t dport) /* host endianess */ { u_int16_t rc; + struct in_addr host; if(protocol == IPPROTO_UDP) { if((sport == dport) && (sport == 17500)) { @@ -37,9 +38,12 @@ u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struc } } - if((rc = ndpi_host_ptree_match(ndpi_struct, htonl(saddr))) != NDPI_PROTOCOL_UNKNOWN) return(rc); - - return(ndpi_host_ptree_match(ndpi_struct, htonl(daddr))); + host.s_addr = htonl(saddr); + if((rc = ndpi_network_ptree_match(ndpi_struct, &host)) != NDPI_PROTOCOL_UNKNOWN) + return (rc); + + host.s_addr = htonl(daddr); + return (ndpi_network_ptree_match(ndpi_struct, &host)); } void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c index f2c2eae4c..f53e5da66 100644 --- a/src/lib/protocols/tor.c +++ b/src/lib/protocols/tor.c @@ -24,7 +24,7 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, if((certificate == NULL) || (strlen(certificate) < 6) - || strncmp(certificate, "www.", 4)) + || !(strncmp(certificate, "www.", 4))) return(0); // printf("***** [SSL] %s(): %s\n", __FUNCTION__, certificate); diff --git a/src/lib/protocols/veohtv.c b/src/lib/protocols/veohtv.c deleted file mode 100644 index a3ab267b9..000000000 --- a/src/lib/protocols/veohtv.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * veohtv.c - * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#include "ndpi_api.h" - - -#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV - -static void ndpi_int_veohtv_add_connection(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, NDPI_PROTOCOL_UNKNOWN); -} - -void ndpi_search_veohtv_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - -// struct ndpi_id_struct *src=ndpi_struct->src; -// struct ndpi_id_struct *dst=ndpi_struct->dst; - - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV) - return; - - if (flow->l4.tcp.veoh_tv_stage == 1 || flow->l4.tcp.veoh_tv_stage == 2) { - if (packet->packet_direction != flow->setup_packet_direction && - packet->payload_packet_len > NDPI_STATICSTRING_LEN("HTTP/1.1 20") - && memcmp(packet->payload, "HTTP/1.1 ", NDPI_STATICSTRING_LEN("HTTP/1.1 ")) == 0 && - (packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '2' || - packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '3' || - packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '4' || - packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '5')) { -#ifdef NDPI_CONTENT_FLASH - ndpi_parse_packet_line_info(ndpi_struct, flow); - if (packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH && - packet->server_line.ptr != NULL && - packet->server_line.len > NDPI_STATICSTRING_LEN("Veoh-") && - memcmp(packet->server_line.ptr, "Veoh-", NDPI_STATICSTRING_LEN("Veoh-")) == 0) { - NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); - ndpi_int_veohtv_add_connection(ndpi_struct, flow); - return; - } -#endif - if (flow->l4.tcp.veoh_tv_stage == 2) { - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, - NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); - return; - } - NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); - ndpi_int_veohtv_add_connection(ndpi_struct, flow); - return; - } else if (flow->packet_direction_counter[(flow->setup_packet_direction == 1) ? 0 : 1] > 3) { - if (flow->l4.tcp.veoh_tv_stage == 2) { - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, - NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); - return; - } - NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); - ndpi_int_veohtv_add_connection(ndpi_struct, flow); - return; - } else { - if (flow->packet_counter > 10) { - if (flow->l4.tcp.veoh_tv_stage == 2) { - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, - NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); - return; - } - NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); - ndpi_int_veohtv_add_connection(ndpi_struct, flow); - return; - } - return; - } - } else if (packet->udp) { - /* UDP packets from Veoh Client Player - * - * packet starts with 16 byte random? value - * then a 4 byte mode value - * values between 21 and 26 has been seen - * then a 4 byte counter */ - - if (packet->payload_packet_len == 28 && - get_u_int32_t(packet->payload, 16) == htonl(0x00000021) && - get_u_int32_t(packet->payload, 20) == htonl(0x00000000) && get_u_int32_t(packet->payload, 24) == htonl(0x01040000)) { - NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "UDP VeohTV found.\n"); - ndpi_int_veohtv_add_connection(ndpi_struct, flow); - return; - } - } - - - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); -} - - -void init_veohtv_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) -{ - ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_VEOHTV", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, - ndpi_search_veohtv_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - -#endif |