diff options
Diffstat (limited to 'src')
48 files changed, 2006 insertions, 1040 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index a07c96e63..737e29cb9 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -115,22 +115,14 @@ extern "C" { * */ void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_match *match); - /** * 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), - void (*__ndpi_free)(void *ptr), - ndpi_debug_function_ptr ndpi_debug_printf); - + struct ndpi_detection_module_struct *ndpi_init_detection_module(); /** * Frees the memory allocated in the specified flow @@ -157,10 +149,9 @@ extern "C" { * 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); /** @@ -233,6 +224,52 @@ extern "C" { struct ndpi_id_struct *src, struct ndpi_id_struct *dst); + + /** + * Processes one packet of L4 and returns the ID of the detected protocol. + * L3 and L4 packet headers are passed in the arguments while payload + * points to the L4 body. + * This function mimics ndpi_detection_process_packet behaviour. + * + * @par ndpi_struct = the detection module + * @par flow = pointer to the connection state machine + * @par iph = IP packet header for IPv4 or NULL + * @par iph6 = IP packet header for IPv6 or NULL + * @par tcp = TCP packet header for TCP or NULL + * @par udp = UDP packet header for UDP or NULL + * @par src_to_dst_direction = order of src/dst state machines in a flow. + * @par l4_proto = L4 protocol of the packet. + * @par src = pointer to the source subscriber state machine + * @par dst = pointer to the destination subscriber state machine + * @par sport = source port of L4 packet, used for protocol guessing. + * @par dport = destination port of L4 packet, used for protocol guessing. + * @par current_tick_l = the current timestamp for the packet + * @par payload = unsigned char pointer to the Layer 4 (TCP/UDP body) + * @par payload_len = the length of the payload + * @return the detected ID of the protocol + * + * NOTE: in a current implementation flow->src and flow->dst are swapped with + * the src_to_dst_direction flag while ndpi_detection_process_packet does not swap + * these values. + * + */ + +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_tcphdr *tcp, + struct ndpi_udphdr *udp, + u_int8_t src_to_dst_direction, + u_int8_t l4_proto, + struct ndpi_id_struct *src, + u_int16_t sport, + struct ndpi_id_struct *dst, + u_int16_t dport, + const u_int64_t current_tick_l, + u_int8_t *payload, u_int16_t payload_len); + + /** * Get the main protocol of the passed flows for the detected module @@ -544,6 +581,61 @@ extern "C" { struct ndpi_flow_struct *flow, char *certificate); #endif + /* Wrappers functions */ + /** + * Init Aho-Corasick automata + * + * @return The requested automata, or NULL if an error occurred + * + */ + void* ndpi_init_automa(); + + + /** + * Free Aho-Corasick automata allocated with ndpi_init_automa(); + * + * @par The automata initialized with ndpi_init_automa(); + * + */ + void ndpi_free_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of no error, or -1 if an error occurred. + * + */ + int ndpi_add_string_to_automa(void *_automa, char *str); + + + /** + * Finalize the automa (necessary before start searching) + * + * @par The automata initialized with ndpi_init_automa(); + * + */ + void ndpi_finalize_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of match, or -1 if no match, or -2 if an error occurred. + * + */ + int ndpi_match_string(void *_automa, char *string_to_match); + + + /* Utility functions to set ndpi malloc/free/print wrappers */ + void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)); + void set_ndpi_free(void (*__ndpi_free)(void *ptr)); + void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf); + #ifdef __cplusplus } #endif diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h index 3fa0b34e6..cc237128a 100644 --- a/src/include/ndpi_define.h +++ b/src/include/ndpi_define.h @@ -1,7 +1,6 @@ /* * - * 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 @@ -77,7 +76,7 @@ #endif -#define NDPI_USE_ASYMMETRIC_DETECTION 0 +#define NDPI_USE_ASYMMETRIC_DETECTION 0 #define NDPI_SELECTION_BITMASK_PROTOCOL_SIZE u_int32_t #define NDPI_SELECTION_BITMASK_PROTOCOL_IP (1<<0) @@ -160,24 +159,24 @@ /* TODO: rebuild all memory areas to have a more aligned memory block here */ /* DEFINITION OF MAX LINE NUMBERS FOR line parse algorithm */ -#define NDPI_MAX_PARSE_LINES_PER_PACKET 64 +#define NDPI_MAX_PARSE_LINES_PER_PACKET 64 #define MAX_PACKET_COUNTER 65000 #define MAX_DEFAULT_PORTS 5 #define NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT 600 #define NDPI_IRC_CONNECTION_TIMEOUT 120 -#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60 -#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60 -#define NDPI_THUNDER_CONNECTION_TIMEOUT 30 -#define NDPI_RTSP_CONNECTION_TIMEOUT 5 -#define NDPI_TVANTS_CONNECTION_TIMEOUT 5 -#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1 -#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30 +#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60 +#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60 +#define NDPI_THUNDER_CONNECTION_TIMEOUT 30 +#define NDPI_RTSP_CONNECTION_TIMEOUT 5 +#define NDPI_TVANTS_CONNECTION_TIMEOUT 5 +#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1 +#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30 #define NDPI_ZATTOO_CONNECTION_TIMEOUT 120 -#define NDPI_ZATTOO_FLASH_TIMEOUT 5 -#define NDPI_JABBER_STUN_TIMEOUT 30 -#define NDPI_JABBER_FT_TIMEOUT 5 +#define NDPI_ZATTOO_FLASH_TIMEOUT 5 +#define NDPI_JABBER_STUN_TIMEOUT 30 +#define NDPI_JABBER_FT_TIMEOUT 5 #define NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT 600 #ifdef NDPI_ENABLE_DEBUG_MESSAGES diff --git a/src/include/ndpi_includes.h b/src/include/ndpi_includes.h index ce36a25f9..f77f8cfc4 100644 --- a/src/include/ndpi_includes.h +++ b/src/include/ndpi_includes.h @@ -1,7 +1,7 @@ /* * ndpi_includes.h * - * Copyright (C) 2011-15 - ntop.org + * 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 @@ -35,6 +35,7 @@ #ifdef WIN32 #include "ndpi_win32.h" #else +#include <sys/types.h> #include <sys/param.h> #include <pthread.h> #include <arpa/inet.h> diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h index a70f35c8d..43bd4e2bb 100644 --- a/src/include/ndpi_main.h +++ b/src/include/ndpi_main.h @@ -1,8 +1,7 @@ /* * ndpi_main.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,79 +31,99 @@ #include "ndpi_protocols.h" #include "ndpi_api.h" +#ifdef __cplusplus +extern "C" { +#endif -void *ndpi_tdelete(const void * __restrict, void ** __restrict, - int (*)(const void *, const void *)); -void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *)); -void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *)); -void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data); -void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)); + void *ndpi_tdelete(const void * __restrict, void ** __restrict, + int (*)(const void *, const void *)); + void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *)); + void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *)); + void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data); + void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)); -int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b); -int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a); -void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a); + int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b); + int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a); + void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a); -extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, - u_int32_t net, - u_int32_t num_bits); + extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, + u_int32_t net, + u_int32_t num_bits); -extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, - u_int32_t net, u_int32_t num_bits); + extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, + u_int32_t net, u_int32_t num_bits); -u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -void ndpi_set_detected_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); + void ndpi_set_detected_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); -extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter); + extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter); -extern void ndpi_int_change_packet_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); -extern 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); -extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId, - u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName, - ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts); + extern void ndpi_int_change_packet_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); + extern 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); + extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId, + u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName, + ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts); -extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet); -extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow); + extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet); + extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow); -extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); -extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); -extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); -extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); + extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); + extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); + extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); + extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); -extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip); -extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet); -extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id); + extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip); + extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet); + extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id); + u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name); -extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int16_t sport, u_int16_t dport); + extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport, + u_int8_t *user_defined_proto); -extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto); + extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto); -extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p); -extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id, - u_int16_t** tcp_master_proto, - u_int16_t** udp_master_proto); + extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p); + extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id, + u_int16_t** tcp_master_proto, + u_int16_t** udp_master_proto); #ifdef NDPI_ENABLE_DEBUG_MESSAGES -void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct, - const char **file, const char **func, u_int32_t * line); + void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct, + const char **file, const char **func, u_int32_t * line); +#endif + + /** Checks when the @p payload starts with the string literal @p str. + * When the string is larger than the payload, check fails. + * @return non-zero if check succeeded + */ + int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len, + const char *str, size_t str_len); + + /* version of ndpi_match_prefix with string literal */ +#define ndpi_match_strprefix(payload, payload_len, str) \ + ndpi_match_prefix((payload), (payload_len), (str), (sizeof(str)-1)) + +#ifdef __cplusplus +} #endif #endif /* __NDPI_MAIN_H__ */ diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h index cfc0ad56d..e4d40e9bb 100644 --- a/src/include/ndpi_protocol_ids.h +++ b/src/include/ndpi_protocol_ids.h @@ -1,8 +1,7 @@ /* * ndpi_protocol_ids.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - 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 @@ -199,10 +198,10 @@ #define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa <g.costa@xplico.org> */ #define NDPI_PROTOCOL_QUIC 188 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> - Michele Campus <michelecampus5@gmail.com> */ #define NDPI_PROTOCOL_WHATSAPP_VOICE 189 -#define NDPI_PROTOCOL_STARCRAFT 213 /* Matteo Bracci <matteobracci1@gmail.com> */ -#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_STARCRAFT 211 /* Matteo Bracci <matteobracci1@gmail.com> */ +#define NDPI_PROTOCOL_TEREDO 212 +#define NDPI_PROTOCOL_HEP 213 /* Sipcapture.org QXIP BV */ +#define NDPI_PROTOCOL_UBNTAC2 214 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */ #define NDPI_PROTOCOL_MS_LYNC 173 @@ -243,36 +242,32 @@ #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 -#define NDPI_SERVICE_TORCEDOR 192 +#define NDPI_PROTOCOL_GIT 191 +#define NDPI_PROTOCOL_DRDA 192 #define NDPI_SERVICE_KAKAOTALK 193 /* KakaoTalk Chat (no voice call) */ #define NDPI_SERVICE_KAKAOTALK_VOICE 194 /* KakaoTalk Voice */ #define NDPI_SERVICE_TWITCH 195 /* Edoardo Dominici <edoaramis@gmail.com> */ #define NDPI_SERVICE_QUICKPLAY 196 /* Streaming service used by various services such as hooq.tv */ -#define NDPI_SERVICE_TIM 197 /* Traffic for tim.com.br and tim.it */ +#define NDPI_SERVICE_OPENDNS 197 #define NDPI_PROTOCOL_MPEGTS 198 #define NDPI_SERVICE_SNAPCHAT 199 -#define NDPI_SERVICE_SIMET 200 -#define NDPI_SERVICE_OPENSIGNAL 201 -#define NDPI_SERVICE_99TAXI 202 -#define NDPI_SERVICE_EASYTAXI 203 -#define NDPI_SERVICE_GLOBOTV 204 -#define NDPI_SERVICE_TIMSOMDECHAMADA 205 -#define NDPI_SERVICE_TIMMENU 206 -#define NDPI_SERVICE_TIMPORTASABERTAS 207 -#define NDPI_SERVICE_TIMRECARGA 208 -#define NDPI_SERVICE_TIMBETA 209 -#define NDPI_SERVICE_DEEZER 210 -#define NDPI_SERVICE_INSTAGRAM 211 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */ -#define NDPI_SERVICE_MICROSOFT 212 -#define NDPI_SERVICE_HOTSPOT_SHIELD 215 -#define NDPI_SERVICE_OCS 218 -#define NDPI_SERVICE_OFFICE_365 219 -#define NDPI_SERVICE_CLOUDFLARE 220 -#define NDPI_SERVICE_MS_ONE_DRIVE 221 -#define NDPI_PROTOCOL_MQTT 222 +#define NDPI_SERVICE_DEEZER 200 +#define NDPI_SERVICE_INSTAGRAM 201 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */ +#define NDPI_SERVICE_MICROSOFT 202 +#define NDPI_SERVICE_HOTSPOT_SHIELD 203 +#define NDPI_SERVICE_OCS 204 +#define NDPI_SERVICE_OFFICE_365 205 +#define NDPI_SERVICE_CLOUDFLARE 206 +#define NDPI_SERVICE_MS_ONE_DRIVE 207 +#define NDPI_PROTOCOL_MQTT 208 +#define NDPI_PROTOCOL_RX 209 +#define NDPI_SERVICE_WEIBO 210 +#define NDPI_SERVICE_HANGOUT 215 +#define NDPI_SERVICE_SLACK 216 +#define NDPI_SERVICE_HOTMAIL 217 + /* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */ -#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MQTT +#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_SERVICE_HOTMAIL #define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1) #define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL) diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index b5df1c937..12f3a0dbd 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -1,8 +1,7 @@ /* * ndpi_protocols.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 @@ -53,10 +52,6 @@ void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, st /* Applications and other protocols. */ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -void ndpi_bittorrent_init(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t size,u_int32_t timeout); -void ndpi_bittorrent_done(struct ndpi_detection_module_struct *ndpi_struct); -int ndpi_bittorrent_gc(struct hash_ip4p_table *ht,int key,time_t now); - void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -198,6 +193,9 @@ void ndpi_search_starcraft(struct ndpi_detection_module_struct *ndpi_struct, str void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); /* --- INIT FUNCTIONS --- */ void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_aimini_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); @@ -337,4 +335,8 @@ void init_stracraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_coap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct,u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); #endif /* __NDPI_PROTOCOLS_H__ */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index ed74b9a07..9a50b65fd 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1,8 +1,7 @@ /* * ndpi_typedefs.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - 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 @@ -555,7 +554,7 @@ struct ndpi_flow_tcp_struct { u_int32_t mail_pop_stage:2; #endif #ifdef NDPI_PROTOCOL_MAIL_IMAP - u_int32_t mail_imap_stage:3; + u_int32_t mail_imap_stage:3, mail_imap_starttls:2; #endif #ifdef NDPI_PROTOCOL_SKYPE u_int8_t skype_packet_id; @@ -622,6 +621,10 @@ struct ndpi_flow_udp_struct { u_int8_t eaq_pkt_id; u_int32_t eaq_sequence; #endif +#ifdef NDPI_PROTOCOL_RX + u_int32_t rx_conn_epoch; + u_int32_t rx_conn_id; +#endif } #ifndef WIN32 __attribute__ ((__packed__)) @@ -734,6 +737,7 @@ typedef struct ndpi_proto_defaults { typedef struct ndpi_default_ports_tree_node { ndpi_proto_defaults_t *proto; + u_int8_t customUserProto; u_int16_t default_port; } ndpi_default_ports_tree_node_t; @@ -749,7 +753,7 @@ typedef struct ndpi_proto { #define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN } struct ndpi_detection_module_struct { - + NDPI_PROTOCOL_BITMASK detection_bitmask; NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask; @@ -802,7 +806,7 @@ struct ndpi_detection_module_struct { content_automa, /* Used for HTTP subprotocol_detection */ subprotocol_automa, /* Used for HTTP subprotocol_detection */ bigrams_automa, impossible_bigrams_automa; /* TOR */ - + /* IP-based protocol detection */ void *protocols_ptree; @@ -846,8 +850,8 @@ struct ndpi_detection_module_struct { ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS]; - u_int8_t http_dont_dissect_response:1; - u_int8_t direction_detect_disable:1; /* disable internal detection of packet direction */ + u_int8_t http_dont_dissect_response:1, dns_dissect_response:1, + direction_detect_disable:1; /* disable internal detection of packet direction */ }; struct ndpi_flow_struct { @@ -908,10 +912,10 @@ struct ndpi_flow_struct { /* the only fields useful for nDPI and ntopng */ struct { - u_int8_t num_answers, ret_code; - u_int16_t query_type; + u_int8_t num_queries, num_answers, reply_code; + u_int16_t query_type, query_class, rsp_type; } dns; - + struct { u_int8_t request_code; u_int8_t version; @@ -1002,6 +1006,10 @@ struct ndpi_flow_struct { #ifdef NDPI_PROTOCOL_STARCRAFT u_int32_t starcraft_udp_stage : 3; // 0-7 #endif +#ifdef NDPI_PROTOCOL_OPENVPN + u_int8_t ovpn_session_id[8]; + u_int8_t ovpn_counter; +#endif /* internal structures to save functions calls */ struct ndpi_packet_struct packet; diff --git a/src/include/ndpi_unix.h b/src/include/ndpi_unix.h index b680d3c30..6e6987bfd 100644 --- a/src/include/ndpi_unix.h +++ b/src/include/ndpi_unix.h @@ -1,8 +1,7 @@ /* * ndpi_unix.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 diff --git a/src/include/ndpi_win32.h b/src/include/ndpi_win32.h index 645c022e5..876e59c05 100644 --- a/src/include/ndpi_win32.h +++ b/src/include/ndpi_win32.h @@ -1,8 +1,7 @@ /* * ndpi_win32.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 diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index abda7ede1..b920d4d67 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -26,6 +26,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/bittorrent.c \ protocols/ciscovpn.c \ protocols/citrix.c \ + protocols/coap.c \ protocols/collectd.c \ protocols/corba.c \ protocols/crossfire.c \ @@ -36,6 +37,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/directdownloadlink.c \ protocols/dns.c \ protocols/dofus.c \ + protocols/drda.c \ protocols/dropbox.c \ protocols/eaq.c \ protocols/edonkey.c \ @@ -45,9 +47,11 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/florensia.c \ protocols/ftp_control.c \ protocols/ftp_data.c \ + protocols/git.c \ protocols/gnutella.c \ protocols/gtp.c \ protocols/guildwars.c \ + protocols/hangout.c \ protocols/h323.c \ protocols/halflife2_and_mods.c \ protocols/hep.c \ @@ -74,6 +78,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/mgcp.c \ protocols/mms.c \ protocols/mpegts.c \ + protocols/mqtt.c \ protocols/msn.c \ protocols/mssql.c \ protocols/mysql.c \ @@ -104,6 +109,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/rtmp.c \ protocols/rtp.c \ protocols/rtsp.c \ + protocols/rx.c \ protocols/sflow.c \ protocols/shoutcast.c \ protocols/sip.c \ @@ -152,12 +158,13 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/yahoo.c \ protocols/zattoo.c \ protocols/zeromq.c \ - protocols/coap.c \ - protocols/mqtt.c \ third_party/include/actypes.h \ third_party/include/ahocorasick.h \ + third_party/include/ndpi_patricia.h \ third_party/include/node.h \ third_party/include/sort.h \ third_party/src/ahocorasick.c \ third_party/src/node.c \ third_party/src/sort.c + +EXTRA_DIST = third_party/src/ndpi_patricia.c diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 915df390f..fc5c35029 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -1,7 +1,7 @@ /* * ndpi_content_match.c * - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2011-16 - ntop.org * * 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 @@ -22,7 +22,13 @@ static ndpi_network host_protocol_list[] = { - /* + /* + OpenDNS + 208.67.216.0/21 + */ + { 0xD043D800 /* 208.67.216.0/21 */, 21, NDPI_SERVICE_OPENDNS }, + + /* Microsoft Corporation (MS One Drive) 204.79.195.0/24 204.79.196.0/23 @@ -40,7 +46,6 @@ static ndpi_network host_protocol_list[] = { { 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 @@ -149,17 +154,29 @@ static ndpi_network host_protocol_list[] = { /* Skype (Microsoft CDN) - 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15 + 157.56.135.64/26, 157.56.185.0/26, 157.56.52.0/26, + 157.56.53.128/25, 157.56.198.0/26 + 157.60.0.0/16, 157.54.0.0/15 + 13.107.3.128/32 + 13.107.3.129/32 111.221.64.0 - 111.221.127.255 91.190.216.0/21 (AS198015 Skype Communications Sarl) 40.126.129.109/32 + 65.55.223.0/26 */ - { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE }, + { 0x9D388740 /* 157.56.135.64 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D38B900 /* 157.56.185.0 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D383400 /* 157.56.52.0 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D383580 /* 157.56.53.128 */, 25, NDPI_PROTOCOL_SKYPE }, + { 0x9D38C600 /* 157.56.198.0 */, 26, NDPI_PROTOCOL_SKYPE }, { 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE }, { 0x9D360000 /* 157.54.0.0 */, 15, NDPI_PROTOCOL_SKYPE }, + { 0x0D6B0380 /* 13.107.3.128 */, 32, NDPI_PROTOCOL_SKYPE }, + { 0x0D6B0381 /* 13.107.3.129 */, 32, 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 }, + { 0x4237DF00 /* 65.55.223.0 */, 26, NDPI_PROTOCOL_SKYPE }, /* @@ -7226,9 +7243,6 @@ static ndpi_network host_protocol_list[] = { { 0xC709F98C, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9C5, 32, NDPI_SERVICE_TWITCH }, - /* Simet - 200.160.4.0/24 */ - { 0xC8A00400, 24, NDPI_SERVICE_SIMET }, - /* AnchorFree (Hotspot Shield) AnchorFree Inc. AFNETWORK-1 (NET-74-115-0-0-1) 74.115.0.0 - 74.115.7.255 @@ -7253,6 +7267,7 @@ ndpi_protocol_match host_match[] = { { "images-amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { "amazonaws.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { "amazon-adsystem.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { ".cloudfront.net", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { ".apple.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".mzstatic.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".icloud.com", "AppleiCloud", NDPI_SERVICE_APPLE_ICLOUD, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7268,10 +7283,11 @@ ndpi_protocol_match host_match[] = { { ".ebayrtm.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".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 }, + { "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 */ + { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */ + { ".facebook.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".gstatic.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".googlesyndication.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7284,10 +7300,12 @@ ndpi_protocol_match host_match[] = { { "googleadservices.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "googleapis.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "ggpht.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "1e100.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "maps.google.", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, { "maps.gstatic.com", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, { ".gmail.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, { "mail.google.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, + { "mail.outlook.com", "Hotmail", NDPI_SERVICE_HOTMAIL, NDPI_PROTOCOL_SAFE }, { ".last.fm", "LastFM", NDPI_SERVICE_LASTFM, NDPI_PROTOCOL_FUN }, { "msn.com", "MSN", NDPI_SERVICE_MSN, NDPI_PROTOCOL_FUN }, { "netflix.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, @@ -7316,6 +7334,7 @@ ndpi_protocol_match host_match[] = { { ".yimg.com", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, { "yahooapis.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, { "youtube.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { "yt3.ggpht.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { ".googlevideo.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { ".ytimg.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { "youtube-nocookie.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, @@ -7323,16 +7342,18 @@ ndpi_protocol_match host_match[] = { { ".spotify.", "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_FUN }, { ".pandora.com", "Pandora", NDPI_SERVICE_PANDORA, NDPI_PROTOCOL_FUN }, { ".torproject.org", "Tor", NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, - { "appmeutim.tim.com.br", "TIM_Meu", NDPI_SERVICE_TIMMEU, NDPI_PROTOCOL_ACCEPTABLE }, - { ".timtorcedor.com.br", "Torcedor", NDPI_SERVICE_TORCEDOR, NDPI_PROTOCOL_ACCEPTABLE }, { ".kakao.com", "KakaoTalk", NDPI_SERVICE_KAKAOTALK, NDPI_PROTOCOL_FUN }, { "ttvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "static-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "www-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "quickplay.com", "QuickPlay", NDPI_SERVICE_QUICKPLAY, NDPI_PROTOCOL_FUN }, - { "tim.com.br", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, - { "tim.it", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, { ".qq.com", "QQ", NDPI_PROTOCOL_QQ, NDPI_PROTOCOL_FUN }, + { ".weibo.com", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sinaimg.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sinajs.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sina.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sina.com.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + /* https://support.cipafilter.com/index.php?/Knowledgebase/Article/View/117/0/snapchat---how-to-block */ { "feelinsonice.appspot.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN }, @@ -7348,17 +7369,6 @@ ndpi_protocol_match host_match[] = { { "instagramstatic-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { ".waze.com", "Waze", NDPI_SERVICE_WAZE, NDPI_PROTOCOL_ACCEPTABLE }, - { "simet-", "Simet", NDPI_SERVICE_SIMET, NDPI_PROTOCOL_ACCEPTABLE }, - { "opensignal.com", "OpenSignal", NDPI_SERVICE_OPENSIGNAL, NDPI_PROTOCOL_ACCEPTABLE }, - { "99taxis.com", "99Taxi", NDPI_SERVICE_99TAXI, NDPI_PROTOCOL_ACCEPTABLE }, - { "easytaxis.com", "EasyTaxi", NDPI_SERVICE_EASYTAXI, NDPI_PROTOCOL_ACCEPTABLE }, - { ".globo.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, - { ".glbimg.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, - { "timsomdechamada.com.br", "SomDeChamada", NDPI_SERVICE_TIMSOMDECHAMADA, NDPI_PROTOCOL_ACCEPTABLE }, - { ".tim.acotelbr.com.br", "TIM_Menu", NDPI_SERVICE_TIMMENU, NDPI_PROTOCOL_ACCEPTABLE }, - { ".timbeta.com.br", "TIM_Beta", NDPI_SERVICE_TIMBETA, NDPI_PROTOCOL_ACCEPTABLE }, - { "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 }, @@ -7368,6 +7378,7 @@ ndpi_protocol_match host_match[] = { { ".msecnd.net", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, { ".visualstudio.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, { "bn1301.storage.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, + { "*.gateway.messenger.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 }, @@ -7386,7 +7397,7 @@ ndpi_protocol_match host_match[] = { { "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 }, - { ".omniroot.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 }, @@ -7400,7 +7411,20 @@ ndpi_protocol_match host_match[] = { { "coby.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, { "amanda.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, + { "d295hzzivaok4k.cloudfront.net", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE }, + { ".opendns.com", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE }, + /* https://get.slack.help/hc/en-us/articles/205138367-Troubleshooting-Slack-connection-issues */ + { "slack.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-msgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-files.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-imgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-edge.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-core.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-redir.net", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + /* Detected "slack-assets2.s3-us-west-2.amazonaws.com.". Omitted "*amazonaws.com" CDN, but no generic pattern to use on first part */ + { "slack-assets2.s3-", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { NULL, 0 } }; @@ -7525,7 +7549,7 @@ static const char *ndpi_en_bigrams[] = { static const char *ndpi_en_impossible_bigrams[] = { "bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee", "fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk", - "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", + "jl", "jm", "jn", "jp", "jq", "jr", /* "js", */ "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", "kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii", "qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu", "qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw", @@ -7533,3 +7557,4 @@ static const char *ndpi_en_impossible_bigrams[] = { "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk", "wb", "zk", "kp", "zk", "xy", NULL }; + diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 845c56c63..4224dd2d6 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -1,8 +1,7 @@ /* * ndpi_main.c * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - 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 @@ -303,13 +302,17 @@ strncasecmp(s1, s2, n) /* Forward */ static void addDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); + ndpi_proto_defaults_t *def, + u_int8_t customUserProto, + ndpi_default_ports_tree_node_t **root); + static int removeDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); + ndpi_proto_defaults_t *def, + ndpi_default_ports_tree_node_t **root); /* ****************************************** */ -void* ndpi_malloc(size_t size) { return(_ndpi_malloc(size)); } +void* ndpi_malloc(size_t size) { return(_ndpi_malloc ? _ndpi_malloc(size) : malloc(size)); } /* ****************************************** */ @@ -325,7 +328,7 @@ void* ndpi_calloc(unsigned long count, size_t size) { /* ****************************************** */ -void ndpi_free(void *ptr) { _ndpi_free(ptr); } +void ndpi_free(void *ptr) { if(_ndpi_free) _ndpi_free(ptr); else free(ptr); } /* ****************************************** */ @@ -374,6 +377,18 @@ char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int return((id >= ndpi_mod->ndpi_num_supported_protocols) ? NULL : ndpi_mod->proto_defaults[id].protoName); } +/* ****************************************************** */ + +u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name) { + u_int16_t i, num = ndpi_get_num_supported_protocols(ndpi_mod); + + for(i = 0; i < num; i++) + if(strcasecmp(ndpi_get_proto_by_id(ndpi_mod, i), name) == 0) + return(i); + + return(NDPI_PROTOCOL_UNKNOWN); +} + /* ******************************************************************** */ ndpi_port_range* ndpi_build_default_ports_range(ndpi_port_range *ports, @@ -446,8 +461,8 @@ void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t)); for(j=0; j<MAX_DEFAULT_PORTS; j++) { - if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->udpRoot); - if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot); + if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->udpRoot); + if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->tcpRoot); } } @@ -480,12 +495,12 @@ void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT wh /* ******************************************************************** */ static void addDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) { + ndpi_proto_defaults_t *def, + u_int8_t customUserProto, + ndpi_default_ports_tree_node_t **root) { ndpi_default_ports_tree_node_t *ret; u_int16_t port; - // printf("[NDPI] %s(%d)\n", __FUNCTION__, port); - for(port=range->port_low; port<=range->port_high; port++) { ndpi_default_ports_tree_node_t *node = (ndpi_default_ports_tree_node_t*)ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t)); @@ -494,11 +509,11 @@ static void addDefaultPort(ndpi_port_range *range, break; } - node->proto = def, node->default_port = port; + node->proto = def, node->default_port = port, node->customUserProto = customUserProto; ret = *(ndpi_default_ports_tree_node_t**)ndpi_tsearch(node, (void*)root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */ if(ret != node) { - printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); + /* printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); */ ret->proto = def; ndpi_free(node); @@ -551,7 +566,11 @@ static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_struc if(automa->ac_automa == NULL) return(-2); ac_pattern.astring = value; ac_pattern.rep.number = protocol_id; - ac_pattern.length = strlen(ac_pattern.astring); + if(value == NULL) + ac_pattern.length = 0; + else + ac_pattern.length = strlen(ac_pattern.astring); + ac_automata_add(((AC_AUTOMATA_t*)automa->ac_automa), &ac_pattern); return(0); @@ -1359,9 +1378,14 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC, no_master, - no_master, "Quic", + no_master, "QUIC", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX, + no_master, + no_master, "Dropbox", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EAQ, no_master, no_master, "EAQ", @@ -1451,43 +1475,43 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS, no_master, no_master, "Whois-DAS", - ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 43, 4343, 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_COLLECTD, no_master, 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_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_SOCKS, no_master, 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_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_TFTP, no_master, no_master, "TFTP", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + 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", - ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 1935, 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_PANDO, no_master, no_master, "Pando_Media_Booster", - 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_MEGACO, no_master, no_master, "Megaco", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS, no_master, no_master, "Redis", - ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 6379, 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_ZMQ, no_master, no_master, "ZeroMQ", @@ -1506,13 +1530,13 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp 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", @@ -1523,11 +1547,32 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "COAP", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ ndpi_build_default_ports(ports_b, 5683, 5684, 0, 0, 0)); /* UDP */ - ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_MQTT, - no_master, - no_master, "MQTT", - ndpi_build_default_ports(ports_a, 1883, 8883, 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_MQTT, + no_master, + no_master, "MQTT", + ndpi_build_default_ports(ports_a, 1883, 8883, 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_RX, + no_master, + no_master, "RX", + 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_GIT, + no_master, + no_master, "Git", + ndpi_build_default_ports(ports_a, 9418, 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_DRDA, + no_master, + no_master, "DRDA", + 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_SERVICE_HANGOUT, + no_master, + no_master, "GoogleHangout", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + /* calling function for host and content matched protocols */ init_string_based_protocols(ndpi_mod); @@ -1674,22 +1719,25 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp #endif -/* ******************************************************************** */ +void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)) { _ndpi_malloc = __ndpi_malloc; } -struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, - void* (*__ndpi_malloc)(size_t size), - void (*__ndpi_free)(void *ptr), - ndpi_debug_function_ptr ndpi_debug_printf) -{ - struct ndpi_detection_module_struct *ndpi_str; +void set_ndpi_free(void (*__ndpi_free)(void *ptr)) { _ndpi_free = __ndpi_free; } - _ndpi_malloc = __ndpi_malloc; - _ndpi_free = __ndpi_free; +void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf) { +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + ndpi_str->ndpi_debug_printf = ndpi_debug_printf; +#endif +} + +/* ******************************************************************** */ - ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); +struct ndpi_detection_module_struct *ndpi_init_detection_module() { + struct ndpi_detection_module_struct *ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); if(ndpi_str == NULL) { +#ifdef NDPI_ENABLE_DEBUG_MESSAGES ndpi_debug_printf(0, NULL, NDPI_LOG_DEBUG, "ndpi_init_detection_module initial malloc failed\n"); +#endif return NULL; } memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct)); @@ -1699,30 +1747,29 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ NDPI_BITMASK_RESET(ndpi_str->detection_bitmask); #ifdef NDPI_ENABLE_DEBUG_MESSAGES - ndpi_str->ndpi_debug_printf = ndpi_debug_printf; ndpi_str->user_data = NULL; #endif - ndpi_str->ticks_per_second = ticks_per_second; + ndpi_str->ticks_per_second = 1000; /* ndpi_str->ticks_per_second */ ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE; ndpi_str->directconnect_connection_ip_tick_timeout = - NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; ndpi_str->yahoo_detect_http_connections = NDPI_YAHOO_DETECT_HTTP_CONNECTIONS; - ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ticks_per_second; - ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ticks_per_second; - ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ticks_per_second; - ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second; ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS; ndpi_str->ndpi_num_custom_protocols = 0; @@ -1738,12 +1785,52 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ /* *********************************************** */ +/* Wrappers */ +void* ndpi_init_automa() { + return(ac_automata_init(ac_match_handler)); +} + +int ndpi_add_string_to_automa(void *_automa, char *str) { + AC_PATTERN_t ac_pattern; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if(automa == NULL) return(-1); + + ac_pattern.astring = str; + ac_pattern.rep.number = 1; /* Dummy */ + ac_pattern.length = strlen(ac_pattern.astring); + return(ac_automata_add(automa, &ac_pattern) == ACERR_SUCCESS ? 0 : -1); +} + +void ndpi_free_automa(void *_automa) { ac_automata_release((AC_AUTOMATA_t*)_automa); } +void ndpi_finalize_automa(void *_automa) { ac_automata_finalize((AC_AUTOMATA_t*)_automa); } + +/* ****************************************************** */ + +int ndpi_match_string(void *_automa, char *string_to_match) { + int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN; + AC_TEXT_t ac_input_text; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if((automa == NULL) + || (string_to_match == NULL) + || (string_to_match[0] == '\0')) + return(-2); + + ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match); + ac_automata_search(automa, &ac_input_text, (void*)&matching_protocol_id); + ac_automata_reset(automa); + + return(matching_protocol_id > 0 ? 0 : -1); +} + +/* *********************************************** */ + static void free_ptree_data(void *data) { ; } /* ****************************************************** */ -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) { if(ndpi_struct != NULL) { int i; @@ -1793,11 +1880,11 @@ int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_ /* ****************************************************** */ -u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int16_t sport, u_int16_t dport) { +static ndpi_default_ports_tree_node_t* ndpi_get_guessed_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport) { const void *ret; ndpi_default_ports_tree_node_t node; - + if(sport && dport) { int low = ndpi_min(sport, dport); int high = ndpi_max(sport, dport); @@ -1814,10 +1901,27 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struc ndpi_default_ports_tree_node_t_cmp); } - if(ret != NULL) { - ndpi_default_ports_tree_node_t *found = *(ndpi_default_ports_tree_node_t**)ret; + if(ret) return(*(ndpi_default_ports_tree_node_t**)ret); + } - return(found->proto->protoId); + return(NULL); +} + +/* ****************************************************** */ + +u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport, + u_int8_t *user_defined_proto) { + const void *ret; + ndpi_default_ports_tree_node_t node; + + *user_defined_proto = 0; /* Default */ + if(sport && dport) { + ndpi_default_ports_tree_node_t *found = ndpi_get_guessed_protocol_id(ndpi_struct, proto, sport, dport); + + if(found != NULL) { + *user_defined_proto = found->customUserProto; + return(found->proto->protoId); } } else { /* No TCP/UDP */ @@ -1871,13 +1975,13 @@ u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi #ifdef WIN32 char * strsep(char **sp, char *sep) { - char *p, *s; - if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL); - s = *sp; - p = s + strcspn(s, sep); - if (*p != '\0') *p++ = '\0'; - *sp = p; - return(s); + char *p, *s; + if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL); + s = *sp; + p = s + strcspn(s, sep); + if (*p != '\0') *p++ = '\0'; + *sp = p; + return(s); } #endif @@ -1970,7 +2074,7 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2) range.port_low = range.port_high = atoi(&elem[4]); if(do_add) - addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); + addDefaultPort(&range, def, 1 /* Custom user proto */, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); else removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); } else if(is_ip) { @@ -2264,7 +2368,7 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* SSDP */ init_ssdp_dissector(ndpi_struct, &a, detection_bitmask); -/* WORLD_OF_WARCRAFT */ + /* WORLD_OF_WARCRAFT */ init_world_of_warcraft_dissector(ndpi_struct, &a, detection_bitmask); /* POSTGRES */ @@ -2495,7 +2599,19 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* MQTT */ init_mqtt_dissector(ndpi_struct, &a, detection_bitmask); - /* Put false-positive sensitive protocols at the end */ + /* RX */ + init_rx_dissector(ndpi_struct, &a, detection_bitmask); + + /* GIT */ + init_git_dissector(ndpi_struct, &a, detection_bitmask); + + /* HANGOUT */ + init_hangout_dissector(ndpi_struct, &a, detection_bitmask); + + /* DRDA */ + init_drda_dissector(ndpi_struct, &a, detection_bitmask); + + /*** Put false-positive sensitive protocols at the end ***/ /* SKYPE */ init_skype_dissector(ndpi_struct, &a, detection_bitmask); @@ -3154,18 +3270,35 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru u_int8_t l4_proto, struct ndpi_id_struct *src, u_int16_t sport, - struct ndpi_id_struct *dst, + struct ndpi_id_struct *dst, u_int16_t dport, + const u_int64_t current_tick_l, u_int8_t *payload, u_int16_t payload_len) { NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet; u_int32_t a; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; + if(flow == NULL) + return(ret); + if(payload_len == 0) return(ret); flow->packet.tcp = tcp, flow->packet.udp = udp; flow->packet.payload = payload, flow->packet.payload_packet_len = payload_len; + flow->packet.tick_timestamp_l = current_tick_l; + flow->packet.tick_timestamp = (u_int32_t)current_tick_l/1000; + + if(flow) { + ndpi_apply_flow_protocol_to_packet(flow, &flow->packet); + } else { + ndpi_int_reset_packet_protocol(&flow->packet); + } + + if(flow->server_id == NULL) flow->server_id = dst; /* Default */ + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + goto ret_protocols; + if(src_to_dst_direction) flow->src = src, flow->dst = dst; else @@ -3179,6 +3312,8 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; #endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + ndpi_connection_tracking(ndpi_struct, flow); + if(flow->packet.tcp != NULL) ndpi_selection_packet |= (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP); @@ -3196,6 +3331,28 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru flow->packet.l4_protocol = l4_proto, flow->packet.packet_direction = src_to_dst_direction; + if((!flow->protocol_id_already_guessed) + && ( +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + flow->packet.iphv6 || +#endif + flow->packet.iph)) { + u_int8_t user_defined_proto; + + flow->protocol_id_already_guessed = 1, + flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, l4_proto, sport, dport, &user_defined_proto); + + if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) { + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id; + return(ret); + } + + 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); + } + } + check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet); a = flow->packet.detected_protocol_stack[0]; @@ -3329,6 +3486,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct u_int16_t sport, dport; u_int8_t protocol; u_int32_t saddr, daddr; + u_int8_t user_defined_proto; flow->protocol_id_already_guessed = 1; @@ -3339,15 +3497,18 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct #endif { protocol = flow->packet.iph->protocol; - saddr = ntohl(flow->packet.iph->saddr); - daddr = ntohl(flow->packet.iph->daddr); } if(flow->packet.udp) sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest); else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest); else sport = dport = 0; - flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport); + flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport, &user_defined_proto); + + if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) { + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id; + return(ret); + } 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) @@ -4182,12 +4343,14 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct unsigned int rc; struct in_addr addr; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; + u_int8_t user_defined_proto; if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) { rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport); + if(rc != NDPI_PROTOCOL_UNKNOWN) { ret.protocol = rc, - ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; @@ -4195,7 +4358,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct return(ret); } - rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); if(rc != NDPI_PROTOCOL_UNKNOWN) { ret.protocol = rc; @@ -4219,7 +4382,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct ret.protocol = NDPI_PROTOCOL_SKYPE; } } else - ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); return(ret); } @@ -4339,6 +4502,16 @@ char* ndpi_strnstr(const char *s, const char *find, size_t slen) { /* ****************************************************** */ +int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len, + const char *str, size_t str_len) +{ + return str_len <= payload_len + ? memcmp(payload, str, str_len) == 0 + : 0; +} + +/* ****************************************************** */ + int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, char *string_to_match, u_int string_to_match_len, u_int8_t is_host_match) { @@ -4369,7 +4542,6 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str 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; #ifdef DEBUG { @@ -4465,25 +4637,6 @@ char* ndpi_revision() { return(NDPI_GIT_RELEASE); } #ifdef WIN32 -/* - int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) { - unused = NULL; - *mutex = CreateMutex(NULL, FALSE, NULL); - return *mutex == NULL ? -1 : 0; - } - - int pthread_mutex_destroy(pthread_mutex_t *mutex) { - return CloseHandle(*mutex) == 0 ? -1 : 0; - } - - int pthread_mutex_lock(pthread_mutex_t *mutex) { - return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; - } - - int pthread_mutex_unlock(pthread_mutex_t *mutex) { - return ReleaseMutex(*mutex) == 0 ? -1 : 0; - } -*/ /* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */ int gettimeofday(struct timeval * tp, struct timezone * tzp) { /* FILETIME of Jan 1 1970 00:00:00. */ diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c index 8f293b611..e72fdee57 100644 --- a/src/lib/protocols/bgp.c +++ b/src/lib/protocols/bgp.c @@ -35,23 +35,23 @@ static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndp /* this detection also works asymmetrically */ void ndpi_search_bgp(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; + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t bgp_port = htons(179); - if (packet->payload_packet_len > 18 && - get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL && - get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL && - ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len && - (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179)) - && packet->payload[18] < 5) { - NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n"); - ndpi_int_bgp_add_connection(ndpi_struct, flow); - return; - } + if(packet->tcp + && (packet->payload_packet_len > 18) + && (packet->payload[18] < 5) + && ((packet->tcp->dest == bgp_port) || (packet->tcp->source == bgp_port)) + && (get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL) + && (get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL) + && (ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len) + ) { + NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n"); + ndpi_int_bgp_add_connection(ndpi_struct, flow); + return; + } - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP); } diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 8213d3b45..0eebe07ee 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -53,8 +53,7 @@ static u_int8_t is_utp_pkt(const u_int8_t *payload, u_int payload_len) { 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 */) + const u_int8_t save_detection, const u_int8_t encrypted_connection) { if(check_hash) { const char *bt_hash = NULL; /* 20 bytes long */ @@ -92,8 +91,7 @@ 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: plain BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 19, 1, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; } } @@ -125,8 +123,7 @@ 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: plain Bitcomet persistent seed protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } @@ -135,7 +132,6 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module || memcmp(packet->payload, "POST ", 5) == 0)) { const u_int8_t *ptr = &packet->payload[4]; u_int16_t len = packet->payload_packet_len - 4; - a = 0; /* parse complete get packet here into line structure elements */ diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c index cddf31b7e..5f8e97863 100644 --- a/src/lib/protocols/coap.c +++ b/src/lib/protocols/coap.c @@ -72,7 +72,7 @@ struct ndpi_coap_hdr [164] = "5.04 Gateway Timeout", [165] = "5.05 Proxying Not Supported" **/ - + /** * Entry point when protocol is identified. @@ -84,6 +84,20 @@ static void ndpi_int_coap_add_connection (struct ndpi_detection_module_struct *n } /** + * Check if the default port is acceptable + * + * UDP Port 5683 (mandatory) + * UDP Ports 61616-61631 compressed 6lowPAN + */ +static int isCoAPport(u_int16_t port) { + if((port == 5683) + || ((port >= 61616) && (port <= 61631))) + return(1); + else + return(0); +} + +/** * Dissector function that searches CoAP headers */ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, @@ -91,22 +105,24 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_coap_hdr * h = (struct ndpi_coap_hdr*) packet->payload; - + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { return; } // search for udp packet if(packet->udp != NULL) { - - // header too short - if(packet->payload_packet_len < 4) { - + u_int16_t s_port = ntohs(flow->packet.udp->source); + u_int16_t d_port = ntohs(flow->packet.udp->dest); + + if((!isCoAPport(s_port) && !isCoAPport(s_port)) + || (packet->payload_packet_len < 4) // header too short + ) { NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "excluding Coap\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP); return; } - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "calculating coap over udp.\n"); // check values in header @@ -116,21 +132,21 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, if((h->code >= 0 && h->code <= 5) || (h->code >= 65 && h->code <= 69) || (h->code >= 128 && h->code <= 134) || (h->code >= 140 && h->code <= 143) || (h->code >= 160 && h->code <= 165)) { - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found...\n"); ndpi_int_coap_add_connection(ndpi_struct,flow); return; } } } - } + } } - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap ...\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP); return; - } + /** * Entry point for the ndpi library */ diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c index ec96d1287..7be8ac027 100644 --- a/src/lib/protocols/dcerpc.c +++ b/src/lib/protocols/dcerpc.c @@ -36,13 +36,11 @@ void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct { struct ndpi_packet_struct *packet = &flow->packet; - u_int16_t len_packet = (packet->payload[9]<<8) | packet->payload[8]; - if((packet->tcp != NULL) && (packet->payload_packet_len >= 64) && (packet->payload[0] == 0x05) /* version 5 */ && (packet->payload[2] < 16) /* Packet type */ - && (len_packet == packet->payload_packet_len) /* Packet Length */ + && (((packet->payload[9]<<8) | packet->payload[8]) == packet->payload_packet_len) /* Packet Length */ ) { NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n"); ndpi_int_dcerpc_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index 8ffc04d51..e33a7c011 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -1,8 +1,7 @@ /* * dhcp.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - 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 @@ -43,16 +42,18 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru /* 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)) { - - NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); - - ndpi_int_dhcp_add_connection(ndpi_struct, flow); - return; + if(packet->udp) { + 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_int_dhcp_add_connection(ndpi_struct, flow); + return; + } } 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 503761137..5358cc8b7 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -3,8 +3,6 @@ * * Copyright (C) 2012-16 - ntop.org * - * Michele Campus - <campus@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 * @@ -29,37 +27,60 @@ #define FLAGS_MASK 0x8000 -void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ +/* #define DNS_DEBUG 1 */ + +/* *********************************************** */ + +static u_int16_t get16(int *i, const u_int8_t *payload) { + u_int16_t v = *(u_int16_t*)&payload[*i]; + + (*i) += 2; + + return(ntohs(v)); +} + +/* *********************************************** */ + +static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { + if(payload[i] == 0x00) + return(1); + else if(payload[i] == 0xC0) + return(2); + else { + u_int8_t len = payload[i]; + u_int8_t off = len + 1; + + if(off == 0) /* Bad packet */ + return(0); + else + return(off + getNameLength(i+off, payload, payloadLen)); + } +} + +/* *********************************************** */ +void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { int x; - u_int8_t is_query, ret_code; - u_int16_t s_port = 0; - u_int16_t d_port = 0; + u_int8_t is_query; + u_int16_t s_port = 0, d_port = 0; NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n"); - if(flow->packet.udp != NULL) - { + if(flow->packet.udp != NULL) { s_port = ntohs(flow->packet.udp->source); d_port = ntohs(flow->packet.udp->dest); x = 0; - } - else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ - { + } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ { s_port = ntohs(flow->packet.tcp->source); d_port = ntohs(flow->packet.tcp->dest); x = 2; - } - else - { + } else { NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); } if((s_port == 53 || d_port == 53 || d_port == 5355) - && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header))) - { + && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+x)) { struct ndpi_dns_packet_header dns_header; int invalid = 0; @@ -70,12 +91,13 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd 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); + x += sizeof(struct ndpi_dns_packet_header); /* 0x0000 QUERY */ 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; @@ -87,69 +109,129 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd && (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) || ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) { /* This is a good query */ + + if(dns_header.num_queries > 0) { + while(x < flow->packet.payload_packet_len) { + if(flow->packet.payload[x] == '\0') { + x++; + flow->protos.dns.query_type = get16(&x, flow->packet.payload); +#ifdef DNS_DEBUG + printf("[%s:%d] query_type=%2d\n", __FILE__, __LINE__, flow->protos.dns.query_type); +#endif + break; + } else + x++; + } + } } else invalid = 1; + } else { /* DNS Reply */ + + flow->protos.dns.reply_code = dns_header.flags & 0x0F; + 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(ndpi_struct->dns_dissect_response) { + x++; + + if(flow->packet.payload[x] != '\0') { + while((x < flow->packet.payload_packet_len) + && (flow->packet.payload[x] != '\0')) { + x++; + } + + x++; + } + + x += 4; + + if(dns_header.num_answers > 0) { + u_int16_t rsp_type; + u_int16_t num; + + for(num = 0; num < dns_header.num_answers; num++) { + u_int16_t data_len; + + if((x+6) >= flow->packet.payload_packet_len) { + break; + } + + if((data_len = getNameLength(x, flow->packet.payload, flow->packet.payload_packet_len)) == 0) { + break; + } else + x += data_len; + + rsp_type = get16(&x, flow->packet.payload); + flow->protos.dns.rsp_type = rsp_type; + break; + } + } + } + } } - } - if(invalid) { - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); - return; - } + if(invalid) { + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + return; + } - /* extract host name server */ - 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')) - { - if(off < flow->packet.payload_packet_len) - { + /* extract host name server */ + int j = 0, max_len = sizeof(flow->host_server_name)-1, off = sizeof(struct ndpi_dns_packet_header) + 1; + + while(off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') { flow->host_server_name[j] = flow->packet.payload[off]; - if(j < strlen(flow->host_server_name)) - { + if(j < max_len) { if(flow->host_server_name[j] < ' ') flow->host_server_name[j] = '.'; j++; - } + } else + break; + off++; } - } - 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.ret_code = ret_code; + flow->host_server_name[j] = '\0'; + + flow->protos.dns.num_queries = (u_int8_t)dns_header.num_queries, + flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs); + + if(j > 0) + ndpi_match_host_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name), + NDPI_PROTOCOL_DNS); - if(j > 0) - ndpi_match_host_subprotocol(ndpi_struct, flow, - (char *)flow->host_server_name, - strlen((const char*)flow->host_server_name), - NDPI_PROTOCOL_DNS); +#ifdef DNS_DEBUG + printf("[%s:%d] [num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", + __FILE__, __LINE__, + flow->protos.dns.num_queries, flow->protos.dns.num_answers, + flow->protos.dns.reply_code, flow->protos.dns.rsp_type, flow->host_server_name + ); +#endif - if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) - { - /** - Do not set the protocol with DNS if ndpi_match_host_subprotocol() has - matched a subprotocol - **/ - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); - } else { - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + if(is_query && ndpi_struct->dns_dissect_response) + return; /* The response will set the verdict */ + + /** + Do not set the protocol with DNS if ndpi_match_host_subprotocol() has + matched a subprotocol + **/ + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); + } else { + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + } } - } + } } void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) diff --git a/src/lib/protocols/drda.c b/src/lib/protocols/drda.c new file mode 100644 index 000000000..fe75379ff --- /dev/null +++ b/src/lib/protocols/drda.c @@ -0,0 +1,106 @@ +/* + * drda.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module 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. + * + * This module 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. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_DRDA + +#define DRDA_PORT 50000 + +struct ndpi_drda_hdr { + u_int16_t length; + u_int8_t magic; + u_int8_t format; + u_int16_t correlID; + u_int16_t length2; + u_int16_t code_pnt; +}; + + +void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct * packet = &flow->packet; + u_int16_t payload_len = packet->payload_packet_len; + u_int count = 0; // prevent integer overflow + + if(packet->tcp != NULL) { + + /* check port */ + if((ntohs(packet->tcp->source) == DRDA_PORT || + ntohs(packet->tcp->dest) == DRDA_PORT) && + payload_len >= sizeof(struct ndpi_drda_hdr)) { + + struct ndpi_drda_hdr * drda = (struct ndpi_drda_hdr *) packet->payload; + + u_int16_t len = ntohs(drda->length); + + /* check first header */ + if(len != ntohs(drda->length2) + 6 || + drda->magic != 0xd0) + goto no_drda; + + /* check if there are more drda headers */ + if(payload_len > len) { + + count = len; + + while(count + sizeof(struct ndpi_drda_hdr) < payload_len) + { + /* update info */ + drda = (struct ndpi_drda_hdr *)(packet->payload + count); + len = ntohs(drda->length); + + if(len != ntohs(drda->length2) + 6 || + drda->magic != 0xd0) + goto no_drda; + + count += len; + } + if(count != payload_len) goto no_drda; + } + NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "found DRDA.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DRDA, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + + no_drda: + NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "exclude DRDA.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DRDA); +} + + +/* ***************************************************************** */ + + +void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("DRDA", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_DRDA, + ndpi_search_drda, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_PROTOCOL_DRDA */ diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c index f51de95d2..d8babfb1b 100644 --- a/src/lib/protocols/dropbox.c +++ b/src/lib/protocols/dropbox.c @@ -1,7 +1,7 @@ /* * dropbox.c * - * Copyright (C) 2011-13 by ntop.org + * Copyright (C) 2012-16 by 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 @@ -44,7 +44,6 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t payload_len = packet->payload_packet_len; if(packet->udp != NULL) { - u_int16_t dropbox_port = htons(DB_LSP_PORT); if((packet->udp->source == dropbox_port) diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 8710096be..9bc2bf904 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -30,904 +30,904 @@ static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_str ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_PROTOCOL_UNKNOWN); } -static int ndpi_ftp_control_check_request(const u_int8_t *payload) { +static int ndpi_ftp_control_check_request(const u_int8_t *payload, size_t payload_len) { - if (match_first_bytes(payload, "ABOR")) { + if (ndpi_match_strprefix(payload, payload_len, "ABOR")) { return 1; } - if (match_first_bytes(payload, "ACCT")) { + if (ndpi_match_strprefix(payload, payload_len, "ACCT")) { return 1; } - if (match_first_bytes(payload, "ADAT")) { + if (ndpi_match_strprefix(payload, payload_len, "ADAT")) { return 1; } - if (match_first_bytes(payload, "ALLO")) { + if (ndpi_match_strprefix(payload, payload_len, "ALLO")) { return 1; } - if (match_first_bytes(payload, "APPE")) { + if (ndpi_match_strprefix(payload, payload_len, "APPE")) { return 1; } - if (match_first_bytes(payload, "AUTH")) { + if (ndpi_match_strprefix(payload, payload_len, "AUTH")) { return 1; } - if (match_first_bytes(payload, "CCC")) { + if (ndpi_match_strprefix(payload, payload_len, "CCC")) { return 1; } - if (match_first_bytes(payload, "CDUP")) { + if (ndpi_match_strprefix(payload, payload_len, "CDUP")) { return 1; } - if (match_first_bytes(payload, "CONF")) { + if (ndpi_match_strprefix(payload, payload_len, "CONF")) { return 1; } - if (match_first_bytes(payload, "CWD")) { + if (ndpi_match_strprefix(payload, payload_len, "CWD")) { return 1; } - if (match_first_bytes(payload, "DELE")) { + if (ndpi_match_strprefix(payload, payload_len, "DELE")) { return 1; } - if (match_first_bytes(payload, "ENC")) { + if (ndpi_match_strprefix(payload, payload_len, "ENC")) { return 1; } - if (match_first_bytes(payload, "EPRT")) { + if (ndpi_match_strprefix(payload, payload_len, "EPRT")) { return 1; } - if (match_first_bytes(payload, "EPSV")) { + if (ndpi_match_strprefix(payload, payload_len, "EPSV")) { return 1; } - if (match_first_bytes(payload, "FEAT")) { + if (ndpi_match_strprefix(payload, payload_len, "FEAT")) { return 1; } - if (match_first_bytes(payload, "HELP")) { + if (ndpi_match_strprefix(payload, payload_len, "HELP")) { return 1; } - if (match_first_bytes(payload, "LANG")) { + if (ndpi_match_strprefix(payload, payload_len, "LANG")) { return 1; } - if (match_first_bytes(payload, "LIST")) { + if (ndpi_match_strprefix(payload, payload_len, "LIST")) { return 1; } - if (match_first_bytes(payload, "LPRT")) { + if (ndpi_match_strprefix(payload, payload_len, "LPRT")) { return 1; } - if (match_first_bytes(payload, "LPSV")) { + if (ndpi_match_strprefix(payload, payload_len, "LPSV")) { return 1; } - if (match_first_bytes(payload, "MDTM")) { + if (ndpi_match_strprefix(payload, payload_len, "MDTM")) { return 1; } - if (match_first_bytes(payload, "MIC")) { + if (ndpi_match_strprefix(payload, payload_len, "MIC")) { return 1; } - if (match_first_bytes(payload, "MKD")) { + if (ndpi_match_strprefix(payload, payload_len, "MKD")) { return 1; } - if (match_first_bytes(payload, "MLSD")) { + if (ndpi_match_strprefix(payload, payload_len, "MLSD")) { return 1; } - if (match_first_bytes(payload, "MLST")) { + if (ndpi_match_strprefix(payload, payload_len, "MLST")) { return 1; } - if (match_first_bytes(payload, "MODE")) { + if (ndpi_match_strprefix(payload, payload_len, "MODE")) { return 1; } - if (match_first_bytes(payload, "NLST")) { + if (ndpi_match_strprefix(payload, payload_len, "NLST")) { return 1; } - if (match_first_bytes(payload, "NOOP")) { + if (ndpi_match_strprefix(payload, payload_len, "NOOP")) { return 1; } - if (match_first_bytes(payload, "OPTS")) { + if (ndpi_match_strprefix(payload, payload_len, "OPTS")) { return 1; } - if (match_first_bytes(payload, "PASS")) { + if (ndpi_match_strprefix(payload, payload_len, "PASS")) { return 1; } - if (match_first_bytes(payload, "PASV")) { + if (ndpi_match_strprefix(payload, payload_len, "PASV")) { return 1; } - if (match_first_bytes(payload, "PBSZ")) { + if (ndpi_match_strprefix(payload, payload_len, "PBSZ")) { return 1; } - if (match_first_bytes(payload, "PORT")) { + if (ndpi_match_strprefix(payload, payload_len, "PORT")) { return 1; } - if (match_first_bytes(payload, "PROT")) { + if (ndpi_match_strprefix(payload, payload_len, "PROT")) { return 1; } - if (match_first_bytes(payload, "PWD")) { + if (ndpi_match_strprefix(payload, payload_len, "PWD")) { return 1; } - if (match_first_bytes(payload, "QUIT")) { + if (ndpi_match_strprefix(payload, payload_len, "QUIT")) { return 1; } - if (match_first_bytes(payload, "REIN")) { + if (ndpi_match_strprefix(payload, payload_len, "REIN")) { return 1; } - if (match_first_bytes(payload, "REST")) { + if (ndpi_match_strprefix(payload, payload_len, "REST")) { return 1; } - if (match_first_bytes(payload, "RETR")) { + if (ndpi_match_strprefix(payload, payload_len, "RETR")) { return 1; } - if (match_first_bytes(payload, "RMD")) { + if (ndpi_match_strprefix(payload, payload_len, "RMD")) { return 1; } - if (match_first_bytes(payload, "RNFR")) { + if (ndpi_match_strprefix(payload, payload_len, "RNFR")) { return 1; } - if (match_first_bytes(payload, "RNTO")) { + if (ndpi_match_strprefix(payload, payload_len, "RNTO")) { return 1; } - if (match_first_bytes(payload, "SITE")) { + if (ndpi_match_strprefix(payload, payload_len, "SITE")) { return 1; } - if (match_first_bytes(payload, "SIZE")) { + if (ndpi_match_strprefix(payload, payload_len, "SIZE")) { return 1; } - if (match_first_bytes(payload, "SMNT")) { + if (ndpi_match_strprefix(payload, payload_len, "SMNT")) { return 1; } - if (match_first_bytes(payload, "STAT")) { + if (ndpi_match_strprefix(payload, payload_len, "STAT")) { return 1; } - if (match_first_bytes(payload, "STOR")) { + if (ndpi_match_strprefix(payload, payload_len, "STOR")) { return 1; } - if (match_first_bytes(payload, "STOU")) { + if (ndpi_match_strprefix(payload, payload_len, "STOU")) { return 1; } - if (match_first_bytes(payload, "STRU")) { + if (ndpi_match_strprefix(payload, payload_len, "STRU")) { return 1; } - if (match_first_bytes(payload, "SYST")) { + if (ndpi_match_strprefix(payload, payload_len, "SYST")) { return 1; } - if (match_first_bytes(payload, "TYPE")) { + if (ndpi_match_strprefix(payload, payload_len, "TYPE")) { return 1; } - if (match_first_bytes(payload, "USER")) { + if (ndpi_match_strprefix(payload, payload_len, "USER")) { return 1; } - if (match_first_bytes(payload, "XCUP")) { + if (ndpi_match_strprefix(payload, payload_len, "XCUP")) { return 1; } - if (match_first_bytes(payload, "XMKD")) { + if (ndpi_match_strprefix(payload, payload_len, "XMKD")) { return 1; } - if (match_first_bytes(payload, "XPWD")) { + if (ndpi_match_strprefix(payload, payload_len, "XPWD")) { return 1; } - if (match_first_bytes(payload, "XRCP")) { + if (ndpi_match_strprefix(payload, payload_len, "XRCP")) { return 1; } - if (match_first_bytes(payload, "XRMD")) { + if (ndpi_match_strprefix(payload, payload_len, "XRMD")) { return 1; } - if (match_first_bytes(payload, "XRSQ")) { + if (ndpi_match_strprefix(payload, payload_len, "XRSQ")) { return 1; } - if (match_first_bytes(payload, "XSEM")) { + if (ndpi_match_strprefix(payload, payload_len, "XSEM")) { return 1; } - if (match_first_bytes(payload, "XSEN")) { + if (ndpi_match_strprefix(payload, payload_len, "XSEN")) { return 1; } - if (match_first_bytes(payload, "HOST")) { + if (ndpi_match_strprefix(payload, payload_len, "HOST")) { return 1; } - if (match_first_bytes(payload, "abor")) { + if (ndpi_match_strprefix(payload, payload_len, "abor")) { return 1; } - if (match_first_bytes(payload, "acct")) { + if (ndpi_match_strprefix(payload, payload_len, "acct")) { return 1; } - if (match_first_bytes(payload, "adat")) { + if (ndpi_match_strprefix(payload, payload_len, "adat")) { return 1; } - if (match_first_bytes(payload, "allo")) { + if (ndpi_match_strprefix(payload, payload_len, "allo")) { return 1; } - if (match_first_bytes(payload, "appe")) { + if (ndpi_match_strprefix(payload, payload_len, "appe")) { return 1; } - if (match_first_bytes(payload, "auth")) { + if (ndpi_match_strprefix(payload, payload_len, "auth")) { return 1; } - if (match_first_bytes(payload, "ccc")) { + if (ndpi_match_strprefix(payload, payload_len, "ccc")) { return 1; } - if (match_first_bytes(payload, "cdup")) { + if (ndpi_match_strprefix(payload, payload_len, "cdup")) { return 1; } - if (match_first_bytes(payload, "conf")) { + if (ndpi_match_strprefix(payload, payload_len, "conf")) { return 1; } - if (match_first_bytes(payload, "cwd")) { + if (ndpi_match_strprefix(payload, payload_len, "cwd")) { return 1; } - if (match_first_bytes(payload, "dele")) { + if (ndpi_match_strprefix(payload, payload_len, "dele")) { return 1; } - if (match_first_bytes(payload, "enc")) { + if (ndpi_match_strprefix(payload, payload_len, "enc")) { return 1; } - if (match_first_bytes(payload, "eprt")) { + if (ndpi_match_strprefix(payload, payload_len, "eprt")) { return 1; } - if (match_first_bytes(payload, "epsv")) { + if (ndpi_match_strprefix(payload, payload_len, "epsv")) { return 1; } - if (match_first_bytes(payload, "feat")) { + if (ndpi_match_strprefix(payload, payload_len, "feat")) { return 1; } - if (match_first_bytes(payload, "help")) { + if (ndpi_match_strprefix(payload, payload_len, "help")) { return 1; } - if (match_first_bytes(payload, "lang")) { + if (ndpi_match_strprefix(payload, payload_len, "lang")) { return 1; } - if (match_first_bytes(payload, "list")) { + if (ndpi_match_strprefix(payload, payload_len, "list")) { return 1; } - if (match_first_bytes(payload, "lprt")) { + if (ndpi_match_strprefix(payload, payload_len, "lprt")) { return 1; } - if (match_first_bytes(payload, "lpsv")) { + if (ndpi_match_strprefix(payload, payload_len, "lpsv")) { return 1; } - if (match_first_bytes(payload, "mdtm")) { + if (ndpi_match_strprefix(payload, payload_len, "mdtm")) { return 1; } - if (match_first_bytes(payload, "mic")) { + if (ndpi_match_strprefix(payload, payload_len, "mic")) { return 1; } - if (match_first_bytes(payload, "mkd")) { + if (ndpi_match_strprefix(payload, payload_len, "mkd")) { return 1; } - if (match_first_bytes(payload, "mlsd")) { + if (ndpi_match_strprefix(payload, payload_len, "mlsd")) { return 1; } - if (match_first_bytes(payload, "mlst")) { + if (ndpi_match_strprefix(payload, payload_len, "mlst")) { return 1; } - if (match_first_bytes(payload, "mode")) { + if (ndpi_match_strprefix(payload, payload_len, "mode")) { return 1; } - if (match_first_bytes(payload, "nlst")) { + if (ndpi_match_strprefix(payload, payload_len, "nlst")) { return 1; } - if (match_first_bytes(payload, "noop")) { + if (ndpi_match_strprefix(payload, payload_len, "noop")) { return 1; } - if (match_first_bytes(payload, "opts")) { + if (ndpi_match_strprefix(payload, payload_len, "opts")) { return 1; } - if (match_first_bytes(payload, "pass")) { + if (ndpi_match_strprefix(payload, payload_len, "pass")) { return 1; } - if (match_first_bytes(payload, "pasv")) { + if (ndpi_match_strprefix(payload, payload_len, "pasv")) { return 1; } - if (match_first_bytes(payload, "pbsz")) { + if (ndpi_match_strprefix(payload, payload_len, "pbsz")) { return 1; } - if (match_first_bytes(payload, "port")) { + if (ndpi_match_strprefix(payload, payload_len, "port")) { return 1; } - if (match_first_bytes(payload, "prot")) { + if (ndpi_match_strprefix(payload, payload_len, "prot")) { return 1; } - if (match_first_bytes(payload, "pwd")) { + if (ndpi_match_strprefix(payload, payload_len, "pwd")) { return 1; } - if (match_first_bytes(payload, "quit")) { + if (ndpi_match_strprefix(payload, payload_len, "quit")) { return 1; } - if (match_first_bytes(payload, "rein")) { + if (ndpi_match_strprefix(payload, payload_len, "rein")) { return 1; } - if (match_first_bytes(payload, "rest")) { + if (ndpi_match_strprefix(payload, payload_len, "rest")) { return 1; } - if (match_first_bytes(payload, "retr")) { + if (ndpi_match_strprefix(payload, payload_len, "retr")) { return 1; } - if (match_first_bytes(payload, "rmd")) { + if (ndpi_match_strprefix(payload, payload_len, "rmd")) { return 1; } - if (match_first_bytes(payload, "rnfr")) { + if (ndpi_match_strprefix(payload, payload_len, "rnfr")) { return 1; } - if (match_first_bytes(payload, "rnto")) { + if (ndpi_match_strprefix(payload, payload_len, "rnto")) { return 1; } - if (match_first_bytes(payload, "site")) { + if (ndpi_match_strprefix(payload, payload_len, "site")) { return 1; } - if (match_first_bytes(payload, "size")) { + if (ndpi_match_strprefix(payload, payload_len, "size")) { return 1; } - if (match_first_bytes(payload, "smnt")) { + if (ndpi_match_strprefix(payload, payload_len, "smnt")) { return 1; } - if (match_first_bytes(payload, "stat")) { + if (ndpi_match_strprefix(payload, payload_len, "stat")) { return 1; } - if (match_first_bytes(payload, "stor")) { + if (ndpi_match_strprefix(payload, payload_len, "stor")) { return 1; } - if (match_first_bytes(payload, "stou")) { + if (ndpi_match_strprefix(payload, payload_len, "stou")) { return 1; } - if (match_first_bytes(payload, "stru")) { + if (ndpi_match_strprefix(payload, payload_len, "stru")) { return 1; } - if (match_first_bytes(payload, "syst")) { + if (ndpi_match_strprefix(payload, payload_len, "syst")) { return 1; } - if (match_first_bytes(payload, "type")) { + if (ndpi_match_strprefix(payload, payload_len, "type")) { return 1; } - if (match_first_bytes(payload, "user")) { + if (ndpi_match_strprefix(payload, payload_len, "user")) { return 1; } - if (match_first_bytes(payload, "xcup")) { + if (ndpi_match_strprefix(payload, payload_len, "xcup")) { return 1; } - if (match_first_bytes(payload, "xmkd")) { + if (ndpi_match_strprefix(payload, payload_len, "xmkd")) { return 1; } - if (match_first_bytes(payload, "xpwd")) { + if (ndpi_match_strprefix(payload, payload_len, "xpwd")) { return 1; } - if (match_first_bytes(payload, "xrcp")) { + if (ndpi_match_strprefix(payload, payload_len, "xrcp")) { return 1; } - if (match_first_bytes(payload, "xrmd")) { + if (ndpi_match_strprefix(payload, payload_len, "xrmd")) { return 1; } - if (match_first_bytes(payload, "xrsq")) { + if (ndpi_match_strprefix(payload, payload_len, "xrsq")) { return 1; } - if (match_first_bytes(payload, "xsem")) { + if (ndpi_match_strprefix(payload, payload_len, "xsem")) { return 1; } - if (match_first_bytes(payload, "xsen")) { + if (ndpi_match_strprefix(payload, payload_len, "xsen")) { return 1; } - if (match_first_bytes(payload, "host")) { + if (ndpi_match_strprefix(payload, payload_len, "host")) { return 1; } return 0; } -static int ndpi_ftp_control_check_response(const u_int8_t *payload) { +static int ndpi_ftp_control_check_response(const u_int8_t *payload, size_t payload_len) { - if (match_first_bytes(payload, "110-")) { + if (ndpi_match_strprefix(payload, payload_len, "110-")) { return 1; } - if (match_first_bytes(payload, "120-")) { + if (ndpi_match_strprefix(payload, payload_len, "120-")) { return 1; } - if (match_first_bytes(payload, "125-")) { + if (ndpi_match_strprefix(payload, payload_len, "125-")) { return 1; } - if (match_first_bytes(payload, "150-")) { + if (ndpi_match_strprefix(payload, payload_len, "150-")) { return 1; } - if (match_first_bytes(payload, "202-")) { + if (ndpi_match_strprefix(payload, payload_len, "202-")) { return 1; } - if (match_first_bytes(payload, "211-")) { + if (ndpi_match_strprefix(payload, payload_len, "211-")) { return 1; } - if (match_first_bytes(payload, "212-")) { + if (ndpi_match_strprefix(payload, payload_len, "212-")) { return 1; } - if (match_first_bytes(payload, "213-")) { + if (ndpi_match_strprefix(payload, payload_len, "213-")) { return 1; } - if (match_first_bytes(payload, "214-")) { + if (ndpi_match_strprefix(payload, payload_len, "214-")) { return 1; } - if (match_first_bytes(payload, "215-")) { + if (ndpi_match_strprefix(payload, payload_len, "215-")) { return 1; } - if (match_first_bytes(payload, "220-")) { + if (ndpi_match_strprefix(payload, payload_len, "220-")) { return 1; } - if (match_first_bytes(payload, "221-")) { + if (ndpi_match_strprefix(payload, payload_len, "221-")) { return 1; } - if (match_first_bytes(payload, "225-")) { + if (ndpi_match_strprefix(payload, payload_len, "225-")) { return 1; } - if (match_first_bytes(payload, "226-")) { + if (ndpi_match_strprefix(payload, payload_len, "226-")) { return 1; } - if (match_first_bytes(payload, "227-")) { + if (ndpi_match_strprefix(payload, payload_len, "227-")) { return 1; } - if (match_first_bytes(payload, "228-")) { + if (ndpi_match_strprefix(payload, payload_len, "228-")) { return 1; } - if (match_first_bytes(payload, "229-")) { + if (ndpi_match_strprefix(payload, payload_len, "229-")) { return 1; } - if (match_first_bytes(payload, "230-")) { + if (ndpi_match_strprefix(payload, payload_len, "230-")) { return 1; } - if (match_first_bytes(payload, "231-")) { + if (ndpi_match_strprefix(payload, payload_len, "231-")) { return 1; } - if (match_first_bytes(payload, "232-")) { + if (ndpi_match_strprefix(payload, payload_len, "232-")) { return 1; } - if (match_first_bytes(payload, "250-")) { + if (ndpi_match_strprefix(payload, payload_len, "250-")) { return 1; } - if (match_first_bytes(payload, "257-")) { + if (ndpi_match_strprefix(payload, payload_len, "257-")) { return 1; } - if (match_first_bytes(payload, "331-")) { + if (ndpi_match_strprefix(payload, payload_len, "331-")) { return 1; } - if (match_first_bytes(payload, "332-")) { + if (ndpi_match_strprefix(payload, payload_len, "332-")) { return 1; } - if (match_first_bytes(payload, "350-")) { + if (ndpi_match_strprefix(payload, payload_len, "350-")) { return 1; } - if (match_first_bytes(payload, "421-")) { + if (ndpi_match_strprefix(payload, payload_len, "421-")) { return 1; } - if (match_first_bytes(payload, "425-")) { + if (ndpi_match_strprefix(payload, payload_len, "425-")) { return 1; } - if (match_first_bytes(payload, "426-")) { + if (ndpi_match_strprefix(payload, payload_len, "426-")) { return 1; } - if (match_first_bytes(payload, "430-")) { + if (ndpi_match_strprefix(payload, payload_len, "430-")) { return 1; } - if (match_first_bytes(payload, "434-")) { + if (ndpi_match_strprefix(payload, payload_len, "434-")) { return 1; } - if (match_first_bytes(payload, "450-")) { + if (ndpi_match_strprefix(payload, payload_len, "450-")) { return 1; } - if (match_first_bytes(payload, "451-")) { + if (ndpi_match_strprefix(payload, payload_len, "451-")) { return 1; } - if (match_first_bytes(payload, "452-")) { + if (ndpi_match_strprefix(payload, payload_len, "452-")) { return 1; } - if (match_first_bytes(payload, "501-")) { + if (ndpi_match_strprefix(payload, payload_len, "501-")) { return 1; } - if (match_first_bytes(payload, "502-")) { + if (ndpi_match_strprefix(payload, payload_len, "502-")) { return 1; } - if (match_first_bytes(payload, "503-")) { + if (ndpi_match_strprefix(payload, payload_len, "503-")) { return 1; } - if (match_first_bytes(payload, "504-")) { + if (ndpi_match_strprefix(payload, payload_len, "504-")) { return 1; } - if (match_first_bytes(payload, "530-")) { + if (ndpi_match_strprefix(payload, payload_len, "530-")) { return 1; } - if (match_first_bytes(payload, "532-")) { + if (ndpi_match_strprefix(payload, payload_len, "532-")) { return 1; } - if (match_first_bytes(payload, "550-")) { + if (ndpi_match_strprefix(payload, payload_len, "550-")) { return 1; } - if (match_first_bytes(payload, "551-")) { + if (ndpi_match_strprefix(payload, payload_len, "551-")) { return 1; } - if (match_first_bytes(payload, "552-")) { + if (ndpi_match_strprefix(payload, payload_len, "552-")) { return 1; } - if (match_first_bytes(payload, "553-")) { + if (ndpi_match_strprefix(payload, payload_len, "553-")) { return 1; } - if (match_first_bytes(payload, "631-")) { + if (ndpi_match_strprefix(payload, payload_len, "631-")) { return 1; } - if (match_first_bytes(payload, "632-")) { + if (ndpi_match_strprefix(payload, payload_len, "632-")) { return 1; } - if (match_first_bytes(payload, "633-")) { + if (ndpi_match_strprefix(payload, payload_len, "633-")) { return 1; } - if (match_first_bytes(payload, "10054-")) { + if (ndpi_match_strprefix(payload, payload_len, "10054-")) { return 1; } - if (match_first_bytes(payload, "10060-")) { + if (ndpi_match_strprefix(payload, payload_len, "10060-")) { return 1; } - if (match_first_bytes(payload, "10061-")) { + if (ndpi_match_strprefix(payload, payload_len, "10061-")) { return 1; } - if (match_first_bytes(payload, "10066-")) { + if (ndpi_match_strprefix(payload, payload_len, "10066-")) { return 1; } - if (match_first_bytes(payload, "10068-")) { + if (ndpi_match_strprefix(payload, payload_len, "10068-")) { return 1; } - if (match_first_bytes(payload, "110 ")) { + if (ndpi_match_strprefix(payload, payload_len, "110 ")) { return 1; } - if (match_first_bytes(payload, "120 ")) { + if (ndpi_match_strprefix(payload, payload_len, "120 ")) { return 1; } - if (match_first_bytes(payload, "125 ")) { + if (ndpi_match_strprefix(payload, payload_len, "125 ")) { return 1; } - if (match_first_bytes(payload, "150 ")) { + if (ndpi_match_strprefix(payload, payload_len, "150 ")) { return 1; } - if (match_first_bytes(payload, "202 ")) { + if (ndpi_match_strprefix(payload, payload_len, "202 ")) { return 1; } - if (match_first_bytes(payload, "211 ")) { + if (ndpi_match_strprefix(payload, payload_len, "211 ")) { return 1; } - if (match_first_bytes(payload, "212 ")) { + if (ndpi_match_strprefix(payload, payload_len, "212 ")) { return 1; } - if (match_first_bytes(payload, "213 ")) { + if (ndpi_match_strprefix(payload, payload_len, "213 ")) { return 1; } - if (match_first_bytes(payload, "214 ")) { + if (ndpi_match_strprefix(payload, payload_len, "214 ")) { return 1; } - if (match_first_bytes(payload, "215 ")) { + if (ndpi_match_strprefix(payload, payload_len, "215 ")) { return 1; } - if (match_first_bytes(payload, "220 ")) { + if (ndpi_match_strprefix(payload, payload_len, "220 ")) { return 1; } - if (match_first_bytes(payload, "221 ")) { + if (ndpi_match_strprefix(payload, payload_len, "221 ")) { return 1; } - if (match_first_bytes(payload, "225 ")) { + if (ndpi_match_strprefix(payload, payload_len, "225 ")) { return 1; } - if (match_first_bytes(payload, "226 ")) { + if (ndpi_match_strprefix(payload, payload_len, "226 ")) { return 1; } - if (match_first_bytes(payload, "227 ")) { + if (ndpi_match_strprefix(payload, payload_len, "227 ")) { return 1; } - if (match_first_bytes(payload, "228 ")) { + if (ndpi_match_strprefix(payload, payload_len, "228 ")) { return 1; } - if (match_first_bytes(payload, "229 ")) { + if (ndpi_match_strprefix(payload, payload_len, "229 ")) { return 1; } - if (match_first_bytes(payload, "230 ")) { + if (ndpi_match_strprefix(payload, payload_len, "230 ")) { return 1; } - if (match_first_bytes(payload, "231 ")) { + if (ndpi_match_strprefix(payload, payload_len, "231 ")) { return 1; } - if (match_first_bytes(payload, "232 ")) { + if (ndpi_match_strprefix(payload, payload_len, "232 ")) { return 1; } - if (match_first_bytes(payload, "250 ")) { + if (ndpi_match_strprefix(payload, payload_len, "250 ")) { return 1; } - if (match_first_bytes(payload, "257 ")) { + if (ndpi_match_strprefix(payload, payload_len, "257 ")) { return 1; } - if (match_first_bytes(payload, "331 ")) { + if (ndpi_match_strprefix(payload, payload_len, "331 ")) { return 1; } - if (match_first_bytes(payload, "332 ")) { + if (ndpi_match_strprefix(payload, payload_len, "332 ")) { return 1; } - if (match_first_bytes(payload, "350 ")) { + if (ndpi_match_strprefix(payload, payload_len, "350 ")) { return 1; } - if (match_first_bytes(payload, "421 ")) { + if (ndpi_match_strprefix(payload, payload_len, "421 ")) { return 1; } - if (match_first_bytes(payload, "425 ")) { + if (ndpi_match_strprefix(payload, payload_len, "425 ")) { return 1; } - if (match_first_bytes(payload, "426 ")) { + if (ndpi_match_strprefix(payload, payload_len, "426 ")) { return 1; } - if (match_first_bytes(payload, "430 ")) { + if (ndpi_match_strprefix(payload, payload_len, "430 ")) { return 1; } - if (match_first_bytes(payload, "434 ")) { + if (ndpi_match_strprefix(payload, payload_len, "434 ")) { return 1; } - if (match_first_bytes(payload, "450 ")) { + if (ndpi_match_strprefix(payload, payload_len, "450 ")) { return 1; } - if (match_first_bytes(payload, "451 ")) { + if (ndpi_match_strprefix(payload, payload_len, "451 ")) { return 1; } - if (match_first_bytes(payload, "452 ")) { + if (ndpi_match_strprefix(payload, payload_len, "452 ")) { return 1; } - if (match_first_bytes(payload, "501 ")) { + if (ndpi_match_strprefix(payload, payload_len, "501 ")) { return 1; } - if (match_first_bytes(payload, "502 ")) { + if (ndpi_match_strprefix(payload, payload_len, "502 ")) { return 1; } - if (match_first_bytes(payload, "503 ")) { + if (ndpi_match_strprefix(payload, payload_len, "503 ")) { return 1; } - if (match_first_bytes(payload, "504 ")) { + if (ndpi_match_strprefix(payload, payload_len, "504 ")) { return 1; } - if (match_first_bytes(payload, "530 ")) { + if (ndpi_match_strprefix(payload, payload_len, "530 ")) { return 1; } - if (match_first_bytes(payload, "532 ")) { + if (ndpi_match_strprefix(payload, payload_len, "532 ")) { return 1; } - if (match_first_bytes(payload, "550 ")) { + if (ndpi_match_strprefix(payload, payload_len, "550 ")) { return 1; } - if (match_first_bytes(payload, "551 ")) { + if (ndpi_match_strprefix(payload, payload_len, "551 ")) { return 1; } - if (match_first_bytes(payload, "552 ")) { + if (ndpi_match_strprefix(payload, payload_len, "552 ")) { return 1; } - if (match_first_bytes(payload, "553 ")) { + if (ndpi_match_strprefix(payload, payload_len, "553 ")) { return 1; } - if (match_first_bytes(payload, "631 ")) { + if (ndpi_match_strprefix(payload, payload_len, "631 ")) { return 1; } - if (match_first_bytes(payload, "632 ")) { + if (ndpi_match_strprefix(payload, payload_len, "632 ")) { return 1; } - if (match_first_bytes(payload, "633 ")) { + if (ndpi_match_strprefix(payload, payload_len, "633 ")) { return 1; } - if (match_first_bytes(payload, "10054 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10054 ")) { return 1; } - if (match_first_bytes(payload, "10060 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10060 ")) { return 1; } - if (match_first_bytes(payload, "10061 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10061 ")) { return 1; } - if (match_first_bytes(payload, "10066 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10066 ")) { return 1; } - if (match_first_bytes(payload, "10068 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10068 ")) { return 1; } @@ -956,7 +956,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str if (flow->ftp_control_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage 0: \n"); - if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload)) { + if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload, payload_len)) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_CONTROL 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. */ @@ -972,7 +972,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload)) { + if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload, payload_len)) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_CONTROL.\n"); ndpi_int_ftp_control_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c index e87b4402f..7daf9190d 100644 --- a/src/lib/protocols/ftp_data.c +++ b/src/lib/protocols/ftp_data.c @@ -60,13 +60,14 @@ static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *nd static int ndpi_match_file_header(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; /* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */ if(packet->payload_packet_len < 256) return 0; /* RIFF is a meta-format for storing AVI and WAV files */ - if(match_first_bytes(packet->payload, "RIFF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "RIFF")) return 1; /* MZ is a .exe file */ @@ -74,7 +75,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* Ogg files */ - if(match_first_bytes(packet->payload, "OggS")) + if(ndpi_match_strprefix(packet->payload, payload_len, "OggS")) return 1; /* ZIP files */ @@ -86,7 +87,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* RAR files */ - if(match_first_bytes(packet->payload, "Rar!")) + if(ndpi_match_strprefix(packet->payload, payload_len, "Rar!")) return 1; /* EBML */ @@ -98,7 +99,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* GIF */ - if(match_first_bytes(packet->payload, "GIF8")) + if(ndpi_match_strprefix(packet->payload, payload_len, "GIF8")) return 1; /* PHP scripts */ @@ -110,7 +111,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* PDFs */ - if(match_first_bytes(packet->payload, "%PDF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "%PDF")) return 1; /* PNG */ @@ -118,7 +119,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* HTML */ - if(match_first_bytes(packet->payload, "<htm")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<htm")) return 1; if((packet->payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D')) return 1; @@ -132,17 +133,17 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* XML */ - if(match_first_bytes(packet->payload, "<!DO")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<!DO")) return 1; /* FLAC */ - if(match_first_bytes(packet->payload, "fLaC")) + if(ndpi_match_strprefix(packet->payload, payload_len, "fLaC")) return 1; /* MP3 */ if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03)) return 1; - if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0")) + if(ndpi_match_strprefix(packet->payload, payload_len, "\xff\xfb\x90\xc0")) return 1; /* RPM */ @@ -150,7 +151,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* Wz Patch */ - if(match_first_bytes(packet->payload, "WzPa")) + if(ndpi_match_strprefix(packet->payload, payload_len, "WzPa")) return 1; /* Flash Video */ @@ -158,7 +159,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* .BKF (Microsoft Tape Format) */ - if(match_first_bytes(packet->payload, "TAPE")) + if(ndpi_match_strprefix(packet->payload, payload_len, "TAPE")) return 1; /* MS Office Doc file - this is unpleasantly geeky */ @@ -174,23 +175,23 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* ar archive, typically .deb files */ - if(match_first_bytes(packet->payload, "!<ar")) + if(ndpi_match_strprefix(packet->payload, payload_len, "!<ar")) return 1; /* Raw XML (skip jabber-like traffic as this is not FTP but unencrypted jabber) */ - if((match_first_bytes(packet->payload, "<?xm")) + if((ndpi_match_strprefix(packet->payload, payload_len, "<?xm")) && (ndpi_strnstr((const char *)packet->payload, "jabber", packet->payload_packet_len) == NULL)) return 1; - if(match_first_bytes(packet->payload, "<iq ")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<iq ")) return 1; /* SPF */ - if(match_first_bytes(packet->payload, "SPFI")) + if(ndpi_match_strprefix(packet->payload, payload_len, "SPFI")) return 1; /* ABIF - Applied Biosystems */ - if(match_first_bytes(packet->payload, "ABIF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "ABIF")) return 1; /* bzip2 - other digits are also possible instead of 9 */ @@ -203,11 +204,11 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F')) return 1; - if(match_first_bytes(packet->payload, ".tem")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".tem")) return 1; - if(match_first_bytes(packet->payload, ".ite")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".ite")) return 1; - if(match_first_bytes(packet->payload, ".lef")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".lef")) return 1; return 0; @@ -229,7 +230,6 @@ static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct } void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; /* Break after 20 packets. */ if(flow->packet_counter > 20) { diff --git a/src/lib/protocols/git.c b/src/lib/protocols/git.c new file mode 100644 index 000000000..e156b7913 --- /dev/null +++ b/src/lib/protocols/git.c @@ -0,0 +1,83 @@ +/* + * git.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module 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. + * + * This module 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. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include <stdlib.h> +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_GIT + +#define GIT_PORT 9418 + +void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct * packet = &flow->packet; + + if((packet->tcp != NULL) && (packet->payload_packet_len > 4)) { + if((ntohs(packet->tcp->source) == GIT_PORT) + || (ntohs(packet->tcp->dest) == GIT_PORT)) { + const u_int8_t * pp = packet->payload; + u_int16_t payload_len = packet->payload_packet_len; + u_int8_t found_git = 1; + u_int16_t git_len = 0, offset = 0; + + while((offset+4) < payload_len) { + char len[5]; + u_int32_t git_pkt_len; + + memcpy(&len, &pp[offset], 4), len[4] = 0; + git_pkt_len = atoi(len); + + if((payload_len < git_pkt_len) || (git_pkt_len == 0 /* Bad */)) { + found_git = 0; + break; + } else + offset += git_pkt_len, payload_len -= git_pkt_len; + } + + if(found_git) { + NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "found Git.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GIT, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "exclude Git.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GIT); +} + + +/* ***************************************************************** */ + + +void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("Git", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_GIT, + ndpi_search_git, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_PROTOCOL_GIT */ diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c index 09d4d0852..e45096391 100644 --- a/src/lib/protocols/gnutella.c +++ b/src/lib/protocols/gnutella.c @@ -294,7 +294,7 @@ void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, stru return; } - if (memcmp(packet->payload, "GND", 3) == 0) { + if (packet->payload_packet_len >= 3 && memcmp(packet->payload, "GND", 3) == 0) { if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0)) || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5) == 0)) || (packet->payload_packet_len == 17 diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c index 97044f94e..88235f2a8 100644 --- a/src/lib/protocols/gtp.c +++ b/src/lib/protocols/gtp.c @@ -18,7 +18,6 @@ * */ - #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_GTP diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c index 1d503a747..31d578455 100644 --- a/src/lib/protocols/h323.c +++ b/src/lib/protocols/h323.c @@ -27,7 +27,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n"); /* H323 */ - if((packet->payload[0] == 0x03) + if(packet->payload_packet_len >= 3 + && (packet->payload[0] == 0x03) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { struct tpkt *t = (struct tpkt*)packet->payload; @@ -63,7 +64,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over udp.\n"); - if(packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) && + if(packet->payload_packet_len >= 6 && packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && + (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) { NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); @@ -79,7 +81,7 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); return; } - else if(packet->payload_packet_len >= 20 || packet->payload_packet_len <= 117) + else if(packet->payload_packet_len >= 20 && packet->payload_packet_len <= 117) { NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/hangout.c b/src/lib/protocols/hangout.c new file mode 100644 index 000000000..ca53a8814 --- /dev/null +++ b/src/lib/protocols/hangout.c @@ -0,0 +1,105 @@ +/* + * hangout.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module 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. + * + * This module 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. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include "ndpi_api.h" + +#ifdef NDPI_SERVICE_HANGOUT + +/* https://support.google.com/a/answer/1279090?hl=en */ +#define HANGOUT_UDP_LOW_PORT 19302 +#define HANGOUT_UDP_HIGH_PORT 19309 +#define HANGOUT_TCP_LOW_PORT 19305 +#define HANGOUT_TCP_HIGH_PORT 19309 + +/* ***************************************************************** */ + +static u_int8_t isHangoutUDPPort(u_int16_t port) { + if((port >= HANGOUT_UDP_LOW_PORT) && (port <= HANGOUT_UDP_HIGH_PORT)) + return(1); + else + return(0); +} + +/* ***************************************************************** */ + +static u_int8_t isHangoutTCPPort(u_int16_t port) { + if((port >= HANGOUT_TCP_LOW_PORT) && (port <= HANGOUT_TCP_HIGH_PORT)) + return(1); + else + return(0); +} + +/* ******************************************* */ + +static u_int8_t google_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) { + return((ndpi_network_ptree_match(ndpi_struct, pin) == NDPI_SERVICE_GOOGLE) ? 1 : 0); +} + +/* ******************************************* */ + +static u_int8_t is_google_flow(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->iph) { + if(google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->saddr) + || google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->daddr)) { + return(1); + } + } + + return(0); +} + +/* ***************************************************************** */ + +void ndpi_search_hangout(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct * packet = &flow->packet; + + if((packet->payload_packet_len > 24) && is_google_flow(ndpi_struct, flow)) { + if( + ((packet->udp != NULL) && (isHangoutUDPPort(ntohs(packet->udp->source)) || isHangoutUDPPort(ntohs(packet->udp->dest)))) + || + ((packet->tcp != NULL) && (isHangoutTCPPort(ntohs(packet->tcp->source)) || isHangoutTCPPort(ntohs(packet->tcp->dest))))) { + NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "Found Hangout.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_HANGOUT, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + + NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "No Hangout.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_HANGOUT); +} + +/* ***************************************************************** */ + +void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) { + ndpi_set_bitmask_protocol_detection("GoogleHangout", ndpi_struct, detection_bitmask, *id, + NDPI_SERVICE_HANGOUT, + ndpi_search_hangout, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_SERVICE_HANGOUT */ diff --git a/src/lib/protocols/kakaotalk_voice.c b/src/lib/protocols/kakaotalk_voice.c index c6972c7a1..368532c5d 100644 --- a/src/lib/protocols/kakaotalk_voice.c +++ b/src/lib/protocols/kakaotalk_voice.c @@ -33,7 +33,7 @@ void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struc if(packet->iph && packet->udp - && (packet->payload_packet_len > 0) + && (packet->payload_packet_len >= 4) ) { if((packet->payload[0] == 0x81) || (packet->payload[1] == 0xC8) diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c index c62c1d366..4e352583e 100644 --- a/src/lib/protocols/mail_imap.c +++ b/src/lib/protocols/mail_imap.c @@ -1,8 +1,7 @@ /* * mail_imap.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - 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 @@ -42,6 +41,15 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, /* const u_int8_t *command = 0; */ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n"); + + if (flow->l4.tcp.mail_imap_starttls == 2) { +#ifdef NDPI_PROTOCOL_SSL + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "starttls detected\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP); + NDPI_DEL_PROTOCOL_FROM_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL); + return; +#endif + } if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { // the DONE command appears without a tag @@ -62,7 +70,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, } if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') || (packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') || - (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) { + (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*' || packet->payload[i] == '.')) { goto imap_excluded; } i++; @@ -99,6 +107,8 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k') && packet->payload[command_start + 2] == ' ') { flow->l4.tcp.mail_imap_stage += 1; + if (flow->l4.tcp.mail_imap_starttls == 1) + flow->l4.tcp.mail_imap_starttls = 2; saw_command = 1; } else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u') && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i') @@ -131,8 +141,10 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't') && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l') && (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) { - flow->l4.tcp.mail_imap_stage += 1; - saw_command = 1; + flow->l4.tcp.mail_imap_stage += 1; + flow->l4.tcp.mail_imap_starttls = 1; + flow->detected_protocol_stack[0] = NDPI_PROTOCOL_MAIL_IMAPS; + saw_command = 1; } } if ((command_start + 5) < packet->payload_packet_len) { diff --git a/src/lib/protocols/mqtt.c b/src/lib/protocols/mqtt.c index 024fad8a7..37c469066 100644 --- a/src/lib/protocols/mqtt.c +++ b/src/lib/protocols/mqtt.c @@ -144,7 +144,7 @@ void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed second stage of identification\n"); // third stage verification (payload) if (pt == CONNECT) { - if (memcmp(&(packet->payload[4]),"MQTT",4) == 0) { + if (packet->payload_packet_len >= 8 && memcmp(&(packet->payload[4]),"MQTT",4) == 0) { NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found CONNECT\n"); ndpi_int_mqtt_add_connection(ndpi_struct,flow); return; diff --git a/src/lib/protocols/msn.c b/src/lib/protocols/msn.c index af537d7ff..ff81a12b3 100644 --- a/src/lib/protocols/msn.c +++ b/src/lib/protocols/msn.c @@ -130,7 +130,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d && get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) { /* The MSNP string is used in XBOX clients. */ - if (memcmp(packet->payload, "VER ", 4) == 0) { + if (ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "VER ")) { if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR", 3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) { @@ -139,7 +139,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct ndpi_int_msn_add_connection(ndpi_struct, flow); return; } - if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) { + if (ndpi_match_strprefix(&packet->payload[4], packet->payload_packet_len-4, "MSNFT")) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN FT by pattern VER MSNFT...0d0a.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow); @@ -153,8 +153,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif - memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 || - memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) { + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "GET ") || + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "POST ")) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") && @@ -277,8 +277,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif - (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || - (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.0 200 OK") || + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.1 200 OK") ) { ndpi_parse_packet_line_info(ndpi_struct, flow); diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c index 9c2283a81..ca649782b 100644 --- a/src/lib/protocols/netbios.c +++ b/src/lib/protocols/netbios.c @@ -324,7 +324,7 @@ void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n"); if(netbios_name_interpret((char*)&packet->payload[12], name, sizeof(name)) > 0) - snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name), "%s", name); + snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name)-1, "%s", name); ndpi_int_netbios_add_connection(ndpi_struct, flow); return; diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c index a0fa92a20..6e355c9f8 100644 --- a/src/lib/protocols/ntp.c +++ b/src/lib/protocols/ntp.c @@ -22,54 +22,44 @@ * */ - #include "ndpi_protocols.h" + #ifdef NDPI_PROTOCOL_NTP + static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_PROTOCOL_UNKNOWN); } -/* detection also works asymmetrically */ - void ndpi_search_ntp_udp(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->udp->dest == htons(123) || packet->udp->source == htons(123))) - goto exclude_ntp; - - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n"); - - // It's not correct because packets could be bigger - //if (packet->payload_packet_len != 48) - // goto exclude_ntp; - - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n"); - - - if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP."); + struct ndpi_packet_struct *packet = &flow->packet; + + if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123))) + goto exclude_ntp; + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n"); + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n"); + + + if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP."); - // 38 in binary representation is 00111000 - flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; - - if (flow->protos.ntp.version == 2) { - flow->protos.ntp.request_code = packet->payload[3]; - } - - ndpi_int_ntp_add_connection(ndpi_struct, flow); - return; - } - - - - exclude_ntp: + // 38 in binary representation is 00111000 + flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; + + if (flow->protos.ntp.version == 2) { + flow->protos.ntp.request_code = packet->payload[3]; + } + + ndpi_int_ntp_add_connection(ndpi_struct, flow); + return; + } + + exclude_ntp: NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NTP); } diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c index 9005dc3ff..3e8412355 100644 --- a/src/lib/protocols/openvpn.c +++ b/src/lib/protocols/openvpn.c @@ -1,68 +1,113 @@ /* - * h323.c + * openvpn.c * - * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * Copyright (C) 2011-16 - ntop.org + * + * OpenVPN TCP / UDP Detection - 128/160 hmac + * + * Detection based upon these openvpn protocol properties: + * - opcode + * - packet ID + * - session ID + * + * Two (good) packets are needed to perform detection. + * - First packet from client: save session ID + * - Second packet from server: report saved session ID + * + * TODO + * - Support PSK only mode (instead of TLS) + * - Support PSK + TLS mode (PSK used for early authentication) + * - TLS certificate extraction * */ #include "ndpi_api.h" - #ifdef NDPI_PROTOCOL_OPENVPN +#define P_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3) +#define P_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3) +#define P_CONTROL_HARD_RESET_SERVER_V1 (0x02 << 3) +#define P_CONTROL_HARD_RESET_SERVER_V2 (0x08 << 3) +#define P_OPCODE_MASK 0xF8 +#define P_SHA1_HMAC_SIZE 20 +#define P_HMAC_128 16 // (RSA-)MD5, (RSA-)MD4, ..others +#define P_HMAC_160 20 // (RSA-|DSA-)SHA(1), ..others, SHA1 is openvpn default +#define P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size) +#define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8) +#define P_HARD_RESET_CLIENT_MAX_COUNT 5 + +static inline u_int32_t get_packet_id(const u_int8_t * payload, u_int8_t hms) { + return ntohl(*(u_int32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms))); +} + +static inline int8_t check_pkid_and_detect_hmac_size(const u_int8_t * payload) { + // try to guess + if (get_packet_id(payload, P_HMAC_160) == 1) + return P_HMAC_160; + if (get_packet_id(payload, P_HMAC_128) == 1) + return P_HMAC_128; + return -1; +} + void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { struct ndpi_packet_struct* packet = &flow->packet; - u_int16_t dport = 0, sport = 0; - - if (packet->udp != NULL) { - - sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); - - if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) && - (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 && - packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn udp 443.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } - - if ( ( (packet->payload_packet_len > 40) || - (packet->payload_packet_len <= 14) ) && // hard-reset - (sport == 1194 || dport == 1194) && - (packet->payload[0] == 0x30 || packet->payload[0] == 0x31 || - packet->payload[0] == 0x32 || packet->payload[0] == 0x33 || - packet->payload[0] == 0x34 || packet->payload[0] == 0x35 || - packet->payload[0] == 0x36 || packet->payload[0] == 0x37 || - packet->payload[0] == 0x38 || packet->payload[0] == 0x39)) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn broadcast udp STD.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } - - } - - if (packet->tcp != NULL) { - - sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); - - if ((packet->payload_packet_len >= 40) && - (sport == 1194 || dport == 1194) && - ((packet->payload[0] == 0x00) && (packet->payload[1] == 0x2a) && - (packet->payload[2] == 0x38))) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn broadcast udp STD.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } + const u_int8_t * ovpn_payload = packet->payload; + const u_int8_t * session_remote; + u_int8_t opcode; + u_int8_t alen; + int8_t hmac_size; + int8_t failed = 0; + + if (packet->payload_packet_len >= 40) { + // skip openvpn TCP transport packet size + if (packet->tcp != NULL) + ovpn_payload += 2; + + opcode = ovpn_payload[0] & P_OPCODE_MASK; + + if (flow->ovpn_counter < P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 || + opcode == P_CONTROL_HARD_RESET_CLIENT_V2)) { + + if (check_pkid_and_detect_hmac_size(ovpn_payload) > 0) { + memcpy(flow->ovpn_session_id, ovpn_payload+1, 8); + + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "session key: %02x%02x%02x%02x%02x%02x%02x%02x\n", + flow->ovpn_session_id[0], flow->ovpn_session_id[1], flow->ovpn_session_id[2], flow->ovpn_session_id[3], + flow->ovpn_session_id[4], flow->ovpn_session_id[5], flow->ovpn_session_id[6], flow->ovpn_session_id[7]); + } + } else if (flow->ovpn_counter >= 1 && flow->ovpn_counter <= P_HARD_RESET_CLIENT_MAX_COUNT && + (opcode == P_CONTROL_HARD_RESET_SERVER_V1 || opcode == P_CONTROL_HARD_RESET_SERVER_V2)) { + + hmac_size = check_pkid_and_detect_hmac_size(ovpn_payload); + + if (hmac_size > 0) { + alen = ovpn_payload[P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size)]; + session_remote = ovpn_payload + P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) + 1 + alen * 4; + + if (memcmp(flow->ovpn_session_id, session_remote, 8) == 0) + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); + else { + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "key mismatch: %02x%02x%02x%02x%02x%02x%02x%02x\n", + session_remote[0], session_remote[1], session_remote[2], session_remote[3], + session_remote[4], session_remote[5], session_remote[6], session_remote[7]); + failed = 1; + } + } else + failed = 1; + } else + failed = 1; + + flow->ovpn_counter++; + + if (failed) + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN); } - - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN); } - void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, detection_bitmask, *id, diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c index a43394a8d..869b36378 100644 --- a/src/lib/protocols/oscar.c +++ b/src/lib/protocols/oscar.c @@ -244,10 +244,19 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct */ if (channel == DATA) { - family = get_u_int16_t(packet->payload, 6); - type = get_u_int16_t(packet->payload, 8); - flag = get_u_int16_t(packet->payload, 10); - req_ID = get_u_int32_t(packet->payload, 12); + if (packet->payload_packet_len >= 8) + family = get_u_int16_t(packet->payload, 6); + else + family = 0; + if (packet->payload_packet_len >= 10) + type = get_u_int16_t(packet->payload, 8); + else + type = 0; + if (family == 0 || type == 0) + { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); + return; + } /* Family 0x0001 */ if (family == htons(GE_SE_CTL)) @@ -561,16 +570,24 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct } /* flag */ - if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) - { - /* request ID */ - if((req_ID <= 4294967295)) + if (packet->payload_packet_len >= 12) + { + flag = get_u_int16_t(packet->payload, 10); + if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) + { + if (packet->payload_packet_len >= 16) { - NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); - ndpi_int_oscar_add_connection(ndpi_struct, flow); - return; + /* request ID */ + req_ID = get_u_int32_t(packet->payload, 12); + if((req_ID <= 4294967295)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } } - } + } + } } /* ERROR -> FLAP__ERROR_CHANNEL_0x03 diff --git a/src/lib/protocols/pando.c b/src/lib/protocols/pando.c index f3ed00783..b906e7ed9 100644 --- a/src/lib/protocols/pando.c +++ b/src/lib/protocols/pando.c @@ -34,7 +34,7 @@ static void ndpi_check_pando_tcp(struct ndpi_detection_module_struct *ndpi_struc struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x0ePan")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x0ePan")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } @@ -56,7 +56,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO 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. */ @@ -64,7 +64,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc return; } - if ((payload_len > 0) && (match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE"))) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO 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. */ @@ -98,7 +98,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len == 0) || match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE")) { + if ((payload_len == 0) || (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE"))) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } else { @@ -115,7 +115,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/pplive.c b/src/lib/protocols/pplive.c index cf9260f17..2e4747159 100644 --- a/src/lib/protocols/pplive.c +++ b/src/lib/protocols/pplive.c @@ -39,7 +39,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str if (flow->pplive_stage1 == 0) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE 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. */ @@ -47,7 +47,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x42\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE 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. */ @@ -55,7 +55,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE 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. */ @@ -72,7 +72,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && (match_first_bytes(packet->payload, "\xe9\x03\x42\x01") || match_first_bytes(packet->payload, "\xe9\x03\x41\x01"))) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01") || ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -89,7 +89,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -105,7 +105,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -124,7 +124,7 @@ static void ndpi_check_pplive_udp2(struct ndpi_detection_module_struct *ndpi_str if (flow->pplive_stage2 == 0) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); - if ((payload_len == 57) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if ((payload_len == 57) && ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE 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. */ diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 2bece25a7..8050a9b61 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1,11 +1,12 @@ /* * quic.c * + * Copyright (C) 2012-16 - ntop.org + * + * Based on code of: * Andrea Buscarinu - <andrea.buscarinu@gmail.com> * Michele Campus - <campus@ntop.org> * - * Copyright (C) 2012-15 - ntop.org - * * This module 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 @@ -21,164 +22,122 @@ * */ - #include "ndpi_api.h" -#define QUIC_NO_V_RES_RSV 0xC3 // 1100 0011 - -#define QUIC_CID_MASK 0x0C // 0000 1100 -#define QUIC_VER_MASK 0x01 // 0000 0001 -#define QUIC_SEQ_MASK 0x30 // 0011 0000 - -#define CID_LEN_8 0x0C // 0000 1100 -#define CID_LEN_4 0x08 // 0000 1000 -#define CID_LEN_1 0x04 // 0000 0100 -#define CID_LEN_0 0x00 // 0000 0000 - -#define SEQ_LEN_6 0x30 // 0011 0000 -#define SEQ_LEN_4 0x20 // 0010 0000 -#define SEQ_LEN_2 0x10 // 0001 0000 -#define SEQ_LEN_1 0x00 // 0000 0000 - -#define SEQ_CONV(ARR) (ARR[0] | ARR[1] | ARR[2] | ARR[3] | ARR[4] | ARR[5] << 8) - - #ifdef NDPI_PROTOCOL_QUIC -static void ndpi_int_quic_add_connection(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) + +static int quic_ports(u_int16_t sport, u_int16_t dport) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN); + if ((sport == 443 || dport == 443 || sport == 80 || dport == 80) && + (sport != 123 && dport != 123)) + return 1; + + return 0; } -static int connect_id(const unsigned char pflags) -{ - u_int cid_len; - - // Check CID length. - switch (pflags & QUIC_CID_MASK) - { - case CID_LEN_8: cid_len = 8; break; - case CID_LEN_4: cid_len = 4; break; - case CID_LEN_1: cid_len = 1; break; - case CID_LEN_0: cid_len = 0; break; - default: - return -1; - - } - // Return offset. - return cid_len + 1; +/* ***************************************************************** */ + +static int quic_len(u_int8_t l) { + switch(l) { + case 0: + return(1); + break; + case 1: + return(2); + break; + case 2: + return(4); + break; + case 3: + return(8); + break; + } + + return(0); /* NOTREACHED */ } -static int sequence(const unsigned char *payload) +/* ***************************************************************** */ + +void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { - unsigned char conv[6] = {0}; - u_int seq_value = -1; - int seq_lens; - int cid_offs; + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t udp_len = packet->payload_packet_len; + u_int version_len = ((packet->payload[0] & 0x01) == 0) ? 0 : 4; + u_int cid_len = quic_len((packet->payload[0] & 0x0C) >> 2); + u_int seq_len = quic_len((packet->payload[0] & 0x30) >> 4); + u_int quic_hlen = 1 /* flags */ + version_len + seq_len + cid_len; + + if(packet->udp != NULL + && (udp_len > (quic_hlen+4 /* QXXX */)) + && ((packet->payload[0] & 0xC2) == 0x00) + && (quic_ports(ntohs(packet->udp->source), ntohs(packet->udp->dest))) + ) { + char *begin; int i; - // Search SEQ bytes length. - switch (payload[0] & QUIC_SEQ_MASK) - { - case SEQ_LEN_6: seq_lens = 6; break; - case SEQ_LEN_4: seq_lens = 4; break; - case SEQ_LEN_2: seq_lens = 2; break; - case SEQ_LEN_1: seq_lens = 1; break; - default: - return -1; - } - // Retrieve SEQ offset. - cid_offs = connect_id(payload[0]); - - if (cid_offs >= 0 && seq_lens > 0) - { - for (i = 0; i < seq_lens; i++) - conv[i] = payload[cid_offs + i]; - - seq_value = SEQ_CONV(conv); - } - - // Return SEQ dec value; - return seq_value; -} + if((version_len > 0) && (packet->payload[1+cid_len] != 'Q')) + goto no_quic; -void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - int ver_offs; - - if(packet->udp != NULL) { - - u_int16_t sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); - - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "calculating quic over udp.\n"); - - if((((sport == 80) || (dport == 80) || (sport == 443) || (dport == 443)))) - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); - - - // Settings without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0. SEQ must be 1 at least. - if ((packet->payload[0] == 0x00 && packet->payload[1] != 0x00) || ((packet->payload[0] & QUIC_NO_V_RES_RSV) == 0)) - { - if (sequence(packet->payload) < 1) - { - - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); - } + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found QUIC.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN); - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); - ndpi_int_quic_add_connection(ndpi_struct, flow); - } + if(udp_len > quic_hlen + 17 + 4 && + !strncmp((char*)&packet->payload[quic_hlen+17], "CHLO" /* Client Hello */, 4)) { + /* Check if SNI (Server Name Identification) is present */ + for(i=quic_hlen+12; i<udp_len-3; i++) { + if((packet->payload[i] == 'S') + && (packet->payload[i+1] == 'N') + && (packet->payload[i+2] == 'I') + && (packet->payload[i+3] == 0)) { + u_int32_t offset = *((u_int32_t*)&packet->payload[i+4]); + u_int32_t prev_offset = *((u_int32_t*)&packet->payload[i-4]); + int len = offset-prev_offset; + int sni_offset = i+prev_offset+1; + + while((sni_offset < udp_len) && (packet->payload[sni_offset] == '-')) + sni_offset++; - // Check if version, than the CID length. - else if (packet->payload[0] & QUIC_VER_MASK) - { - // Skip CID length. - ver_offs = connect_id(packet->payload[0]); - - if (ver_offs >= 0) - { - unsigned char vers[] = {packet->payload[ver_offs], packet->payload[ver_offs + 1], - packet->payload[ver_offs + 2], packet->payload[ver_offs + 3]}; - - // Version Match. - if ((vers[0] == 'Q' && vers[1] == '0') && - ((vers[2] == '2' && (vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || - vers[3] == '1' || vers[3] == '0')) || - (vers[2] == '1' && (vers[3] == '9' || vers[3] == '8' || vers[3] == '7' || vers[3] == '6' || - vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || - vers[3] == '1' || vers[3] == '0')) || - (vers[2] == '0' && vers[3] == '9'))) - - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); - ndpi_int_quic_add_connection(ndpi_struct, flow); + if((sni_offset+len) < udp_len) { + int max_len = sizeof(flow->host_server_name)-1, j = 0; + + if(len > max_len) len = max_len; + + while((len > 0) && (sni_offset < udp_len)) { + flow->host_server_name[j++] = packet->payload[sni_offset]; + sni_offset++, len--; } + + ndpi_match_host_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name), + NDPI_PROTOCOL_QUIC); + } + + break; } - } - else - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } } + return; + } + + no_quic: + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude QUIC.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } +/* ***************************************************************** */ -void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) +void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) { - ndpi_set_bitmask_protocol_detection("Quic", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_QUIC, - ndpi_search_quic, + ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_QUIC, ndpi_search_quic, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); + SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } -#endif +#endif /* NDPI_PROTOCOL_QUIC */ diff --git a/src/lib/protocols/radius.c b/src/lib/protocols/radius.c index 625dc4108..308049522 100644 --- a/src/lib/protocols/radius.c +++ b/src/lib/protocols/radius.c @@ -37,12 +37,11 @@ static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, if(packet->udp != NULL) { struct radius_header *h = (struct radius_header*)packet->payload; - u_int len = ntohs(h->len); if((payload_len > sizeof(struct radius_header)) && (h->code > 0) && (h->code <= 5) - && (len == payload_len)) { + && (ntohs(h->len) == payload_len)) { NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "Found radius.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/rtcp.c b/src/lib/protocols/rtcp.c index c8fc90953..cc6265220 100644 --- a/src/lib/protocols/rtcp.c +++ b/src/lib/protocols/rtcp.c @@ -38,7 +38,7 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n /* Let's check first the RTCP packet length */ u_int16_t len, offset = 0, rtcp_section_len; - while(offset < packet->payload_packet_len) { + while(offset + 3 < packet->payload_packet_len) { len = packet->payload[2+offset] * 256 + packet->payload[2+offset+1]; rtcp_section_len = (len + 1) * 4; @@ -48,11 +48,11 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n offset += rtcp_section_len; } - sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); - if(((packet->payload_packet_len >= 28 || packet->payload_packet_len <= 1200) && + /* TODO changed a pair of length condition to the && from ||. Is it correct? */ + if(((packet->payload_packet_len >= 28 && packet->payload_packet_len <= 1200) && ((packet->payload[0] == 0x80) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00))) - || (((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) + || (packet->payload_packet_len >= 3 && ((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00)))) { NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n"); ndpi_int_rtcp_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c index 17744ed95..9bcaec941 100644 --- a/src/lib/protocols/rtp.c +++ b/src/lib/protocols/rtp.c @@ -73,6 +73,8 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t * payload, const u_int16_t payload_len) { + if (payload_len < 2) + return; //struct ndpi_packet_struct *packet = &flow->packet; u_int8_t payloadType, payload_type = payload[1] & 0x7F; u_int32_t *ssid = (u_int32_t*)&payload[8]; diff --git a/src/lib/protocols/rx.c b/src/lib/protocols/rx.c new file mode 100644 index 000000000..9d27d5e18 --- /dev/null +++ b/src/lib/protocols/rx.c @@ -0,0 +1,234 @@ +/* + * rx.c + * + * Copyright (C) 2012-16 - ntop.org + * + * Giovanni Mascellani <gio@debian.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_RX + +/* See http://web.mit.edu/kolya/afs/rx/rx-spec for procotol description. */ + +/* The should be no need for explicit packing, but just in case... */ +PACK_ON +struct ndpi_rx_header { + u_int32_t conn_epoch; + u_int32_t conn_id; + u_int32_t call_number; + u_int32_t sequence_number; + u_int32_t serial_number; + u_int8_t type; + u_int8_t flags; + u_int8_t status; + u_int8_t security; + u_int16_t checksum; + u_int16_t service_id; +} PACK_OFF; + +/* Type values */ +#define DATA 1 +#define ACK 2 +#define BUSY 3 +#define ABORT 4 +#define ACKALL 5 +#define CHALLENGE 6 +#define RESPONSE 7 +#define DEBUG 8 +#define PARAM_1 9 +#define PARAM_2 10 +#define PARAM_3 11 +#define PARAMS_4 12 +#define VERSION 13 + +/* Flags values */ +#define EMPTY 0 +#define CLIENT_INIT_1 1 +#define REQ_ACK 2 +#define PLUS_0 3 +#define LAST_PKT 4 +#define PLUS_1 5 +#define PLUS_2 6 +#define MORE_1 9 +#define CLIENT_INIT_2 33 + + + +void ndpi_check_rx(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; + int found = 0; + + + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "RX: pck: %d, dir[0]: %d, dir[1]: %d\n", + flow->packet_counter, flow->packet_direction_counter[0], flow->packet_direction_counter[1]); + + /* Check that packet is long enough */ + if (payload_len < sizeof(struct ndpi_rx_header)) { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + struct ndpi_rx_header *header = (struct ndpi_rx_header*) packet->payload; + + /** + * Useless check: a session could be detected also after it starts + * and this check limit the correct detection for -d option (disable guess) + * TODO - maybe to improve + **/ + /* Check whether the packet has counters beginning from one; the + Sequence Number can be zero if the packet is just an ACK. */ + /* if ((ntohl(header->sequence_number) | 1) != 1 || ntohl(header->serial_number) != 1) */ + + + /** + * Check the TYPE and FLAGS fields of an RX packet header. + * This check is necessary because we could detect an RX session already begun + **/ + + /* TYPE field */ + if((header->type < DATA) || (header->type > VERSION)) { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + /* FLAGS fields */ + if(header->flags == EMPTY || header->flags == LAST_PKT || + header->flags == PLUS_0 || header->flags == PLUS_1 || + header->flags == PLUS_2 || header->flags == REQ_ACK || + header->flags == MORE_1 || header->flags == CLIENT_INIT_1 || + header->flags == CLIENT_INIT_2) { + + /* TYPE and FLAGS combo */ + switch(header->type) + { + case DATA: + if(header->flags == LAST_PKT || header->flags == EMPTY || + header->flags == PLUS_0 || header->flags == PLUS_1 || + header->flags == PLUS_2 || header->flags == REQ_ACK || + header->flags == MORE_1) + goto security; + case ACK: + if(header->flags == CLIENT_INIT_1 || header->flags == CLIENT_INIT_2 || + header->flags == EMPTY) + goto security; + case CHALLENGE: + if(header->flags == EMPTY || header->call_number == 0) + goto security; + case RESPONSE: + if(header->flags == EMPTY || header->call_number == 0) + goto security; + case ACKALL: + if(header->flags == EMPTY) + goto security; + case BUSY: + goto security; + case ABORT: + goto security; + case DEBUG: + goto security; + case PARAM_1: + goto security; + case PARAM_2: + goto security; + case PARAM_3: + goto security; + case VERSION: + goto security; + default: + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } // switch + } else { // FLAG + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + security: + /* SECURITY field */ + if(header->security > 3) + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + /* If we have already seen one packet in the other direction, then + the two must have matching connection numbers. Otherwise store + them. */ + if(flow->packet_direction_counter[!packet->packet_direction] != 0) + { + if (flow->l4.udp.rx_conn_epoch == header->conn_epoch && + flow->l4.udp.rx_conn_id == header->conn_id) + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN); + } + /* https://www.central.org/frameless/numbers/rxservice.html. */ + else + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + } else { + flow->l4.udp.rx_conn_epoch = header->conn_epoch; + flow->l4.udp.rx_conn_id = header->conn_id; + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN); + } + } +} + +void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "entering RX search\n"); + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RX) { + ndpi_check_rx(ndpi_struct, flow); + } +} + +void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, + u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("RX", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_RX, + ndpi_search_rx, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c index 274312163..e7dac5d66 100644 --- a/src/lib/protocols/spotify.c +++ b/src/lib/protocols/spotify.c @@ -54,7 +54,7 @@ static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct, } } else if(packet->tcp != NULL) { - if(packet->payload[0] == 0x00 && packet->payload[1] == 0x04 && + if(payload_len >= 8 && packet->payload[0] == 0x00 && packet->payload[1] == 0x04 && packet->payload[2] == 0x00 && packet->payload[3] == 0x00&& packet->payload[6] == 0x52 && packet->payload[7] == 0x0e && packet->payload[8] == 0x50 ) { diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c index 2269ae782..5632741e5 100644 --- a/src/lib/protocols/ssl.c +++ b/src/lib/protocols/ssl.c @@ -1,8 +1,7 @@ /* * ssl.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - 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 @@ -35,6 +34,52 @@ extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, u_int32_t protocol) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if((flow->protos.ssl.client_certificate[0] != '\0') + || (flow->protos.ssl.server_certificate[0] != '\0') + || (flow->host_server_name[0] != '\0')) + protocol = NDPI_PROTOCOL_SSL; + else + protocol = NDPI_PROTOCOL_SSL_NO_CERT; + + if(packet->tcp != NULL) { + switch(protocol) { + + case NDPI_PROTOCOL_SSL: + case NDPI_PROTOCOL_SSL_NO_CERT: + { + /* + In case of SSL there are probably sub-protocols + such as IMAPS that can be otherwise detected + */ + u_int16_t sport = ntohs(packet->tcp->source); + u_int16_t dport = ntohs(packet->tcp->dest); + + if((sport == 465) || (dport == 465)) + protocol = NDPI_PROTOCOL_MAIL_SMTPS; + else if((sport == 993) || (dport == 993) +#ifdef NDPI_PROTOCOL_MAIL_IMAP + || (flow->l4.tcp.mail_imap_starttls) +#endif + ) protocol = NDPI_PROTOCOL_MAIL_IMAPS; + else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; + } + break; + } + + if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) + && is_skype_flow(ndpi_struct, flow)) { + protocol = NDPI_PROTOCOL_SKYPE; + } + } + + return protocol; +} + static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int32_t protocol) { @@ -42,40 +87,7 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp && (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) { ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } else { - struct ndpi_packet_struct *packet = &flow->packet; - - if((flow->protos.ssl.client_certificate[0] != '\0') - || (flow->protos.ssl.server_certificate[0] != '\0') - || (flow->host_server_name[0] != '\0')) - protocol = NDPI_PROTOCOL_SSL; - else - protocol = NDPI_PROTOCOL_SSL_NO_CERT; - - if(packet->tcp != NULL) { - switch(protocol) { - case NDPI_PROTOCOL_SSL: - case NDPI_PROTOCOL_SSL_NO_CERT: - { - /* - In case of SSL there are probably sub-protocols - such as IMAPS that can be otherwise detected - */ - u_int16_t sport = ntohs(packet->tcp->source); - u_int16_t dport = ntohs(packet->tcp->dest); - - if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS; - else if((sport == 993) || (dport == 993)) protocol = NDPI_PROTOCOL_MAIL_IMAPS; - else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; - } - break; - } - - if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) - && is_skype_flow(ndpi_struct, flow)) { - protocol = NDPI_PROTOCOL_SKYPE; - } - } - + protocol = ndpi_ssl_refine_master_protocol(ndpi_struct, flow, protocol); ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } } @@ -86,20 +98,20 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp #define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9') #define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' ')) #define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e) -#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ - ((ch) >= ':' && (ch) <= '@') || \ - ((ch) >= '[' && (ch) <= '`') || \ - ((ch) >= '{' && (ch) <= '~')) +#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ + ((ch) >= ':' && (ch) <= '@') || \ + ((ch) >= '[' && (ch) <= '`') || \ + ((ch) >= '{' && (ch) <= '~')) static void stripCertificateTrailer(char *buffer, int buffer_len) { - + int i, is_puny; - + // printf("->%s<-\n", buffer); - + for(i = 0; i < buffer_len; i++) { // printf("%c [%d]\n", buffer[i], buffer[i]); - + if((buffer[i] != '.') && (buffer[i] != '-') && (buffer[i] != '*') @@ -153,7 +165,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Nothing matched so far: let's decode the certificate with some heuristics Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com> - */ + */ if(packet->payload[0] == 0x16 /* Handshake */) { u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */; u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */ @@ -162,7 +174,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Truncate total len, search at least in incomplete packet */ if(total_len > packet->payload_packet_len) - total_len = packet->payload_packet_len; + total_len = packet->payload_packet_len; /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ if(total_len > 4) { @@ -223,69 +235,74 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, } } else if(handshake_protocol == 0x01 /* Client Hello */) { u_int offset, base_offset = 43; - u_int16_t session_id_len = packet->payload[base_offset]; + if (base_offset + 2 <= packet->payload_packet_len) + { + u_int16_t session_id_len = packet->payload[base_offset]; - if((session_id_len+base_offset+2) <= total_len) { - u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); - offset = base_offset + session_id_len + cypher_len + 2; + if((session_id_len+base_offset+2) <= total_len) { + u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); + offset = base_offset + session_id_len + cypher_len + 2; - flow->l4.tcp.ssl_seen_client_cert = 1; + flow->l4.tcp.ssl_seen_client_cert = 1; - if(offset < total_len) { - u_int16_t compression_len; - u_int16_t extensions_len; + if(offset < total_len) { + u_int16_t compression_len; + u_int16_t extensions_len; - compression_len = packet->payload[offset+1]; - offset += compression_len + 3; + compression_len = packet->payload[offset+1]; + offset += compression_len + 3; - if(offset < total_len) { - extensions_len = packet->payload[offset]; + if(offset < total_len) { + extensions_len = packet->payload[offset]; - if((extensions_len+offset) < total_len) { - u_int16_t extension_offset = 1; /* Move to the first extension */ + if((extensions_len+offset) < total_len) { + /* Move to the first extension + Type is u_int to avoid possible overflow on extension_len addition */ + u_int extension_offset = 1; - while(extension_offset < extensions_len) { - u_int16_t extension_id, extension_len; + while(extension_offset < extensions_len) { + u_int16_t extension_id, extension_len; - memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); + extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); - if(extension_id == 0) { - u_int begin = 0,len; - char *server_name = (char*)&packet->payload[offset+extension_offset]; + if(extension_id == 0) { + u_int begin = 0,len; + char *server_name = (char*)&packet->payload[offset+extension_offset]; - while(begin < extension_len) { - if((!ndpi_isprint(server_name[begin])) - || ndpi_ispunct(server_name[begin]) - || ndpi_isspace(server_name[begin])) - begin++; - else - break; - } + while(begin < extension_len) { + if((!ndpi_isprint(server_name[begin])) + || ndpi_ispunct(server_name[begin]) + || ndpi_isspace(server_name[begin])) + begin++; + else + break; + } - len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); - strncpy(buffer, &server_name[begin], len); - buffer[len] = '\0'; - stripCertificateTrailer(buffer, buffer_len); + len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); + strncpy(buffer, &server_name[begin], len); + buffer[len] = '\0'; + stripCertificateTrailer(buffer, buffer_len); - snprintf(flow->protos.ssl.client_certificate, - sizeof(flow->protos.ssl.client_certificate), "%s", buffer); + snprintf(flow->protos.ssl.client_certificate, + sizeof(flow->protos.ssl.client_certificate), "%s", buffer); - /* We're happy now */ - return(2 /* Client Certificate */); - } + /* We're happy now */ + return(2 /* Client Certificate */); + } - extension_offset += extension_len; + extension_offset += extension_len; + } + } } } } } - } } } } @@ -312,11 +329,14 @@ int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_s #ifdef CERTIFICATE_DEBUG printf("***** [SSL] %s\n", certificate); #endif - - if(ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, - strlen(certificate), - NDPI_PROTOCOL_SSL) != NDPI_PROTOCOL_UNKNOWN) + u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, + strlen(certificate), NDPI_PROTOCOL_SSL); + + if(subproto != NDPI_PROTOCOL_UNKNOWN) { + ndpi_set_detected_protocol(ndpi_struct, flow, subproto, + ndpi_ssl_refine_master_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL)); return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */ + } #ifdef NDPI_PROTOCOL_TOR if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0) @@ -366,7 +386,7 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK - (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { + (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); return; } @@ -375,18 +395,18 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct #endif #ifdef NDPI_PROTOCOL_OSCAR if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' - || packet->payload[a] == 'h') { + || packet->payload[a] == 'h') { if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) - // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) - // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) - || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) - || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) - || ((a + 41) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) - || ((a + 28) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) - || ((a + 32) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { + // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) + // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) + || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) + || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) + || ((a + 41) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) + || ((a + 28) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) + || ((a + 32) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); if(flow->dst != NULL && packet->payload_packet_len > 75) { @@ -402,8 +422,8 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(packet->payload[a] == 'm' || packet->payload[a] == 's') { if((a + 21) < packet->payload_packet_len && - (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 - || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { + (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 + || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; @@ -438,13 +458,13 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if((packet->payload_packet_len >= 5) - && (packet->payload[0] == 0x16) - && (packet->payload[1] == 0x03) - && ((packet->payload[2] == 0x00) - || (packet->payload[2] == 0x01) - || (packet->payload[2] == 0x02) - || (packet->payload[2] == 0x03) - )) { + && (packet->payload[0] == 0x16) + && (packet->payload[1] == 0x03) + && ((packet->payload[2] == 0x00) + || (packet->payload[2] == 0x01) + || (packet->payload[2] == 0x02) + || (packet->payload[2] == 0x03) + )) { u_int32_t temp; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n"); // SSLv3 Record @@ -454,7 +474,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp - || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { + || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { return 1; } @@ -499,7 +519,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16) - && packet->payload[temp + 1] == 0x03) { + && packet->payload[temp + 1] == 0x03) { u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -510,7 +530,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -521,7 +541,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -590,16 +610,16 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - packet->payload[1] == 2)) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - packet->payload[1] == 2)) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; return; } if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03 - && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) - && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { + && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) + && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { // SSLv3 Record NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; @@ -608,8 +628,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc } if(packet->payload_packet_len > 40 && - flow->l4.tcp.ssl_stage == 1 + packet->packet_direction - && flow->packet_direction_counter[packet->packet_direction] < 5) { + flow->l4.tcp.ssl_stage == 1 + packet->packet_direction + && flow->packet_direction_counter[packet->packet_direction] < 5) { return; } @@ -617,8 +637,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - 2) >= packet->payload[1]) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - 2) >= packet->payload[1]) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n"); ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); return; diff --git a/src/lib/protocols/starcraft.c b/src/lib/protocols/starcraft.c index f96853f23..760578563 100644 --- a/src/lib/protocols/starcraft.c +++ b/src/lib/protocols/starcraft.c @@ -49,9 +49,8 @@ u_int8_t ndpi_check_starcraft_tcp(struct ndpi_detection_module_struct* ndpi_stru { if (sc2_match_logon_ip(&flow->packet) && flow->packet.tcp->dest == htons(1119) //bnetgame port - && flow->packet.payload_packet_len >= 10 - && (match_first_bytes(flow->packet.payload, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") - || match_first_bytes(flow->packet.payload, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) + && (ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") + || ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) return 1; else return -1; diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c index 7ed0eae29..d12a0cb4b 100644 --- a/src/lib/protocols/steam.c +++ b/src/lib/protocols/steam.c @@ -50,7 +50,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc if (flow->steam_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM 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. */ @@ -58,7 +58,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc return; } - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM 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. */ @@ -74,7 +74,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -90,7 +90,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -104,7 +104,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; - if ((payload_len > 0) && match_first_bytes(packet->payload, "VS01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "VS01")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); return; @@ -114,7 +114,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru if (flow->steam_stage1 == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM 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. */ @@ -122,7 +122,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM 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. */ @@ -139,7 +139,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -156,7 +156,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -175,7 +175,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru if (flow->steam_stage2 == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if ((payload_len == 25) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if ((payload_len == 25) && ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM 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. */ @@ -191,7 +191,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len == 0) || match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if ((payload_len == 0) || ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/teredo.c b/src/lib/protocols/teredo.c index 9fb2c6483..079d1fbcd 100644 --- a/src/lib/protocols/teredo.c +++ b/src/lib/protocols/teredo.c @@ -29,6 +29,8 @@ void ndpi_search_teredo(struct ndpi_detection_module_struct *ndpi_struct, struct struct ndpi_packet_struct *packet = &flow->packet; if(packet->udp + && packet->iph + && ((ntohl(packet->iph->daddr) & 0xF0000000) == 0xE0000000 /* A multicast address */) && ((ntohs(packet->udp->source) == 3544) || (ntohs(packet->udp->dest) == 3544)) && (packet->payload_packet_len >= 40 /* IPv6 header */)) ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEREDO, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c index 7903bf511..2152da328 100644 --- a/src/lib/protocols/tor.c +++ b/src/lib/protocols/tor.c @@ -1,7 +1,7 @@ /* * tor.c * - * Copyright (C) 2015 ntop.org + * Copyright (C) 2016 ntop.org * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> * */ @@ -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); @@ -39,10 +39,11 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, len = strlen(name); - if(len > 6) { + if(len >= 5) { for(i = 0; name[i+1] != '\0'; i++) { + // printf("***** [SSL] %s(): [%d][%c]", __FUNCTION__, i, name[i]); + if((name[i] >= '0') && (name[i] <= '9')) { - if(prev_num != 1) { numbers_found++; |