diff options
Diffstat (limited to 'src/lib/protocols')
262 files changed, 4594 insertions, 5634 deletions
diff --git a/src/lib/protocols/activision.c b/src/lib/protocols/activision.c index ac24ee80f..42503966a 100644 --- a/src/lib/protocols/activision.c +++ b/src/lib/protocols/activision.c @@ -45,7 +45,7 @@ static void ndpi_search_activision(struct ndpi_detection_module_struct *ndpi_str if (packet->payload_packet_len < 18) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -55,20 +55,20 @@ static void ndpi_search_activision(struct ndpi_detection_module_struct *ndpi_str { if (ntohs(get_u_int16_t(packet->payload, 0)) != 0x0c02) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } else { if (ntohs(get_u_int16_t(packet->payload, 0)) != 0x0d02) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } if (packet->payload_packet_len < 29) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -81,13 +81,13 @@ static void ndpi_search_activision(struct ndpi_detection_module_struct *ndpi_str } else if (packet->packet_direction == 0) { if (packet->payload[0] != 0x29) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } else if (packet->packet_direction == 1) { if (packet->payload[0] != 0x28) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -98,16 +98,10 @@ static void ndpi_search_activision(struct ndpi_detection_module_struct *ndpi_str } } -void init_activision_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_activision_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Activision", ndpi_struct, *id, - NDPI_PROTOCOL_ACTIVISION, - ndpi_search_activision, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Activision", ndpi_struct, + ndpi_search_activision, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ACTIVISION); } diff --git a/src/lib/protocols/afp.c b/src/lib/protocols/afp.c index 73d623457..4560ac71a 100644 --- a/src/lib/protocols/afp.c +++ b/src/lib/protocols/afp.c @@ -2,7 +2,7 @@ * afp.c * * Copyright (C) 2009-11 by ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -58,7 +58,7 @@ static void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, st as they are not an indication that this flow is not AFP */ if(flow->packet_counter > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -72,18 +72,15 @@ static void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("AFP", ndpi_struct, *id, - NDPI_PROTOCOL_AFP, - ndpi_search_afp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("AFP", ndpi_struct, + ndpi_search_afp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_AFP); } diff --git a/src/lib/protocols/ajp.c b/src/lib/protocols/ajp.c index 4d8768890..9d1db7485 100644 --- a/src/lib/protocols/ajp.c +++ b/src/lib/protocols/ajp.c @@ -72,7 +72,7 @@ static void ndpi_check_ajp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_packet_struct *packet = &ndpi_struct->packet; if (packet->payload_packet_len < sizeof(ajp_hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -89,7 +89,7 @@ static void ndpi_check_ajp(struct ndpi_detection_module_struct *ndpi_struct, } else { NDPI_LOG_DBG(ndpi_struct, "Invalid AJP request type"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } else if (ajp_hdr.len > 0 && ajp_hdr.magic == AJP_CONTAINER_TO_SERVER) { if (ajp_hdr.code == AJP_SEND_BODY_CHUNK || ajp_hdr.code == AJP_SEND_HEADERS @@ -100,11 +100,11 @@ static void ndpi_check_ajp(struct ndpi_detection_module_struct *ndpi_struct, } else { NDPI_LOG_DBG(ndpi_struct, "Invalid AJP response type"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } else { NDPI_LOG_DBG(ndpi_struct,"Invalid AJP packet\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } @@ -120,14 +120,10 @@ static void ndpi_search_ajp(struct ndpi_detection_module_struct *ndpi_struct, /* ********************************* */ -void init_ajp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ajp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("AJP", ndpi_struct, - *id, NDPI_PROTOCOL_AJP, ndpi_search_ajp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("AJP", ndpi_struct, + ndpi_search_ajp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_AJP); } diff --git a/src/lib/protocols/alicloud.c b/src/lib/protocols/alicloud.c index 9ec87f3ec..7c4cb8ce1 100644 --- a/src/lib/protocols/alicloud.c +++ b/src/lib/protocols/alicloud.c @@ -44,7 +44,7 @@ static void ndpi_search_alicloud(struct ndpi_detection_module_struct *ndpi_struc if (packet->payload_packet_len < 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -64,20 +64,14 @@ static void ndpi_search_alicloud(struct ndpi_detection_module_struct *ndpi_struc if (flow->packet_counter > 3) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_alicloud_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_alicloud_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("AliCloud", ndpi_struct, *id, - NDPI_PROTOCOL_ALICLOUD, - ndpi_search_alicloud, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("AliCloud", ndpi_struct, + ndpi_search_alicloud, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ALICLOUD); } diff --git a/src/lib/protocols/amazon_video.c b/src/lib/protocols/amazon_video.c index bbb446eb3..1e6ce8f82 100644 --- a/src/lib/protocols/amazon_video.c +++ b/src/lib/protocols/amazon_video.c @@ -54,7 +54,7 @@ static void ndpi_check_amazon_video(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, @@ -65,13 +65,9 @@ static void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_s } -void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("AMAZON_VIDEO", ndpi_struct, *id, - NDPI_PROTOCOL_AMAZON_VIDEO, - ndpi_search_amazon_video, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("AMAZON_VIDEO", ndpi_struct, + ndpi_search_amazon_video, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_AMAZON_VIDEO); } diff --git a/src/lib/protocols/among_us.c b/src/lib/protocols/among_us.c index 9cc90ac38..5c0707a68 100644 --- a/src/lib/protocols/among_us.c +++ b/src/lib/protocols/among_us.c @@ -43,16 +43,15 @@ static void ndpi_search_among_us(struct ndpi_detection_module_struct *ndpi_struc { ndpi_int_among_us_add_connection(ndpi_struct, flow); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_among_us_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_among_us_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection( - "AmongUs", ndpi_struct, *id, - NDPI_PROTOCOL_AMONG_US, ndpi_search_among_us, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("AmongUs", ndpi_struct, + ndpi_search_among_us, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_AMONG_US); } diff --git a/src/lib/protocols/amqp.c b/src/lib/protocols/amqp.c index ce0397e70..299579975 100644 --- a/src/lib/protocols/amqp.c +++ b/src/lib/protocols/amqp.c @@ -1,7 +1,7 @@ /* * amqp.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -69,18 +69,14 @@ static void ndpi_search_amqp(struct ndpi_detection_module_struct *ndpi_struct, s } if(flow->packet_counter > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_amqp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("AMQP", ndpi_struct, *id, - NDPI_PROTOCOL_AMQP, - ndpi_search_amqp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_amqp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("AMQP", ndpi_struct, + ndpi_search_amqp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_AMQP); } diff --git a/src/lib/protocols/apple_push.c b/src/lib/protocols/apple_push.c index 6cc233f61..0df85e580 100644 --- a/src/lib/protocols/apple_push.c +++ b/src/lib/protocols/apple_push.c @@ -83,7 +83,7 @@ static void ndpi_check_apple_push(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_apple_push(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -94,14 +94,11 @@ static void ndpi_search_apple_push(struct ndpi_detection_module_struct *ndpi_str } -void init_apple_push_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_apple_push_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("APPLE_PUSH", ndpi_struct, *id, - NDPI_PROTOCOL_APPLE_PUSH, - ndpi_search_apple_push, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("APPLE_PUSH", ndpi_struct, + ndpi_search_apple_push, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_APPLE_PUSH); } diff --git a/src/lib/protocols/armagetron.c b/src/lib/protocols/armagetron.c index d9cdd1b20..33c4fec2f 100644 --- a/src/lib/protocols/armagetron.c +++ b/src/lib/protocols/armagetron.c @@ -2,7 +2,7 @@ * armagetron.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,69 +42,39 @@ static void ndpi_search_armagetron_udp(struct ndpi_detection_module_struct *ndpi NDPI_LOG_DBG(ndpi_struct, "search armagetron\n"); - if (packet->payload_packet_len > 10) { + if (packet->payload_packet_len >= 8) { /* login request */ if (get_u_int32_t(packet->payload, 0) == htonl(0x000b0000)) { const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); - if (dataLength == 0 || dataLength * 2 + 8 != packet->payload_packet_len) - goto exclude; - if (get_u_int16_t(packet->payload, 6) == htons(0x0008) - && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { + if (dataLength * 2 + 8 == packet->payload_packet_len && + get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { NDPI_LOG_INFO(ndpi_struct, "found armagetron\n"); ndpi_int_armagetron_add_connection(ndpi_struct, flow); return; } } - /* sync_msg */ - if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x001c) - && get_u_int16_t(packet->payload, 2) != 0) { + /* big_server/big_request */ + if (get_u_int32_t(packet->payload, 0) == htonl(0x00330000) || + get_u_int32_t(packet->payload, 0) == htonl(0x00350000)) { const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); - if (dataLength != 4) - goto exclude; - if (get_u_int32_t(packet->payload, 6) == htonl(0x00000500) && get_u_int32_t(packet->payload, 6 + 4) == htonl(0x00010000) - && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { + if (dataLength * 2 + 8 == packet->payload_packet_len && + get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { NDPI_LOG_INFO(ndpi_struct, "found armagetron\n"); ndpi_int_armagetron_add_connection(ndpi_struct, flow); return; } } - - /* net_sync combination */ - if (packet->payload_packet_len > 50 && get_u_int16_t(packet->payload, 0) == htons(0x0018) - && get_u_int16_t(packet->payload, 2) != 0) { - u_int16_t val; - const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); - if (dataLength == 0 || dataLength * 2 + 8 > packet->payload_packet_len) - goto exclude; - val = get_u_int16_t(packet->payload, 6 + 2); - if (val == get_u_int16_t(packet->payload, 6 + 6)) { - val = ntohs(get_u_int16_t(packet->payload, 6 + 8)); - if ((6 + 10 + val + 4) < packet->payload_packet_len - && (get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00010000) - || get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00000001)) - && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found armagetron\n"); - ndpi_int_armagetron_add_connection(ndpi_struct, flow); - return; - } - } - } } - exclude: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_armagetron_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_armagetron_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Armagetron", ndpi_struct, *id, - NDPI_PROTOCOL_ARMAGETRON, - ndpi_search_armagetron_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Armagetron", ndpi_struct, + ndpi_search_armagetron_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ARMAGETRON); } diff --git a/src/lib/protocols/atg.c b/src/lib/protocols/atg.c index cc25a70ce..5dd30aa28 100644 --- a/src/lib/protocols/atg.c +++ b/src/lib/protocols/atg.c @@ -52,16 +52,12 @@ static void ndpi_search_atg(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_atg_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("ATG", ndpi_struct, *id, - NDPI_PROTOCOL_ATG, - ndpi_search_atg, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_atg_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("ATG", ndpi_struct, + ndpi_search_atg, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ATG); } diff --git a/src/lib/protocols/avast.c b/src/lib/protocols/avast.c index 388538dea..d7ead6892 100644 --- a/src/lib/protocols/avast.c +++ b/src/lib/protocols/avast.c @@ -39,7 +39,7 @@ static void ndpi_search_avast(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 6) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -50,18 +50,13 @@ static void ndpi_search_avast(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_avast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_avast_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("AVAST", - ndpi_struct, *id, - NDPI_PROTOCOL_AVAST, - ndpi_search_avast, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("AVAST", ndpi_struct, + ndpi_search_avast, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_AVAST); } diff --git a/src/lib/protocols/avast_securedns.c b/src/lib/protocols/avast_securedns.c index c42a39736..d5d850457 100644 --- a/src/lib/protocols/avast_securedns.c +++ b/src/lib/protocols/avast_securedns.c @@ -41,7 +41,7 @@ static void ndpi_search_avast_securedns(struct ndpi_detection_module_struct *ndp ntohl(get_u_int32_t(packet->payload, 11)) != 0x00013209 || flow->packet_counter > 1) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -51,18 +51,13 @@ static void ndpi_search_avast_securedns(struct ndpi_detection_module_struct *ndp return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_avast_securedns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_avast_securedns_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("AVAST SecureDNS", - ndpi_struct, *id, - NDPI_PROTOCOL_AVAST_SECUREDNS, - ndpi_search_avast_securedns, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("AVAST SecureDNS", ndpi_struct, + ndpi_search_avast_securedns, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_AVAST_SECUREDNS); } diff --git a/src/lib/protocols/bacnet.c b/src/lib/protocols/bacnet.c index b79455d1e..df0ebcc66 100644 --- a/src/lib/protocols/bacnet.c +++ b/src/lib/protocols/bacnet.c @@ -60,25 +60,25 @@ static void ndpi_search_bacnet(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < sizeof(*bvlc)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (bvlc->type != 0x81) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (bvlc->function > 0x0b) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (ntohs(bvlc->length) != packet->payload_packet_len) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -87,16 +87,10 @@ static void ndpi_search_bacnet(struct ndpi_detection_module_struct *ndpi_struct, /* ***************************************************** */ -void init_bacnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_bacnet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BACnet", ndpi_struct, *id, - NDPI_PROTOCOL_BACNET, - ndpi_search_bacnet, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("BACnet", ndpi_struct, + ndpi_search_bacnet, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_BACNET); } diff --git a/src/lib/protocols/beckhoff_ads.c b/src/lib/protocols/beckhoff_ads.c index b976b873d..c6fa4ce52 100644 --- a/src/lib/protocols/beckhoff_ads.c +++ b/src/lib/protocols/beckhoff_ads.c @@ -109,17 +109,13 @@ static void ndpi_search_beckhoff_ads(struct ndpi_detection_module_struct *ndpi_s } not_beckhoff_ads: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_beckhoff_ads_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_beckhoff_ads_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BeckhoffADS", ndpi_struct, *id, - NDPI_PROTOCOL_BECKHOFF_ADS, - ndpi_search_beckhoff_ads, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("BeckhoffADS", ndpi_struct, + ndpi_search_beckhoff_ads, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BECKHOFF_ADS); } diff --git a/src/lib/protocols/bfcp.c b/src/lib/protocols/bfcp.c index b2bd52bdb..8e7917b28 100644 --- a/src/lib/protocols/bfcp.c +++ b/src/lib/protocols/bfcp.c @@ -43,43 +43,44 @@ static void ndpi_search_bfcp(struct ndpi_detection_module_struct *ndpi_struct, } u_int8_t version = (packet->payload[0] >> 5) & 0x07; - u_int8_t reserved = (packet->payload[0] >> 3) & 0x01; + u_int8_t reserved = (packet->payload[0] & 0x03); - if (version != 1 || reserved != 0) { + /* RFC4582: 1 + RFC8855: 1 on TCP, 2 on UDP */ + if (!(version == 1 || + (version == 2 && flow->l4_proto == IPPROTO_UDP))) { + goto not_bfcp; + } + if (reserved != 0) { goto not_bfcp; } u_int8_t primitive = packet->payload[1]; - if (primitive < 1 || primitive > 17) { + if (primitive < 1 || primitive > 18) { goto not_bfcp; } - u_int32_t conference_id = ntohl(get_u_int32_t(packet->payload, 4)); - if (!flow->bfcp_stage) { - flow->bfcp_conference_id = conference_id; - flow->bfcp_stage = 1; - return; + u_int16_t length = ntohs(get_u_int16_t(packet->payload, 2)); + if (12 + length * 4 != packet->payload_packet_len) { + goto not_bfcp; } - if (flow->bfcp_stage && flow->bfcp_conference_id == conference_id) { - NDPI_LOG_INFO(ndpi_struct, "found BFCP\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BFCP, - NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - return; - } + NDPI_LOG_INFO(ndpi_struct, "found BFCP\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BFCP, + NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + + flow->protos.bfcp.conference_id = ntohl(get_u_int32_t(packet->payload, 4)); + flow->protos.bfcp.user_id = ntohs(get_u_int16_t(packet->payload, 10)); + return; not_bfcp: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_bfcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_bfcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BFCP", ndpi_struct, *id, - NDPI_PROTOCOL_BFCP, - ndpi_search_bfcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("BFCP", ndpi_struct, + ndpi_search_bfcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BFCP); } diff --git a/src/lib/protocols/bfd.c b/src/lib/protocols/bfd.c index eb7eb82e9..23b738c63 100644 --- a/src/lib/protocols/bfd.c +++ b/src/lib/protocols/bfd.c @@ -66,17 +66,12 @@ static void ndpi_search_bfd(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_bfd_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_bfd_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BFD", ndpi_struct, *id, - NDPI_PROTOCOL_BFD, - ndpi_search_bfd, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("BFD", ndpi_struct, + ndpi_search_bfd, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_BFD); } diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c index 956eef48d..ac0440053 100644 --- a/src/lib/protocols/bgp.c +++ b/src/lib/protocols/bgp.c @@ -51,18 +51,15 @@ static void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_bgp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_bgp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BGP", ndpi_struct, *id, - NDPI_PROTOCOL_BGP, - ndpi_search_bgp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("BGP", ndpi_struct, + ndpi_search_bgp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BGP); } diff --git a/src/lib/protocols/bitcoin.c b/src/lib/protocols/bitcoin.c index e7ac4cffb..5f473d54a 100644 --- a/src/lib/protocols/bitcoin.c +++ b/src/lib/protocols/bitcoin.c @@ -52,21 +52,16 @@ static void ndpi_search_bitcoin(struct ndpi_detection_module_struct *ndpi_struct } } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************************** */ -void init_bitcoin_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_bitcoin_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Bitcoin", ndpi_struct, *id, - NDPI_PROTOCOL_BITCOIN, - ndpi_search_bitcoin, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Bitcoin", ndpi_struct, + ndpi_search_bitcoin, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BITCOIN); } diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 01080906f..6c77e29ef 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -2,7 +2,7 @@ * bittorrent.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-24 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -184,13 +184,15 @@ static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struc struct ndpi_flow_struct *flow, int bt_offset, int check_hash, ndpi_confidence_t confidence) { - if(check_hash) + if(ndpi_struct->cfg.bittorrent_hash_enabled && + check_hash) ndpi_search_bittorrent_hash(ndpi_struct, flow, bt_offset); ndpi_set_detected_protocol_keeping_master(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, confidence); - if(flow->protos.bittorrent.hash[0] == '\0') { + if(ndpi_struct->cfg.bittorrent_hash_enabled && + flow->protos.bittorrent.hash[0] == '\0') { /* Don't use just 1 as in TCP DNS more packets could be returned (e.g. ACK). */ flow->max_extra_packets_to_check = 3; flow->extra_packets_func = search_bittorrent_again; @@ -511,10 +513,12 @@ static u_int8_t is_port(u_int16_t a, u_int16_t b, u_int16_t what) { static void ndpi_skip_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_BITTORRENT) + return; if(search_into_bittorrent_cache(ndpi_struct, flow)) ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 0, NDPI_CONFIDENCE_DPI_CACHE); else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************* */ @@ -537,7 +541,7 @@ static void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_str if(is_port(sport, dport, 3544) /* teredo */ || is_port(sport, dport, 5246) || is_port(sport, dport, 5247) /* CAPWAP */) { exclude_bt: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -649,14 +653,10 @@ static void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_str /* ************************************* */ -void init_bittorrent_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_bittorrent_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BitTorrent", ndpi_struct, *id, - NDPI_PROTOCOL_BITTORRENT, - ndpi_search_bittorrent, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("BitTorrent", ndpi_struct, + ndpi_search_bittorrent, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BITTORRENT); } diff --git a/src/lib/protocols/bjnp.c b/src/lib/protocols/bjnp.c index 91277ecda..e16ffd023 100644 --- a/src/lib/protocols/bjnp.c +++ b/src/lib/protocols/bjnp.c @@ -29,7 +29,7 @@ static void ndpi_check_bjnp(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_bjnp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -40,13 +40,10 @@ static void ndpi_search_bjnp(struct ndpi_detection_module_struct *ndpi_struct, s } -void init_bjnp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_bjnp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("BJNP", ndpi_struct, *id, - NDPI_PROTOCOL_BJNP, - ndpi_search_bjnp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("BJNP", ndpi_struct, + ndpi_search_bjnp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_BJNP); } diff --git a/src/lib/protocols/blizzard.c b/src/lib/protocols/blizzard.c new file mode 100644 index 000000000..af80735a6 --- /dev/null +++ b/src/lib/protocols/blizzard.c @@ -0,0 +1,152 @@ +/* +* blizzard.c +* +* Copyright (C) 2015 - Matteo Bracci <matteobracci1@gmail.com> +* Copyright (C) 2015-22 - 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 +* 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_BLIZZARD + +#include "ndpi_api.h" +#include "ndpi_private.h" + + +static void search_blizzard_tcp(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) +{ + struct ndpi_packet_struct* packet = &ndpi_struct->packet; + char wow_string[] = "WORLD OF WARCRAFT CONNECTION"; + char overwatch2_string_c[] = "HELLO PRO CLIENT\0"; + char overwatch2_string_s[] = "HELLO PRO SERVER\0"; + + NDPI_LOG_DBG(ndpi_struct, "search Blizzard\n"); + + /* Generic Battle.net traffic */ + if(flow->guessed_protocol_id_by_ip == NDPI_PROTOCOL_BLIZZARD && + flow->s_port == htons(1119)) { + /* Looking for the first pkt sent by the server */ + if(current_pkt_from_server_to_client(ndpi_struct, flow) && + packet->payload_packet_len == 2 && + packet->payload[0] == 0x52 && packet->payload[1] == 0x08) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (battle.net)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } else if(flow->packet_direction_counter[packet->packet_direction] == 1) { + return; + } + } + + /* Pattern found on Hearthstone */ + if(packet->payload_packet_len >= 8 && + le32toh(*(uint32_t *)&packet->payload[4]) == (u_int32_t)(packet->payload_packet_len - 8)) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (Hearthstone)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + + /* Pattern found on WoW */ + if(packet->payload_packet_len >= NDPI_STATICSTRING_LEN(wow_string) && + memcmp(packet->payload, wow_string, NDPI_STATICSTRING_LEN(wow_string)) == 0) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (wow)\n"); + /* Which id? It should be NDPI_PROTOCOL_BLIZZARD, but we already have NDPI_PROTOCOL_WORLDOFWARCRAFT. + Keep using the latter for the time being.... */ + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WORLDOFWARCRAFT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + + /* Pattern found on Overwatch2 */ + if((packet->payload_packet_len == NDPI_STATICSTRING_LEN(overwatch2_string_c) && + memcmp(packet->payload, overwatch2_string_c, NDPI_STATICSTRING_LEN(overwatch2_string_c)) == 0) || + (packet->payload_packet_len == NDPI_STATICSTRING_LEN(overwatch2_string_s) && + memcmp(packet->payload, overwatch2_string_s, NDPI_STATICSTRING_LEN(overwatch2_string_s)) == 0)) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (overwatch2)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + + /* TODO: other patterns */ + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +static void search_blizzard_udp(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) +{ + struct ndpi_packet_struct* packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search Blizzard\n"); + + /* Patterns found on Warcraft Rumble */ + + /* The last bytes are some kind of sequence number, always starting from 1 */ + if(/* First pkt send by the client */ + (packet->payload_packet_len == 18 && + le32toh(*(uint32_t *)&packet->payload[14]) == 1) || + /* First pkt send by the server */ + (packet->payload_packet_len == 15 && + packet->payload[14] == 1)) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (Warcraft Ramble; pattern 1)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + /* First pkt send by the client */ + if(packet->payload_packet_len == 23 && + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "\xff\xff\xff\xff\xa3\x1f\xb6\x1e\x00\x00\x40\x01\x00\x00\x00\x00\x00\x00\x00\x04\x03\x02\x01")) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (Warcraft Ramble; pattern 2)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + + /* Patterns found on Overwatch2 */ + /* Some kind of ping */ + if(flow->guessed_protocol_id_by_ip == NDPI_PROTOCOL_BLIZZARD && + packet->payload_packet_len == 40 && + *(uint32_t *)&packet->payload[17] == 0 /* Seq number starting from 0 */) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (overwatch2; pattern 1)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + if(flow->guessed_protocol_id_by_ip == NDPI_PROTOCOL_BLIZZARD && + packet->payload_packet_len == 50 && + ((*(uint64_t *)&packet->payload[32] == 0 && *(uint64_t *)&packet->payload[40] == 0) /* First pkt from client */ || + (*(uint64_t *)&packet->payload[0] == 0 && *(uint64_t *)&packet->payload[8] == 0)) /* First pkt from server */) { + NDPI_LOG_INFO(ndpi_struct, "Found Blizzard (overwatch2; pattern 2)\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BLIZZARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + + /* TODO: other patterns */ + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +static void ndpi_search_blizzard(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) +{ + if(flow->l4_proto == IPPROTO_TCP) + search_blizzard_tcp(ndpi_struct, flow); + else + search_blizzard_udp(ndpi_struct, flow); +} + +void init_blizzard_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("Blizzard", ndpi_struct, + ndpi_search_blizzard, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_BLIZZARD); +} + diff --git a/src/lib/protocols/btlib.c b/src/lib/protocols/btlib.c index 14ec331b2..9b65ecffb 100644 --- a/src/lib/protocols/btlib.c +++ b/src/lib/protocols/btlib.c @@ -1,7 +1,7 @@ /* * btlib.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Contributed by Vitaly Lavrov <vel21ripn@gmail.com> * * This file is part of nDPI, an open source deep packet inspection diff --git a/src/lib/protocols/c1222.c b/src/lib/protocols/c1222.c index 6247769a8..38fdaa832 100644 --- a/src/lib/protocols/c1222.c +++ b/src/lib/protocols/c1222.c @@ -50,7 +50,7 @@ static void ndpi_search_c1222(struct ndpi_detection_module_struct *ndpi_struct, if ((packet->payload_packet_len < 50) || (packet->payload[0] != 0x60) || ((u_int8_t)(packet->payload_packet_len-2) != packet->payload[1])) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -59,17 +59,13 @@ static void ndpi_search_c1222(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_c1222_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_c1222_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("ANSI_C1222", ndpi_struct, *id, - NDPI_PROTOCOL_C1222, - ndpi_search_c1222, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("ANSI_C1222", ndpi_struct, + ndpi_search_c1222, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_C1222); } diff --git a/src/lib/protocols/can.c b/src/lib/protocols/can.c index fc12866a8..126211807 100644 --- a/src/lib/protocols/can.c +++ b/src/lib/protocols/can.c @@ -54,13 +54,13 @@ static void ndpi_search_can(struct ndpi_detection_module_struct *ndpi_struct, u_int64_t const signature = 0x49534f3131383938; // "ISO11898" if (packet->payload_packet_len < sizeof(struct can_hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } struct can_hdr const * const can_header = (struct can_hdr *)packet->payload; if (ndpi_ntohll(can_header->signature) != signature) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -71,15 +71,10 @@ static void ndpi_search_can(struct ndpi_detection_module_struct *ndpi_struct, } } -void init_can_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_can_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Controller_Area_Network", ndpi_struct, *id, - NDPI_PROTOCOL_CAN, - ndpi_search_can, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Controller_Area_Network", ndpi_struct, + ndpi_search_can, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CAN); } diff --git a/src/lib/protocols/capwap.c b/src/lib/protocols/capwap.c index e42a3b6be..efabad971 100644 --- a/src/lib/protocols/capwap.c +++ b/src/lib/protocols/capwap.c @@ -115,7 +115,7 @@ static void ndpi_search_setup_capwap(struct ndpi_detection_module_struct *ndpi_s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; capwap_found: @@ -131,15 +131,10 @@ static void ndpi_search_capwap(struct ndpi_detection_module_struct *ndpi_struct, } -void init_capwap_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_capwap_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CAPWAP", ndpi_struct, *id, - NDPI_PROTOCOL_CAPWAP, - ndpi_search_capwap, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("CAPWAP", ndpi_struct, + ndpi_search_capwap, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CAPWAP); } diff --git a/src/lib/protocols/cassandra.c b/src/lib/protocols/cassandra.c index 7e52dab14..975a8566b 100644 --- a/src/lib/protocols/cassandra.c +++ b/src/lib/protocols/cassandra.c @@ -71,12 +71,12 @@ static void ndpi_search_cassandra(struct ndpi_detection_module_struct *ndpi_stru (!ndpi_validate_cassandra_response(packet->payload[0]) || !ndpi_validate_cassandra_request(packet->payload[0]))) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (flow->packet_direction_counter[packet->packet_direction] > 2) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -92,17 +92,9 @@ static void ndpi_search_cassandra(struct ndpi_detection_module_struct *ndpi_stru } } -void init_cassandra_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - - ndpi_set_bitmask_protocol_detection("Cassandra", - ndpi_struct, - *id, - NDPI_PROTOCOL_CASSANDRA, - ndpi_search_cassandra, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_cassandra_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Cassandra", ndpi_struct, + ndpi_search_cassandra, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CASSANDRA); } diff --git a/src/lib/protocols/ceph.c b/src/lib/protocols/ceph.c index 8c1dc8df6..25d216c43 100644 --- a/src/lib/protocols/ceph.c +++ b/src/lib/protocols/ceph.c @@ -48,16 +48,13 @@ static void ndpi_search_ceph(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ceph_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ceph_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Ceph", ndpi_struct, *id, - NDPI_PROTOCOL_CEPH, - ndpi_search_ceph, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Ceph", ndpi_struct, + ndpi_search_ceph, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CEPH); } diff --git a/src/lib/protocols/checkmk.c b/src/lib/protocols/checkmk.c index cfc70f451..4638d6afd 100644 --- a/src/lib/protocols/checkmk.c +++ b/src/lib/protocols/checkmk.c @@ -1,7 +1,7 @@ /* * checkmk.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -52,7 +52,7 @@ static void ndpi_search_checkmk(struct ndpi_detection_module_struct *ndpi_struct as they are not an indication that this flow is not AFP */ if(flow->packet_counter > 6) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -69,19 +69,14 @@ static void ndpi_search_checkmk(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_LOG_DBG(ndpi_struct, "Check_MK excluded.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CHECKMK); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_checkmk_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_checkmk_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CHECKMK", ndpi_struct, *id, - NDPI_PROTOCOL_CHECKMK, - ndpi_search_checkmk, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("CHECKMK", ndpi_struct, + ndpi_search_checkmk, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CHECKMK); } diff --git a/src/lib/protocols/cip.c b/src/lib/protocols/cip.c index f9412b809..21dba3efe 100644 --- a/src/lib/protocols/cip.c +++ b/src/lib/protocols/cip.c @@ -59,16 +59,13 @@ static void ndpi_search_cip(struct ndpi_detection_module_struct *ndpi_struct, /* TODO add TCP dissection */ } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_cip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("CIP", ndpi_struct, *id, - NDPI_PROTOCOL_CIP, - ndpi_search_cip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_cip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("CIP", ndpi_struct, + ndpi_search_cip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CIP); } diff --git a/src/lib/protocols/ciscovpn.c b/src/lib/protocols/ciscovpn.c index b8bf8d09b..b584ffe9a 100644 --- a/src/lib/protocols/ciscovpn.c +++ b/src/lib/protocols/ciscovpn.c @@ -59,19 +59,16 @@ static void ndpi_search_ciscovpn(struct ndpi_detection_module_struct *ndpi_struc } if(flow->num_processed_pkts > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ciscovpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ciscovpn_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CiscoVPN", ndpi_struct, *id, - NDPI_PROTOCOL_CISCOVPN, - ndpi_search_ciscovpn, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("CiscoVPN", ndpi_struct, + ndpi_search_ciscovpn, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CISCOVPN); } diff --git a/src/lib/protocols/citrix.c b/src/lib/protocols/citrix.c index 0db341f02..f7b9de976 100644 --- a/src/lib/protocols/citrix.c +++ b/src/lib/protocols/citrix.c @@ -55,7 +55,7 @@ static void ndpi_check_citrix(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -66,13 +66,10 @@ static void ndpi_search_citrix(struct ndpi_detection_module_struct *ndpi_struct, } -void init_citrix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_citrix_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Citrix", ndpi_struct, *id, - NDPI_PROTOCOL_CITRIX, - ndpi_search_citrix, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Citrix", ndpi_struct, + ndpi_search_citrix, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CITRIX); } diff --git a/src/lib/protocols/cloudflare_warp.c b/src/lib/protocols/cloudflare_warp.c index af3ab0b85..0dbf00419 100644 --- a/src/lib/protocols/cloudflare_warp.c +++ b/src/lib/protocols/cloudflare_warp.c @@ -79,18 +79,14 @@ static void ndpi_search_cloudflare_warp(struct ndpi_detection_module_struct *ndp } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_cloudflare_warp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_cloudflare_warp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CloudflareWarp", ndpi_struct, *id, - NDPI_PROTOCOL_CLOUDFLARE_WARP, - ndpi_search_cloudflare_warp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("CloudflareWarp", ndpi_struct, + ndpi_search_cloudflare_warp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CLOUDFLARE_WARP); } diff --git a/src/lib/protocols/cnp-ip.c b/src/lib/protocols/cnp-ip.c index 9e3590d40..ef87728ea 100644 --- a/src/lib/protocols/cnp-ip.c +++ b/src/lib/protocols/cnp-ip.c @@ -51,17 +51,13 @@ static void ndpi_search_cnp_ip(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_cnp_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_cnp_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CNP-IP", ndpi_struct, *id, - NDPI_PROTOCOL_CNP_IP, - ndpi_search_cnp_ip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("CNP-IP", ndpi_struct, + ndpi_search_cnp_ip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CNP_IP); } diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c index bf6e06924..32affa3d4 100644 --- a/src/lib/protocols/coap.c +++ b/src/lib/protocols/coap.c @@ -119,7 +119,7 @@ static void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, if((!isCoAPport(s_port) && !isCoAPport(d_port)) || (packet->payload_packet_len < 4) ) { // header too short - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -142,21 +142,18 @@ static void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /** * Entry point for the ndpi library */ -void init_coap_dissector (struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_coap_dissector (struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection ("COAP", ndpi_struct, *id, - NDPI_PROTOCOL_COAP, - ndpi_search_coap, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id +=1; + register_dissector("COAP", ndpi_struct, + ndpi_search_coap, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_COAP); } diff --git a/src/lib/protocols/cod_mobile.c b/src/lib/protocols/cod_mobile.c index 97bdca42d..0efa72b11 100644 --- a/src/lib/protocols/cod_mobile.c +++ b/src/lib/protocols/cod_mobile.c @@ -66,18 +66,14 @@ static void ndpi_search_cod_mobile(struct ndpi_detection_module_struct *ndpi_str } if (flow->packet_counter >= 4) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_cod_mobile_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_cod_mobile_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CoD_Mobile", ndpi_struct, *id, - NDPI_PROTOCOL_COD_MOBILE, - ndpi_search_cod_mobile, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("CoD_Mobile", ndpi_struct, + ndpi_search_cod_mobile, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_COD_MOBILE); } diff --git a/src/lib/protocols/collectd.c b/src/lib/protocols/collectd.c index 3c878e9c9..a84a253ff 100644 --- a/src/lib/protocols/collectd.c +++ b/src/lib/protocols/collectd.c @@ -169,7 +169,7 @@ static void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struc block_length < COLLECTD_ENCR_AES256_MIN_BLOCK_SIZE || ndpi_int_collectd_dissect_username(flow, packet) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else { ndpi_int_collectd_add_connection(ndpi_struct, flow); } @@ -180,7 +180,7 @@ static void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struc if (num_blocks < COLLECTD_MIN_BLOCKS_REQUIRED) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -190,16 +190,10 @@ static void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struc ndpi_int_collectd_add_connection(ndpi_struct, flow); } -void init_collectd_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_collectd_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("collectd", ndpi_struct, *id, - NDPI_PROTOCOL_COLLECTD, - ndpi_search_collectd, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("collectd", ndpi_struct, + ndpi_search_collectd, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_COLLECTD); } diff --git a/src/lib/protocols/corba.c b/src/lib/protocols/corba.c index 8aa98babe..1218a38ec 100644 --- a/src/lib/protocols/corba.c +++ b/src/lib/protocols/corba.c @@ -55,17 +55,14 @@ static void ndpi_search_corba(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_corba_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_corba_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Corba", ndpi_struct, *id, - NDPI_PROTOCOL_CORBA, - ndpi_search_corba, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Corba", ndpi_struct, + ndpi_search_corba, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CORBA); } diff --git a/src/lib/protocols/cpha.c b/src/lib/protocols/cpha.c index b2967413f..6b2f1c79f 100644 --- a/src/lib/protocols/cpha.c +++ b/src/lib/protocols/cpha.c @@ -1,7 +1,7 @@ /* * qq.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -48,17 +48,13 @@ static void ndpi_search_cpha(struct ndpi_detection_module_struct *ndpi_struct, s ) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CPHA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_cpha_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("CPHA", ndpi_struct, *id, - NDPI_PROTOCOL_CPHA, - ndpi_search_cpha, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* TODO: ipv6 support? */ - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_cpha_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("CPHA", ndpi_struct, + ndpi_search_cpha, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* TODO: ipv6 support? */ + 1, NDPI_PROTOCOL_CPHA); } diff --git a/src/lib/protocols/crossfire.c b/src/lib/protocols/crossfire.c index e0f462f86..ec7cf0d08 100644 --- a/src/lib/protocols/crossfire.c +++ b/src/lib/protocols/crossfire.c @@ -30,60 +30,48 @@ static void ndpi_int_crossfire_add_connection(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) + struct ndpi_flow_struct *flow) { - + NDPI_LOG_INFO(ndpi_struct, "found CrossFire\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CROSSFIRE, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } static void ndpi_search_crossfire_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &ndpi_struct->packet; + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search CrossFire\n"); - NDPI_LOG_DBG(ndpi_struct, "search crossfire\n"); - if (packet->udp != 0) { - if (packet->payload_packet_len == 25 - && get_u_int32_t(packet->payload, 0) == ntohl(0xc7d91999) - && get_u_int16_t(packet->payload, 4) == ntohs(0x0200) - && get_u_int16_t(packet->payload, 22) == ntohs(0x7d00)) { - NDPI_LOG_INFO(ndpi_struct, "found Crossfire: udp packet\n"); - ndpi_int_crossfire_add_connection(ndpi_struct, flow); - return; - } + if (packet->udp != NULL && packet->payload_packet_len >= 8 && + get_u_int32_t(packet->payload, 0) == ntohl(0xc7d91999)) + { + ndpi_int_crossfire_add_connection(ndpi_struct, flow); + return; + } - } else if (packet->tcp != 0) { - if (packet->payload_packet_len > 4 && memcmp(packet->payload, "GET /", 5) == 0) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - if (packet->parsed_lines == 8 - && (packet->line[0].ptr != NULL && packet->line[0].len >= 30 - && (memcmp(&packet->payload[5], "notice/login_big", 16) == 0 - || memcmp(&packet->payload[5], "notice/login_small", 18) == 0)) - && memcmp(&packet->payload[packet->line[0].len - 19], "/index.asp HTTP/1.", 18) == 0 - && (packet->host_line.ptr != NULL && packet->host_line.len >= 13 - && (memcmp(packet->host_line.ptr, "crossfire", 9) == 0 - || memcmp(packet->host_line.ptr, "www.crossfire", 13) == 0)) - ) { - NDPI_LOG_DBG(ndpi_struct, "found Crossfire: HTTP request\n"); - ndpi_int_crossfire_add_connection(ndpi_struct, flow); - return; - } - } + if (packet->tcp != NULL && packet->payload_packet_len > 100 && + (packet->payload[0] == 0xF1 && packet->payload[packet->payload_packet_len-1] == 0xF2)) + { + /* Login packet */ + if (ntohl(get_u_int32_t(packet->payload, 2)) == 0x01000000) + { + ndpi_int_crossfire_add_connection(ndpi_struct, flow); + return; + } - } + /* TODO: add more CrossFire TCP signatures*/ + } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_crossfire_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_crossfire_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Crossfire", ndpi_struct, *id, - NDPI_PROTOCOL_CROSSFIRE, - ndpi_search_crossfire_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Crossfire", ndpi_struct, + ndpi_search_crossfire_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_CROSSFIRE); } diff --git a/src/lib/protocols/crynet.c b/src/lib/protocols/crynet.c index 21cbe7607..3ec918558 100644 --- a/src/lib/protocols/crynet.c +++ b/src/lib/protocols/crynet.c @@ -45,13 +45,13 @@ static void ndpi_search_crynet(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 26) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (packet->payload_packet_len != packet->payload[0] + 10) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -60,23 +60,17 @@ static void ndpi_search_crynet(struct ndpi_detection_module_struct *ndpi_struct, packet->payload[20] != 0x07 || ntohs(get_u_int16_t(packet->payload, 24)) != 0x0307) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ndpi_int_crynet_add_connection(ndpi_struct, flow); } -void init_crynet_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_crynet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CryNetwork", ndpi_struct, *id, - NDPI_PROTOCOL_CRYNET, - ndpi_search_crynet, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("CryNetwork", ndpi_struct, + ndpi_search_crynet, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_CRYNET); } diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c index 838d5f292..b22ddc84e 100644 --- a/src/lib/protocols/dcerpc.c +++ b/src/lib/protocols/dcerpc.c @@ -90,17 +90,14 @@ static void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, } if(packet->payload_packet_len>1) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_dcerpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dcerpc_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DCERPC", ndpi_struct, *id, - NDPI_PROTOCOL_DCERPC, - ndpi_search_dcerpc, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("DCERPC", ndpi_struct, + ndpi_search_dcerpc, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DCERPC); } diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index 4c400df9a..7074b0503 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -127,7 +127,7 @@ static void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struc #ifdef DHCP_DEBUG NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Invalid message type %d. Not dhcp\n", msg_type); #endif - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -194,18 +194,14 @@ static void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struc } } } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, *id, - NDPI_PROTOCOL_DHCP, - ndpi_search_dhcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("DHCP", ndpi_struct, + ndpi_search_dhcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_DHCP); } diff --git a/src/lib/protocols/dhcpv6.c b/src/lib/protocols/dhcpv6.c index 6afcd7a8c..97704025c 100644 --- a/src/lib/protocols/dhcpv6.c +++ b/src/lib/protocols/dhcpv6.c @@ -2,7 +2,7 @@ * dhcpv6.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,17 +53,14 @@ static void ndpi_search_dhcpv6_udp(struct ndpi_detection_module_struct *ndpi_str return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_dhcpv6_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dhcpv6_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DHCPV6", ndpi_struct, *id, - NDPI_PROTOCOL_DHCPV6, - ndpi_search_dhcpv6_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("DHCPV6", ndpi_struct, + ndpi_search_dhcpv6_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_DHCPV6); } diff --git a/src/lib/protocols/diameter.c b/src/lib/protocols/diameter.c index 0d9a8382b..8c19387b1 100644 --- a/src/lib/protocols/diameter.c +++ b/src/lib/protocols/diameter.c @@ -101,17 +101,15 @@ static void ndpi_search_diameter(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_diameter_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_diameter_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Diameter", ndpi_struct, *id, - NDPI_PROTOCOL_DIAMETER, ndpi_search_diameter, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Diameter", ndpi_struct, + ndpi_search_diameter, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DIAMETER); } diff --git a/src/lib/protocols/dicom.c b/src/lib/protocols/dicom.c index 18354258f..a32d299c3 100644 --- a/src/lib/protocols/dicom.c +++ b/src/lib/protocols/dicom.c @@ -51,20 +51,16 @@ static void ndpi_search_dicom(struct ndpi_detection_module_struct *ndpi_struct, NDPI_PROTOCOL_DICOM, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ********************************* */ -void init_dicom_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("DICOM", ndpi_struct, - *id, NDPI_PROTOCOL_DICOM, ndpi_search_dicom, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_dicom_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("DICOM", ndpi_struct, + ndpi_search_dicom, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DICOM); } diff --git a/src/lib/protocols/dingtalk.c b/src/lib/protocols/dingtalk.c index 25aea3f99..c42a5adea 100644 --- a/src/lib/protocols/dingtalk.c +++ b/src/lib/protocols/dingtalk.c @@ -48,16 +48,13 @@ static void ndpi_search_dingtalk(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_dingtalk_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dingtalk_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DingTalk", ndpi_struct, *id, - NDPI_PROTOCOL_DINGTALK, - ndpi_search_dingtalk, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("DingTalk", ndpi_struct, + ndpi_search_dingtalk, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DINGTALK); } diff --git a/src/lib/protocols/discord.c b/src/lib/protocols/discord.c index 5256910db..75231e2c6 100644 --- a/src/lib/protocols/discord.c +++ b/src/lib/protocols/discord.c @@ -72,19 +72,13 @@ static void ndpi_search_discord(struct ndpi_detection_module_struct *ndpi_struct } if (flow->packet_counter >= 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_discord_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_discord_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Discord", ndpi_struct, *id, - NDPI_PROTOCOL_DISCORD, - ndpi_search_discord, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Discord", ndpi_struct, + ndpi_search_discord, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_DISCORD); } diff --git a/src/lib/protocols/dlep.c b/src/lib/protocols/dlep.c index dc40d1a09..1ac00870e 100644 --- a/src/lib/protocols/dlep.c +++ b/src/lib/protocols/dlep.c @@ -67,17 +67,13 @@ static void ndpi_search_dlep(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_dlep_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dlep_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DLEP", ndpi_struct, *id, - NDPI_PROTOCOL_DLEP, - ndpi_search_dlep, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("DLEP", ndpi_struct, + ndpi_search_dlep, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DLEP); } diff --git a/src/lib/protocols/dnp3.c b/src/lib/protocols/dnp3.c index 99d23dad7..7472e33cd 100644 --- a/src/lib/protocols/dnp3.c +++ b/src/lib/protocols/dnp3.c @@ -1,7 +1,7 @@ /* * dnp3.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -49,20 +49,16 @@ static void ndpi_search_dnp3_tcp(struct ndpi_detection_module_struct *ndpi_struc return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ******************************************************** */ -void init_dnp3_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - - ndpi_set_bitmask_protocol_detection("DNP3", ndpi_struct, *id, - NDPI_PROTOCOL_DNP3, - ndpi_search_dnp3_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_dnp3_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + + register_dissector("DNP3", ndpi_struct, + ndpi_search_dnp3_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DNP3); } diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index ce991735d..59566d5c7 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -39,8 +39,8 @@ #define PKT_LEN_ALERT 512 -static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow); +static void search_dns(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); /* *********************************************** */ @@ -161,16 +161,13 @@ static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { return(0); else if(payload[i] == 0x00) return(1); - else if(payload[i] == 0xC0) + else if((payload[i] & 0xC0)== 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)); + return(off + getNameLength(i+off, payload, payloadLen)); } } /* @@ -213,6 +210,32 @@ static char* dns_error_code2string(u_int16_t error_code, char *buf, u_int buf_le /* *********************************************** */ +u_int64_t fpc_dns_cache_key_from_flow(struct ndpi_flow_struct *flow) { + u_int64_t key; + + if(flow->is_ipv6) + key = ndpi_quick_hash64((const char *)flow->s_address.v6, 16); + else + key = (u_int64_t)(flow->s_address.v4); + + return key; +} + +/* *********************************************** */ + +static u_int64_t fpc_dns_cache_key_from_packet(const unsigned char *ip, int ip_len) { + u_int64_t key; + + if(ip_len == 16) + key = ndpi_quick_hash64((const char *)ip, 16); + else + key = (u_int64_t)(*(u_int32_t *)ip); + + return key; +} + +/* *********************************************** */ + static u_int8_t ndpi_grab_dns_name(struct ndpi_packet_struct *packet, u_int *off /* payload offset */, char *_hostname, u_int max_len, @@ -226,14 +249,17 @@ static u_int8_t ndpi_grab_dns_name(struct ndpi_packet_struct *packet, while((j < max_len) && ((*off) < packet->payload_packet_len) && (packet->payload[(*off)] != '\0')) { - u_int8_t c, cl = packet->payload[(*off)++]; + u_int8_t c, cl = packet->payload[*off]; if(((cl & 0xc0) != 0) || // we not support compressed names in query - ((*off) + cl >= packet->payload_packet_len)) { + (((*off)+1) + cl >= packet->payload_packet_len)) { + /* Don't update the offset */ j = 0; break; } + (*off)++; + if(j && (j < max_len)) _hostname[j++] = '.'; while((j < max_len) && (cl != 0)) { @@ -272,645 +298,619 @@ static u_int8_t ndpi_grab_dns_name(struct ndpi_packet_struct *packet, /* *********************************************** */ -static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - struct ndpi_dns_packet_header *dns_header, - u_int payload_offset, u_int8_t *is_query, - u_int8_t ignore_checks) { +static int process_queries(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + struct ndpi_dns_packet_header *dns_header, + u_int payload_offset) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int x = payload_offset; + u_int16_t rsp_type; + u_int16_t num; - memcpy(dns_header, (struct ndpi_dns_packet_header*)&packet->payload[x], - sizeof(struct ndpi_dns_packet_header)); - - dns_header->tr_id = ntohs(dns_header->tr_id); - dns_header->flags = ntohs(dns_header->flags); - dns_header->num_queries = ntohs(dns_header->num_queries); - dns_header->num_answers = ntohs(dns_header->num_answers); - dns_header->authority_rrs = ntohs(dns_header->authority_rrs); - dns_header->additional_rrs = ntohs(dns_header->additional_rrs); + for(num = 0; num < dns_header->num_queries; num++) { + u_int16_t data_len; - x += sizeof(struct ndpi_dns_packet_header); + if((data_len = getNameLength(x, packet->payload, + packet->payload_packet_len)) == 0) { + return -1; + } else + x += data_len; - /* 0x0000 QUERY */ - if((dns_header->flags & FLAGS_MASK) == 0x0000) - *is_query = 1; - /* 0x8000 RESPONSE */ - else - *is_query = 0; + if(data_len > 253) + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Query Lenght"); - if(*is_query) { - /* DNS Request */ - if((dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) - // && (dns_header->num_answers == 0) - && (((dns_header->flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) - || ((dns_header->flags & 0xFCF0) == 0x00) /* Standard Query */ - || ((dns_header->flags & 0xFCFF) == 0x0800) /* Inverse query */ - || ((dns_header->num_answers == 0) && (dns_header->authority_rrs == 0)))) { - /* This is a good query */ - while(x+2 < packet->payload_packet_len) { - if(packet->payload[x] == '\0') { - x++; - flow->protos.dns.query_type = get16(&x, packet->payload); -#ifdef DNS_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type); - printf("[DNS] [request] query_type=%d\n", flow->protos.dns.query_type); -#endif - break; - } else - x++; - } - } else { - if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Header"); - return(1 /* invalid */); + if((x+4) > packet->payload_packet_len) { + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Query Lenght"); + return -1; } - } else { - /* DNS Reply */ - if(flow->protos.dns.query_type == 0) { - /* In case we missed the query packet... */ + rsp_type = get16(&x, packet->payload); - while(x+2 < packet->payload_packet_len) { - if(packet->payload[x] == '\0') { - x++; - flow->protos.dns.query_type = get16(&x, packet->payload); #ifdef DNS_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type); - printf("[DNS] [request] query_type=%d\n", flow->protos.dns.query_type); + printf("[DNS] [response (query)] response_type=%d\n", rsp_type); #endif - break; - } else - x++; - } + if(flow->protos.dns.query_type == 0) { + /* In case we missed the query packet... */ + flow->protos.dns.query_type = rsp_type; } - flow->protos.dns.reply_code = dns_header->flags & 0x0F; + /* here x points to the response "class" field */ + x += 2; /* Skip class */ + } - if(flow->protos.dns.reply_code != 0) { - char str[32], buf[16]; + return x; +} - snprintf(str, sizeof(str), "DNS Error Code %s", - dns_error_code2string(flow->protos.dns.reply_code, buf, sizeof(buf))); - ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); - } else { - if(ndpi_isset_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN)) { - ndpi_set_risk(ndpi_struct, flow, NDPI_RISKY_DOMAIN, "DGA Name Query with no Error Code"); - } - } +static int process_answers(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + struct ndpi_dns_packet_header *dns_header, + u_int payload_offset, + ndpi_master_app_protocol *proto) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int x = payload_offset; + u_int16_t rsp_type; + u_int32_t rsp_ttl; + u_int16_t num; + u_int8_t found = 0; + int ignore_checks; - 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: we dissect it both for request and response */ - - if(dns_header->num_queries > 0) { -#ifdef DNS_DEBUG - u_int16_t rsp_type; -#endif - u_int16_t num; + ignore_checks = (proto->master_protocol == NDPI_PROTOCOL_MDNS); - for(num = 0; num < dns_header->num_queries; num++) { - u_int16_t data_len; + for(num = 0; num < dns_header->num_answers; num++) { + u_int16_t data_len; - if((x+6) >= packet->payload_packet_len) { - break; - } + if((data_len = getNameLength(x, packet->payload, + packet->payload_packet_len)) == 0) { + return -1; + } else + x += data_len; - if((data_len = getNameLength(x, packet->payload, - packet->payload_packet_len)) == 0) { - break; - } else - x += data_len; + if((x+8) >= packet->payload_packet_len) { + return -1; + } - if((x+8) >= packet->payload_packet_len) { - break; - } + rsp_type = get16(&x, packet->payload); + rsp_ttl = ntohl(*((u_int32_t*)&packet->payload[x+2])); - /* To avoid warning: variable ‘rsp_type’ set but not used [-Wunused-but-set-variable] */ -#ifdef DNS_DEBUG - rsp_type = get16(&x, packet->payload); -#else - get16(&x, packet->payload); -#endif + if(rsp_ttl == 0) + ndpi_set_risk(ndpi_struct, flow, NDPI_MINOR_ISSUES, "DNS Record with zero TTL"); #ifdef DNS_DEBUG - printf("[DNS] [response (query)] response_type=%d\n", rsp_type); + printf("[DNS] Date len %u; TTL = %u\n", data_len, rsp_ttl); + printf("[DNS] [response] response_type=%d\n", rsp_type); #endif - /* here x points to the response "class" field */ - x += 2; /* Skip class */ - } - } + if(found == 0) { + ndpi_check_dns_type(ndpi_struct, flow, rsp_type); + flow->protos.dns.rsp_type = rsp_type; + } - if(dns_header->num_answers > 0) { - u_int16_t rsp_type; - u_int32_t rsp_ttl; - u_int16_t num; - u_int8_t found = 0; + /* x points to the response "class" field */ + if((x+12) <= packet->payload_packet_len) { + u_int32_t ttl = ntohl(*((u_int32_t*)&packet->payload[x+2])); - for(num = 0; num < dns_header->num_answers; num++) { - u_int16_t data_len; + x += 6; + data_len = get16(&x, packet->payload); - if((x+6) >= packet->payload_packet_len) { - break; - } + if((x + data_len) <= packet->payload_packet_len) { +#ifdef DNS_DEBUG + printf("[DNS] [rsp_type: %u][data_len: %u]\n", rsp_type, data_len); +#endif - if((data_len = getNameLength(x, packet->payload, - packet->payload_packet_len)) == 0) { - break; - } else - x += data_len; + if(rsp_type == 0x05 /* CNAME */) { + ; + } else if(rsp_type == 0x0C /* PTR */) { + u_int16_t ptr_len = (packet->payload[x-2] << 8) + packet->payload[x-1]; + + if((x + ptr_len) <= packet->payload_packet_len) { + if(found == 0) { + u_int len, orig_x; + + orig_x = x; + ndpi_grab_dns_name(packet, &x, + flow->protos.dns.ptr_domain_name, + sizeof(flow->protos.dns.ptr_domain_name), &len, + ignore_checks); + /* ndpi_grab_dns_name doesn't update the offset if it failed. + We unconditionally update it at the end of the for loop */ + x = orig_x; + found = 1; + } + } + } else if((((rsp_type == 0x1) && (data_len == 4)) /* A */ + || ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */ + )) { + if(found == 0) { + + if(flow->protos.dns.num_rsp_addr < MAX_NUM_DNS_RSP_ADDRESSES) { + /* Necessary for IP address comparison */ + memset(&flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], 0, sizeof(ndpi_ip_addr_t)); + + memcpy(&flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], packet->payload + x, data_len); + flow->protos.dns.is_rsp_addr_ipv6[flow->protos.dns.num_rsp_addr] = (data_len == 16) ? 1 : 0; + flow->protos.dns.rsp_addr_ttl[flow->protos.dns.num_rsp_addr] = ttl; + + if(ndpi_struct->cfg.address_cache_size) + ndpi_cache_address(ndpi_struct, + flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], + flow->host_server_name, + packet->current_time_ms/1000, + flow->protos.dns.rsp_addr_ttl[flow->protos.dns.num_rsp_addr]); + + ++flow->protos.dns.num_rsp_addr; + } + + if(flow->protos.dns.num_rsp_addr >= MAX_NUM_DNS_RSP_ADDRESSES) + found = 1; + } + + /* Add (all addresses) to FPC DNS cache */ + if(ndpi_struct->cfg.fpc_enabled && + proto->app_protocol != NDPI_PROTOCOL_UNKNOWN && + proto->app_protocol != proto->master_protocol && + ndpi_struct->fpc_dns_cache) { + ndpi_lru_add_to_cache(ndpi_struct->fpc_dns_cache, + fpc_dns_cache_key_from_packet(packet->payload + x, data_len), + proto->app_protocol, + ndpi_get_current_time(flow)); - if((x+8) >= packet->payload_packet_len) { - break; - } + NDPI_LOG_DBG(ndpi_struct, "Adding entry to fpc_dns: %s proto %d\n", + data_len == 4 ? "ipv4" : "ipv6", proto->app_protocol); + } + } - rsp_type = get16(&x, packet->payload); - rsp_ttl = ntohl(*((u_int32_t*)&packet->payload[x+2])); + x += data_len; + } + } - if(rsp_ttl == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_MINOR_ISSUES, "DNS Record with zero TTL"); - -#ifdef DNS_DEBUG - printf("[DNS] TTL = %u\n", rsp_ttl); - printf("[DNS] [response] response_type=%d\n", rsp_type); -#endif + if(found && (dns_header->additional_rrs == 0)) { + /* + In case we have RR we need to iterate + all the answers and not just consider the + first one as we need to properly move 'x' + to the right offset + */ + break; + } + } - if(found == 0) { - ndpi_check_dns_type(ndpi_struct, flow, rsp_type); - flow->protos.dns.rsp_type = rsp_type; - } - - /* x points to the response "class" field */ - if((x+12) <= packet->payload_packet_len) { - u_int32_t ttl = ntohl(*((u_int32_t*)&packet->payload[x+2])); - - x += 6; - data_len = get16(&x, packet->payload); - - if((x + data_len) <= packet->payload_packet_len) { -#ifdef DNS_DEBUG - printf("[DNS] [rsp_type: %u][data_len: %u]\n", rsp_type, data_len); -#endif + return x; +} - if(rsp_type == 0x05 /* CNAME */) { - ; - } else if(rsp_type == 0x0C /* PTR */) { - u_int16_t ptr_len = (packet->payload[x-2] << 8) + packet->payload[x-1]; - - if((x + ptr_len) <= packet->payload_packet_len) { - if(found == 0) { - u_int len; - - ndpi_grab_dns_name(packet, &x, - flow->protos.dns.ptr_domain_name, - sizeof(flow->protos.dns.ptr_domain_name), &len, - ignore_checks); - found = 1; - } - } - } else if((((rsp_type == 0x1) && (data_len == 4)) /* A */ - || ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */ - )) { - if(found == 0) { - - if(flow->protos.dns.num_rsp_addr < MAX_NUM_DNS_RSP_ADDRESSES) { - /* Necessary for IP address comparison */ - memset(&flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], 0, sizeof(ndpi_ip_addr_t)); - - memcpy(&flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], packet->payload + x, data_len); - flow->protos.dns.is_rsp_addr_ipv6[flow->protos.dns.num_rsp_addr] = (data_len == 16) ? 1 : 0; - flow->protos.dns.rsp_addr_ttl[flow->protos.dns.num_rsp_addr] = ttl; - - if(ndpi_struct->cfg.address_cache_size) - ndpi_cache_address(ndpi_struct, - flow->protos.dns.rsp_addr[flow->protos.dns.num_rsp_addr], - flow->host_server_name, - packet->current_time_ms/1000, - flow->protos.dns.rsp_addr_ttl[flow->protos.dns.num_rsp_addr]); - - ++flow->protos.dns.num_rsp_addr; - } - - if(flow->protos.dns.num_rsp_addr >= MAX_NUM_DNS_RSP_ADDRESSES) - found = 1; - } - } - - x += data_len; - } - } - - if(found && (dns_header->additional_rrs == 0)) { - /* - In case we have RR we need to iterate - all the answers and not just consider the - first one as we need to properly move 'x' - to the right offset - */ - break; - } - } - } +static int process_additionals(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + struct ndpi_dns_packet_header *dns_header, + u_int payload_offset) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int x = payload_offset; - if(dns_header->additional_rrs > 0) { - /* - Dissect the rest of the packet only if there are - additional_rrs as we need to check fo EDNS(0) + /* + Dissect the rest of the packet only if there are + additional_rrs as we need to check for: + * EDNS(0) + * NSID - In this case we need to go through the whole packet - as we need to update the 'x' offset - */ - if(dns_header->authority_rrs > 0) { + In this case we need to go through the whole packet + as we need to update the 'x' offset + */ + + if(dns_header->additional_rrs == 0) + return x; + + if(dns_header->authority_rrs > 0) { #ifdef DNS_DEBUG - u_int16_t rsp_type; + u_int16_t rsp_type; #endif - u_int16_t num; + u_int16_t num; - for(num = 0; num < dns_header->authority_rrs; num++) { - u_int16_t data_len; + for(num = 0; num < dns_header->authority_rrs; num++) { + u_int16_t data_len; - if((x+6) >= packet->payload_packet_len) { - break; - } + if((x+6) >= packet->payload_packet_len) { + return -1; + } - if((data_len = getNameLength(x, packet->payload, - packet->payload_packet_len)) == 0) { - break; - } else - x += data_len; + if((data_len = getNameLength(x, packet->payload, + packet->payload_packet_len)) == 0) { + return -1; + } else + x += data_len; - if((x+8) >= packet->payload_packet_len) { - break; - } + if((x+8) >= packet->payload_packet_len) { + return -1; + } - /* To avoid warning: variable ‘rsp_type’ set but not used [-Wunused-but-set-variable] */ + /* To avoid warning: variable ‘rsp_type’ set but not used [-Wunused-but-set-variable] */ #ifdef DNS_DEBUG - rsp_type = get16(&x, packet->payload); + rsp_type = get16(&x, packet->payload); #else - get16(&x, packet->payload); + get16(&x, packet->payload); #endif #ifdef DNS_DEBUG - printf("[DNS] [RRS response] response_type=%d\n", rsp_type); + printf("[DNS] [RRS response] response_type=%d\n", rsp_type); #endif - /* here x points to the response "class" field */ - if((x+12) <= packet->payload_packet_len) { - x += 6; - data_len = get16(&x, packet->payload); + /* here x points to the response "class" field */ + if((x+12) <= packet->payload_packet_len) { + x += 6; + data_len = get16(&x, packet->payload); - if((x + data_len) <= packet->payload_packet_len) - x += data_len; - } - } - } + if((x + data_len) <= packet->payload_packet_len) + x += data_len; + } + } + } + + if(dns_header->additional_rrs > 0) { + u_int16_t rsp_type; + u_int16_t num; - if(dns_header->additional_rrs > 0) { - u_int16_t rsp_type; - u_int16_t num; + for(num = 0; num < dns_header->additional_rrs; num++) { + u_int16_t data_len, rdata_len, opt_code, opt_len; + const unsigned char *opt; - for(num = 0; num < dns_header->additional_rrs; num++) { - u_int16_t data_len, rdata_len, opt_code, opt_len; - const unsigned char *opt; +#ifdef DNS_DEBUG + printf("[DNS] [RR response %d/%d]\n", num + 1, dns_header->additional_rrs); +#endif - if((x+6) > packet->payload_packet_len) { - break; - } + if((x+6) > packet->payload_packet_len) { + return -1; + } - if((data_len = getNameLength(x, packet->payload, packet->payload_packet_len)) == 0) { - break; - } else - x += data_len; + if((data_len = getNameLength(x, packet->payload, packet->payload_packet_len)) == 0) { + return -1; + } else + x += data_len; - if((x+10) > packet->payload_packet_len) { - break; - } + if((x+10) > packet->payload_packet_len) { + return -1; + } - rsp_type = get16(&x, packet->payload); + rsp_type = get16(&x, packet->payload); #ifdef DNS_DEBUG - printf("[DNS] [RR response] response_type=%d\n", rsp_type); + printf("[DNS] [RR response] response_type=%d\n", rsp_type); #endif - if(rsp_type == 41 /* OPT */) { - /* https://en.wikipedia.org/wiki/Extension_Mechanisms_for_DNS */ - flow->protos.dns.edns0_udp_payload_size = ntohs(*((u_int16_t*)&packet->payload[x])); /* EDNS(0) */ + if(rsp_type == 41 /* OPT */) { + /* https://en.wikipedia.org/wiki/Extension_Mechanisms_for_DNS */ + flow->protos.dns.edns0_udp_payload_size = ntohs(*((u_int16_t*)&packet->payload[x])); /* EDNS(0) */ #ifdef DNS_DEBUG - printf("[DNS] [response] edns0_udp_payload_size: %u\n", flow->protos.dns.edns0_udp_payload_size); + printf("[DNS] [response] edns0_udp_payload_size: %u\n", flow->protos.dns.edns0_udp_payload_size); #endif - x += 6; + x += 6; - rdata_len = ntohs(*((u_int16_t *)&packet->payload[x])); + rdata_len = ntohs(*((u_int16_t *)&packet->payload[x])); #ifdef DNS_DEBUG - printf("[DNS] [response] rdata len: %u\n", rdata_len); + printf("[DNS] [response] rdata len: %u\n", rdata_len); #endif - if(rdata_len > 0 && - x + 6 <= packet->payload_packet_len) { - opt_code = ntohs(*((u_int16_t *)&packet->payload[x + 2])); - opt_len = ntohs(*((u_int16_t *)&packet->payload[x + 4])); - opt = &packet->payload[x + 6]; - /* TODO: parse the TLV list */ - if(opt_code == 0x03 && - opt_len <= rdata_len + 4 && - opt_len > 6 && - x + 6 + opt_len <= packet->payload_packet_len) { + if(rdata_len > 0 && + x + 6 <= packet->payload_packet_len) { + opt_code = ntohs(*((u_int16_t *)&packet->payload[x + 2])); + opt_len = ntohs(*((u_int16_t *)&packet->payload[x + 4])); + opt = &packet->payload[x + 6]; + /* TODO: parse the TLV list */ + if(opt_code == 0x03 && + opt_len <= rdata_len + 4 && + opt_len > 6 && + x + 6 + opt_len <= packet->payload_packet_len) { #ifdef DNS_DEBUG - printf("[DNS] NSID: [%.*s]\n", opt_len, opt); + printf("[DNS] NSID: [%.*s]\n", opt_len, opt); #endif - if(memcmp(opt, "gpdns-", 6) == 0) { + if(memcmp(opt, "gpdns-", 6) == 0) { #ifdef DNS_DEBUG - printf("[DNS] NSID Airport code [%.*s]\n", opt_len - 6, opt + 6); + printf("[DNS] NSID Airport code [%.*s]\n", opt_len - 6, opt + 6); #endif - memcpy(flow->protos.dns.geolocation_iata_code, opt + 6, - ndpi_min(opt_len - 6, (int)sizeof(flow->protos.dns.geolocation_iata_code) - 1)); - } - } - - } - } else { - x += 6; - } - - if((data_len = getNameLength(x, packet->payload, packet->payload_packet_len)) == 0) { - break; - } else - x += data_len; - } - } + memcpy(flow->protos.dns.geolocation_iata_code, opt + 6, + ndpi_min(opt_len - 6, (int)sizeof(flow->protos.dns.geolocation_iata_code) - 1)); + } + } - if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) - || (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) { - /* Request already set the protocol */ - // flow->extra_packets_func = NULL; /* Removed so the caller can keep dissecting DNS flows */ - } else { - /* We missed the request */ - u_int16_t s_port = packet->udp ? ntohs(packet->udp->source) : ntohs(packet->tcp->source); - - ndpi_set_detected_protocol(ndpi_struct, flow, checkPort(s_port), NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - } + } + } else { + x += 6; } + + if((data_len = getNameLength(x, packet->payload, packet->payload_packet_len)) == 0) { + return -1; + } else + x += data_len; } } - /* Valid */ - return(0); + return x; +} + +static int is_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + struct ndpi_dns_packet_header *dns_header, + u_int payload_offset, u_int8_t *is_query) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + + if(packet->payload_packet_len < sizeof(struct ndpi_dns_packet_header) + payload_offset) + return 0; + + memcpy(dns_header, (struct ndpi_dns_packet_header*)&packet->payload[payload_offset], + sizeof(struct ndpi_dns_packet_header)); + + dns_header->tr_id = ntohs(dns_header->tr_id); + dns_header->flags = ntohs(dns_header->flags); + dns_header->num_queries = ntohs(dns_header->num_queries); + dns_header->num_answers = ntohs(dns_header->num_answers); + dns_header->authority_rrs = ntohs(dns_header->authority_rrs); + dns_header->additional_rrs = ntohs(dns_header->additional_rrs); + + if((dns_header->flags & FLAGS_MASK) == 0x0000) + *is_query = 1; + else + *is_query = 0; + + if(*is_query) { + if(dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS && + /* dns_header->num_answers == 0 && */ + ((dns_header->flags & 0x2800) == 0x2800 /* Dynamic DNS Update */ || + (dns_header->flags & 0xFCF0) == 0x00 /* Standard Query */ || + (dns_header->flags & 0xFCFF) == 0x0800 /* Inverse query */ || + (dns_header->num_answers == 0 && dns_header->authority_rrs == 0))) { + /* This is a good query */ + return 1; + } + } else { + if(((dns_header->num_queries > 0 && dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) || /* Don't assume that num_queries must be zero */ + (checkDNSSubprotocol(ntohs(flow->c_port), ntohs(flow->s_port)) == NDPI_PROTOCOL_MDNS && dns_header->num_queries == 0)) && + ((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) || + (dns_header->num_answers == 0 && dns_header->authority_rrs == 0 && dns_header->additional_rrs == 0))) { + /* This is a good reply */ + return 1; + } + if(dns_header->num_queries == 0 && dns_header->num_answers == 0 && + dns_header->authority_rrs == 0 && dns_header->additional_rrs == 0 && + packet->payload_packet_len == sizeof(struct ndpi_dns_packet_header)) { + /* This is a good empty reply */ + return 1; + } + } + return 0; +} + +/* *********************************************** */ + +static int keep_extra_dissection(struct ndpi_flow_struct *flow) +{ + /* As a general rule, we wait for a valid response + (in the ideal world, we want to process the request/response pair) */ + return !(!flow->protos.dns.is_query && flow->protos.dns.num_answers != 0); } /* *********************************************** */ static int search_dns_again(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - /* possibly dissect the DNS reply */ - ndpi_search_dns(ndpi_struct, flow); + struct ndpi_packet_struct *packet = &ndpi_struct->packet; - if(flow->protos.dns.num_answers != 0) - return(0); + if(packet->tcp_retransmission || packet->payload_packet_len == 0) + return keep_extra_dissection(flow); + + /* possibly dissect the DNS reply */ + search_dns(ndpi_struct, flow); - /* Possibly more processing */ - return(1); + return keep_extra_dissection(flow); } /* *********************************************** */ -static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { +static int process_hostname(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + struct ndpi_dns_packet_header *dns_header, + ndpi_master_app_protocol *proto) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; - int payload_offset; - u_int8_t is_query, is_mdns; - u_int16_t s_port = 0, d_port = 0; + char *dot; + u_int len, is_mdns, off = sizeof(struct ndpi_dns_packet_header) + (packet->tcp ? 2 : 0); + char _hostname[256]; + u_int8_t hostname_is_valid; - NDPI_LOG_DBG(ndpi_struct, "search DNS\n"); + proto->master_protocol = checkDNSSubprotocol(ntohs(flow->c_port), ntohs(flow->s_port)); + proto->app_protocol = flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN; - if(packet->udp != NULL) { - s_port = ntohs(packet->udp->source); - d_port = ntohs(packet->udp->dest); - payload_offset = 0; + /* We try to get hostname only from "standard" query/answer */ + if(dns_header->num_queries == 0 && dns_header->num_answers == 0) + return -1; - /* For MDNS/LLMNR: If the packet is not a response, dest addr needs to be multicast. */ - if ((d_port == MDNS_PORT && isMDNSMulticastAddress(packet) == 0) || - (d_port == LLMNR_PORT && isLLMNRMulticastAddress(packet) == 0)) - { - if (packet->payload_packet_len > 5 && - ntohs(get_u_int16_t(packet->payload, 2)) != 0 && - ntohs(get_u_int16_t(packet->payload, 4)) != 0) - { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + is_mdns = (proto->master_protocol == NDPI_PROTOCOL_MDNS); + + /* TODO: should we overwrite existing hostname? + For the time being, keep the old/current behavior */ + + hostname_is_valid = ndpi_grab_dns_name(packet, &off, _hostname, sizeof(_hostname), &len, is_mdns); + +#ifdef DNS_DEBUG + printf("[DNS] [%s]\n", _hostname); +#endif + + ndpi_hostname_sni_set(flow, (const u_int8_t *)_hostname, len, is_mdns ? NDPI_HOSTNAME_NORM_LC : NDPI_HOSTNAME_NORM_ALL); + + if (hostname_is_valid == 0) + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, "Invalid chars detected in domain name"); + + /* Ignore reverse DNS queries */ + if(strstr(_hostname, ".in-addr.") == NULL) { + dot = strchr(_hostname, '.'); + + if(dot) { + uintptr_t first_element_len = dot - _hostname; + + if((first_element_len > 48) && (!is_mdns)) { + /* + The length of the first element in the query is very long + and this might be an issue or indicate an exfiltration + */ + + if(ends_with(ndpi_struct, _hostname, "multi.surbl.org") + || ends_with(ndpi_struct, _hostname, "spamhaus.org") + || ends_with(ndpi_struct, _hostname, "rackcdn.com") + || ends_with(ndpi_struct, _hostname, "akamaiedge.net") + || ends_with(ndpi_struct, _hostname, "mx-verification.google.com") + || ends_with(ndpi_struct, _hostname, "amazonaws.com") + ) + ; /* Check common domain exceptions [TODO: if the list grows too much use a different datastructure] */ + else + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_SUSPICIOUS_TRAFFIC, "Long DNS host name"); } } - } else if(packet->tcp != NULL) /* pkt size > 512 bytes */ { - s_port = ntohs(packet->tcp->source); - d_port = ntohs(packet->tcp->dest); - payload_offset = 2; } - is_mdns = ((s_port == MDNS_PORT) || (d_port == MDNS_PORT)) ? 1 : 0; - - if(((s_port == DNS_PORT) || (d_port == DNS_PORT) - || is_mdns - || (d_port == LLMNR_PORT)) - && (packet->payload_packet_len > sizeof(struct ndpi_dns_packet_header)+payload_offset)) { - struct ndpi_dns_packet_header dns_header; - char *dot; - u_int len, off; - int invalid = search_valid_dns(ndpi_struct, flow, &dns_header, payload_offset, &is_query, is_mdns); - ndpi_protocol ret; - u_int num_queries, idx; - char _hostname[256]; - - ret.proto.master_protocol = NDPI_PROTOCOL_UNKNOWN; - ret.proto.app_protocol = (d_port == LLMNR_PORT) ? NDPI_PROTOCOL_LLMNR : (((d_port == MDNS_PORT) && isLLMNRMulticastAddress(packet) ) ? NDPI_PROTOCOL_MDNS : NDPI_PROTOCOL_DNS); - - if(invalid) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + if(strlen(flow->host_server_name) > 0) { + ndpi_protocol_match_result ret_match; + + if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { + proto->app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow, + flow->host_server_name, + strlen(flow->host_server_name), + &ret_match, + proto->master_protocol, + /* Avoid updating classification if subclassification is disabled */ + ndpi_struct->cfg.dns_subclassification_enabled ? 1 : 0); } - /* extract host name server */ - off = sizeof(struct ndpi_dns_packet_header) + payload_offset; + ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0, proto->app_protocol != NDPI_PROTOCOL_UNKNOWN); + } - /* Before continuing let's dissect the following queries to see if they are valid */ - for(idx=off, num_queries=0; (num_queries < dns_header.num_queries) && (idx < packet->payload_packet_len);) { - u_int32_t i, tot_len = 0; + return 0; +} - for(i=idx; i<packet->payload_packet_len;) { - u_int8_t is_ptr = 0, name_len = packet->payload[i]; /* Lenght of the individual name blocks aaa.bbb.com */ +static void search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + int payload_offset = 0; + u_int8_t is_query; + struct ndpi_dns_packet_header dns_header; + u_int off; + ndpi_master_app_protocol proto; + int rc; - if(name_len == 0) { - tot_len++; /* \0 */ - /* End of query */ - break; - } else if((name_len & 0xC0) == 0xC0) - is_ptr = 1, name_len = 0; /* Pointer */ + if(packet->udp != NULL) { + payload_offset = 0; + } else if(packet->tcp != NULL) { + payload_offset = 2; + } + if(!is_valid_dns(ndpi_struct, flow, &dns_header, payload_offset, &is_query)) { #ifdef DNS_DEBUG - if((!is_ptr) && (name_len > 0)) { - printf("[DNS] [name_len: %u][", name_len); - - { - int idx; + printf("[DNS] invalid packet\n"); +#endif + if(flow->extra_packets_func == NULL) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Header"); + } + return; + } - for(idx=0; idx<name_len; idx++) - printf("%c", packet->payload[i+1+idx]); + process_hostname(ndpi_struct, flow, &dns_header, &proto); - printf("]\n"); - } - } -#endif + off = sizeof(struct ndpi_dns_packet_header) + payload_offset; - i += name_len+1, tot_len += name_len+1; - if(is_ptr) break; - } /* for */ + if(is_query) { + flow->protos.dns.is_query = 1; + flow->protos.dns.transaction_id = dns_header.tr_id; + rc = process_queries(ndpi_struct, flow, &dns_header, off); #ifdef DNS_DEBUG - printf("[DNS] [tot_len: %u]\n\n", tot_len+4 /* type + class */); + if(rc == -1) + printf("[DNS] Error queries (query msg)\n"); #endif + } else { + flow->protos.dns.is_query = 0; + flow->protos.dns.transaction_id = dns_header.tr_id; + flow->protos.dns.reply_code = dns_header.flags & 0x0F; + flow->protos.dns.num_queries = dns_header.num_queries; + flow->protos.dns.num_answers = dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs; - if(((i+4 /* Skip query type and class */) > packet->payload_packet_len) - || ((packet->payload[i+1] == 0x0) && (packet->payload[i+2] == 0x0)) /* Query type cannot be 0 */ - || (tot_len > 253) - ) { - /* Invalid */ -#ifdef DNS_DEBUG - printf("[DNS] Invalid query len [%u >= %u]\n", i+4, packet->payload_packet_len); -#endif - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Query Lenght"); - break; + if(flow->protos.dns.reply_code != 0) { + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_ERROR_CODE_DETECTED)) { + char str[32], buf[16]; + + snprintf(str, sizeof(str), "DNS Error Code %s", + dns_error_code2string(flow->protos.dns.reply_code, buf, sizeof(buf))); + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); } else { - idx = i+5, num_queries++; + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, NULL); } - } /* for */ - - u_int8_t hostname_is_valid = ndpi_grab_dns_name(packet, &off, _hostname, sizeof(_hostname), &len, is_mdns); - - ndpi_hostname_sni_set(flow, (const u_int8_t *)_hostname, len, is_mdns ? NDPI_HOSTNAME_NORM_LC : NDPI_HOSTNAME_NORM_ALL); - - if (hostname_is_valid == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, "Invalid chars detected in domain name"); - - /* Ignore reverse DNS queries */ - if(strstr(_hostname, ".in-addr.") == NULL) { - dot = strchr(_hostname, '.'); - - if(dot) { - uintptr_t first_element_len = dot - _hostname; - - if((first_element_len > 48) && (!is_mdns)) { - /* - The lenght of the first element in the query is very long - and this might be an issue or indicate an exfiltration - */ - - if(ends_with(ndpi_struct, _hostname, "multi.surbl.org") - || ends_with(ndpi_struct, _hostname, "spamhaus.org") - || ends_with(ndpi_struct, _hostname, "rackcdn.com") - || ends_with(ndpi_struct, _hostname, "akamaiedge.net") - || ends_with(ndpi_struct, _hostname, "mx-verification.google.com") - || ends_with(ndpi_struct, _hostname, "amazonaws.com") - ) - ; /* Check common domain exceptions [TODO: if the list grows too much use a different datastructure] */ - else - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_SUSPICIOUS_TRAFFIC, "Long DNS host name"); - } + } else { + if(ndpi_isset_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN)) { + ndpi_set_risk(ndpi_struct, flow, NDPI_RISKY_DOMAIN, "DGA Name Query with no Error Code"); } } - - if(len > 0) { - if(ndpi_struct->cfg.dns_subclassification_enabled) { - ndpi_protocol_match_result ret_match; - - ret.proto.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow, - flow->host_server_name, - strlen(flow->host_server_name), - &ret_match, - NDPI_PROTOCOL_DNS); - /* Add to FPC DNS cache */ - if(ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN && - (flow->protos.dns.rsp_type == 0x1 || flow->protos.dns.rsp_type == 0x1c) && /* A, AAAA */ - ndpi_struct->fpc_dns_cache) { - ndpi_lru_add_to_cache(ndpi_struct->fpc_dns_cache, - fpc_dns_cache_key_from_dns_info(flow), ret.proto.app_protocol, - ndpi_get_current_time(flow)); - } - - if(ret.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN) - ret.proto.master_protocol = checkDNSSubprotocol(s_port, d_port); - else - ret.proto.master_protocol = NDPI_PROTOCOL_DNS; - ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0); + rc = process_queries(ndpi_struct, flow, &dns_header, off); + if(rc == -1) { +#ifdef DNS_DEBUG + printf("[DNS] Error queries (response msg)\n"); +#endif + } else { + off = rc; + rc = process_answers(ndpi_struct, flow, &dns_header, off, &proto); + if(rc == -1) { +#ifdef DNS_DEBUG + printf("[DNS] Error answers\n"); +#endif } else { - ret.proto.master_protocol = checkDNSSubprotocol(s_port, d_port); - ret.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN; + off = rc; + rc = process_additionals(ndpi_struct, flow, &dns_header, off); +#ifdef DNS_DEBUG + if(rc == -1) + printf("[DNS] Error additionals\n"); +#endif } - - /* Category is always NDPI_PROTOCOL_CATEGORY_NETWORK, regardless of the subprotocol */ - flow->category = NDPI_PROTOCOL_CATEGORY_NETWORK; - } - /* Report if this is a DNS query or reply */ - flow->protos.dns.is_query = is_query; + if(proto.master_protocol == NDPI_PROTOCOL_DNS && + /* TODO: add support to RFC6891 to avoid some false positives */ + packet->udp && + packet->payload_packet_len > PKT_LEN_ALERT && + packet->payload_packet_len > flow->protos.dns.edns0_udp_payload_size) { + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_DNS_LARGE_PACKET)) { + char str[48]; - if(is_query) { - /* In this case we say that the protocol has been detected just to let apps carry on with their activities */ - ndpi_set_detected_protocol(ndpi_struct, flow, ret.proto.app_protocol, ret.proto.master_protocol, NDPI_CONFIDENCE_DPI); - - if(ndpi_struct->cfg.dns_parse_response_enabled) { - /* We have never triggered extra-dissection for LLMNR. Keep the old behaviour */ - if(ret.proto.master_protocol != NDPI_PROTOCOL_LLMNR) { - /* Don't use just 1 as in TCP DNS more packets could be returned (e.g. ACK). */ - flow->max_extra_packets_to_check = 5; - flow->extra_packets_func = search_dns_again; - } + snprintf(str, sizeof(str), "%u Bytes DNS Packet", packet->payload_packet_len); + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, NULL); } - return; /* The response will set the verdict */ } - 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); - -#ifdef DNS_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "[num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", - 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 + NDPI_LOG_DBG2(ndpi_struct, "Response: [num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", + flow->protos.dns.num_queries, flow->protos.dns.num_answers, + flow->protos.dns.reply_code, flow->protos.dns.rsp_type, flow->host_server_name); + } - if(flow->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_INFO(ndpi_struct, "found DNS\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, ret.proto.app_protocol, ret.proto.master_protocol, NDPI_CONFIDENCE_DPI); - } else { - if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) - || (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) - ; - else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + if(ndpi_struct->cfg.dns_subclassification_enabled) + ndpi_set_detected_protocol(ndpi_struct, flow, proto.app_protocol, proto.master_protocol, NDPI_CONFIDENCE_DPI); + else + ndpi_set_detected_protocol(ndpi_struct, flow, proto.master_protocol, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + } + /* Category is always NDPI_PROTOCOL_CATEGORY_NETWORK, regardless of the subprotocol */ + flow->category = NDPI_PROTOCOL_CATEGORY_NETWORK; + + if(!flow->extra_packets_func && + ndpi_struct->cfg.dns_parse_response_enabled && + /* We have never triggered extra-dissection for LLMNR. Keep the old behavior */ + flow->detected_protocol_stack[0] != NDPI_PROTOCOL_LLMNR && + flow->detected_protocol_stack[1] != NDPI_PROTOCOL_LLMNR) { + if(keep_extra_dissection(flow)) { + NDPI_LOG_DBG(ndpi_struct, "Enabling extra dissection\n"); + flow->max_extra_packets_to_check = 5; + flow->extra_packets_func = search_dns_again; } } - if(flow->packet_counter > 3) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - + /* The bigger packets are usually the replies, but it shouldn't harm + to check the requests, too */ if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) || (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) { - /* TODO: add support to RFC6891 to avoid some false positives */ - if((packet->udp != NULL) - && (packet->payload_packet_len > PKT_LEN_ALERT) - && (packet->payload_packet_len > flow->protos.dns.edns0_udp_payload_size) - ) { - char str[48]; - - snprintf(str, sizeof(str), "%u Bytes DNS Packet", packet->payload_packet_len); - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, str); - } if(packet->iph != NULL) { /* IPv4 */ @@ -934,15 +934,62 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st /* *********************************************** */ -void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("DNS", ndpi_struct, *id, - NDPI_PROTOCOL_DNS, - ndpi_search_dns, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); +static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int16_t s_port = 0, d_port = 0; + int payload_offset = 0; + + NDPI_LOG_DBG(ndpi_struct, "search DNS\n"); - *id += 1; + if(packet->udp != NULL) { + s_port = ntohs(packet->udp->source); + d_port = ntohs(packet->udp->dest); + payload_offset = 0; + + /* For MDNS/LLMNR: If the packet is not a response, dest addr needs to be multicast. */ + if ((d_port == MDNS_PORT && isMDNSMulticastAddress(packet) == 0) || + (d_port == LLMNR_PORT && isLLMNRMulticastAddress(packet) == 0)) + { + if (packet->payload_packet_len > 5 && + ntohs(get_u_int16_t(packet->payload, 2)) != 0 && + ntohs(get_u_int16_t(packet->payload, 4)) != 0) + { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + } + } else if(packet->tcp != NULL) { + s_port = ntohs(packet->tcp->source); + d_port = ntohs(packet->tcp->dest); + payload_offset = 2; + } + + /* We are able to detect DNS/MDNS/LLMNR only on standard ports (see #1788) */ + if(!(s_port == DNS_PORT || d_port == DNS_PORT || + s_port == MDNS_PORT || d_port == MDNS_PORT || + d_port == LLMNR_PORT)) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + /* Since: + UDP: every packet must contains a complete/valid DNS message; + TCP: we are not able to handle DNS messages spanning multiple TCP packets; + we must be able to detect these protocols on the first packet + */ + if(packet->payload_packet_len < sizeof(struct ndpi_dns_packet_header) + payload_offset) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + search_dns(ndpi_struct, flow); +} + +/* *********************************************** */ +void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("DNS", ndpi_struct, + ndpi_search_dns, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DNS); } diff --git a/src/lib/protocols/dnscrypt.c b/src/lib/protocols/dnscrypt.c index a77bade98..782ae0763 100644 --- a/src/lib/protocols/dnscrypt.c +++ b/src/lib/protocols/dnscrypt.c @@ -62,17 +62,16 @@ static void ndpi_search_dnscrypt(struct ndpi_detection_module_struct *ndpi_struc * Wait for at least one packet per direction, up to a max * Required as we need to wait for the server response which contains the ASCII pattern below. */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } -void init_dnscrypt_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dnscrypt_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection( - "DNScrypt", ndpi_struct, *id, - NDPI_PROTOCOL_DNSCRYPT, ndpi_search_dnscrypt, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("DNScrypt", ndpi_struct, + ndpi_search_dnscrypt, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DNSCRYPT); } diff --git a/src/lib/protocols/dofus.c b/src/lib/protocols/dofus.c index 37dbb2310..d87763d88 100644 --- a/src/lib/protocols/dofus.c +++ b/src/lib/protocols/dofus.c @@ -2,7 +2,7 @@ * dofus.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -41,113 +41,24 @@ static void ndpi_search_dofus(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search dofus\n"); - /* Dofus v 1.x.x */ - if (packet->payload_packet_len == 13 && get_u_int16_t(packet->payload, 1) == ntohs(0x0508) - && get_u_int16_t(packet->payload, 5) == ntohs(0x04a0) - && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == ntohs(0x0194)) { - ndpi_dofus_add_connection(ndpi_struct, flow); - return; - } - if (flow->l4.tcp.dofus_stage == 0) { - if (packet->payload_packet_len == 3 && memcmp(packet->payload, "HG", 2) == 0 - && packet->payload[packet->payload_packet_len - 1] == 0) - goto maybe_dofus; - - if (packet->payload_packet_len == 12 && memcmp(packet->payload, "Af", 2) == 0 - && packet->payload[packet->payload_packet_len - 1] == 0) - goto maybe_dofus; - - if (packet->payload_packet_len == 35 && memcmp(packet->payload, "HC", 2) == 0 - && packet->payload[packet->payload_packet_len - 1] == 0) - goto maybe_dofus; - - if (packet->payload_packet_len > 2 && packet->payload[0] == 'A' - && (packet->payload[1] == 'x' || packet->payload[1] == 'X') - && packet->payload[packet->payload_packet_len - 1] == 0) - goto maybe_dofus; - - if (packet->payload_packet_len > 2 && memcmp(packet->payload, "Ad", 2) - && packet->payload[packet->payload_packet_len - 1] == 0) - goto maybe_dofus; - - } - if (flow->l4.tcp.dofus_stage == 1) { - if (packet->payload_packet_len == 11 && memcmp(packet->payload, "AT", 2) == 0 - && packet->payload[10] == 0x00) { - ndpi_dofus_add_connection(ndpi_struct, flow); - return; - } - if (packet->payload_packet_len == 5 - && packet->payload[0] == 'A' && packet->payload[4] == 0x00 - && (packet->payload[1] == 'T' || packet->payload[1] == 'k')) { - ndpi_dofus_add_connection(ndpi_struct, flow); - return; - } - } - /* end Dofus 1.x.x */ - - - /* Dofus 2.0 */ - if ((packet->payload_packet_len == 11 || packet->payload_packet_len == 13 || packet->payload_packet_len == 49) - && get_u_int32_t(packet->payload, 0) == ntohl(0x00050800) - && get_u_int16_t(packet->payload, 4) == ntohs(0x0005) - && get_u_int16_t(packet->payload, 8) == ntohs(0x0005) - && packet->payload[10] == 0x18) { - if (packet->payload_packet_len == 13 - && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != ntohs(0x0194)) { - goto exclude; - } - if (packet->payload_packet_len == 49 && ntohs(get_u_int16_t(packet->payload, 15)) + 17 != packet->payload_packet_len) { - goto exclude; - } - ndpi_dofus_add_connection(ndpi_struct, flow); - return; - } - if (packet->payload_packet_len >= 41 && get_u_int16_t(packet->payload, 0) == ntohs(0x01b9) && packet->payload[2] == 0x26) { - u_int16_t len, len2; - len = ntohs(get_u_int16_t(packet->payload, 3)); - if ((len + 5 + 2) > packet->payload_packet_len) - goto exclude; - len2 = ntohs(get_u_int16_t(packet->payload, 5 + len)); - if (5 + len + 2 + len2 == packet->payload_packet_len) { + /* Dofus 3 */ + if(ntohs(flow->c_port) == 5555 || ntohs(flow->s_port) == 5555) { + if(packet->payload_packet_len > 3 && + packet->payload[0] + 1 == packet->payload_packet_len && + packet->payload[1] == 0x0a && + packet->payload[2] + 2 == packet->payload[0]) { ndpi_dofus_add_connection(ndpi_struct, flow); - return; } } - if (packet->payload_packet_len == 56 - && memcmp(packet->payload, "\x00\x11\x35\x02\x03\x00\x93\x96\x01\x00", 10) == 0) { - u_int16_t len, len2; - len = ntohs(get_u_int16_t(packet->payload, 10)); - if ((len + 12 + 2) > packet->payload_packet_len) - goto exclude; - len2 = ntohs(get_u_int16_t(packet->payload, 12 + len)); - if ((12 + len + 2 + len2 + 1) > packet->payload_packet_len) - goto exclude; - if (12 + len + 2 + len2 + 1 == packet->payload_packet_len && packet->payload[12 + len + 2 + len2] == 0x01) { - ndpi_dofus_add_connection(ndpi_struct, flow); - return; - } - } -exclude: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - -maybe_dofus: - flow->l4.tcp.dofus_stage = 1; - NDPI_LOG_DBG2(ndpi_struct, "maybe dofus\n"); - return; + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_dofus_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dofus_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Dofus", ndpi_struct, *id, - NDPI_PROTOCOL_DOFUS, - ndpi_search_dofus, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Dofus", ndpi_struct, + ndpi_search_dofus, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DOFUS); } diff --git a/src/lib/protocols/drda.c b/src/lib/protocols/drda.c index a3b1a4143..24a09c31c 100644 --- a/src/lib/protocols/drda.c +++ b/src/lib/protocols/drda.c @@ -83,21 +83,17 @@ static void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, } no_drda: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************************** */ -void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DRDA", ndpi_struct, *id, - NDPI_PROTOCOL_DRDA, - ndpi_search_drda, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("DRDA", ndpi_struct, + ndpi_search_drda, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_DRDA); } diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c index 2ac2f7d8a..d9afa1ef3 100644 --- a/src/lib/protocols/dropbox.c +++ b/src/lib/protocols/dropbox.c @@ -63,7 +63,7 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -74,13 +74,10 @@ static void ndpi_search_dropbox(struct ndpi_detection_module_struct *ndpi_struct } -void init_dropbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_dropbox_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("DROPBOX", ndpi_struct, *id, - NDPI_PROTOCOL_DROPBOX, - ndpi_search_dropbox, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("DROPBOX", ndpi_struct, + ndpi_search_dropbox, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_DROPBOX); } diff --git a/src/lib/protocols/eaq.c b/src/lib/protocols/eaq.c index b0c191fe8..ed03097ca 100644 --- a/src/lib/protocols/eaq.c +++ b/src/lib/protocols/eaq.c @@ -74,19 +74,15 @@ static void ndpi_search_eaq(struct ndpi_detection_module_struct *ndpi_struct, st } while(0); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_eaq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_eaq_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("EAQ", ndpi_struct, *id, - NDPI_PROTOCOL_EAQ, - ndpi_search_eaq, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("EAQ", ndpi_struct, + ndpi_search_eaq, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_EAQ); } diff --git a/src/lib/protocols/edonkey.c b/src/lib/protocols/edonkey.c index 96561a95b..f300a12b3 100644 --- a/src/lib/protocols/edonkey.c +++ b/src/lib/protocols/edonkey.c @@ -44,7 +44,7 @@ static void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct protocol = packet->payload[0]; /* 0xE3: Edonkey, 0xC5: eMule extensions, 0xD4: eMule compressed */ if(protocol != 0xE3 && protocol != 0xC5 && protocol != 0xD4) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } message_length = packet->payload_packet_len - 5; @@ -54,19 +54,15 @@ static void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_edonkey_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_edonkey_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("eDonkey", ndpi_struct, *id, - NDPI_PROTOCOL_EDONKEY, - ndpi_search_edonkey, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("eDonkey", ndpi_struct, + ndpi_search_edonkey, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_EDONKEY); } diff --git a/src/lib/protocols/egd.c b/src/lib/protocols/egd.c index e91ac4792..bd66dbc2e 100644 --- a/src/lib/protocols/egd.c +++ b/src/lib/protocols/egd.c @@ -49,17 +49,13 @@ static void ndpi_search_egd(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_egd_dissector(struct ndpi_detection_module_struct *ndpi_struct,u_int32_t *id) +void init_egd_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("EthernetGlobalData", ndpi_struct, *id, - NDPI_PROTOCOL_EGD, - ndpi_search_egd, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("EthernetGlobalData", ndpi_struct, + ndpi_search_egd, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_EGD); } diff --git a/src/lib/protocols/elastic_search.c b/src/lib/protocols/elastic_search.c index c1de3c86b..182a130f7 100644 --- a/src/lib/protocols/elastic_search.c +++ b/src/lib/protocols/elastic_search.c @@ -49,20 +49,20 @@ static void ndpi_search_elasticsearch(struct ndpi_detection_module_struct *ndpi_ if (packet->payload_packet_len < 6) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (ntohs(get_u_int16_t(packet->payload, 0)) != 0x4553 /* "ES" */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } message_length = ntohl(get_u_int32_t(packet->payload, 2)); if (packet->payload_packet_len < message_length + 6) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -71,16 +71,10 @@ static void ndpi_search_elasticsearch(struct ndpi_detection_module_struct *ndpi_ /* ***************************************************** */ -void init_elasticsearch_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_elasticsearch_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Elasticsearch", ndpi_struct, *id, - NDPI_PROTOCOL_ELASTICSEARCH, - ndpi_search_elasticsearch, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Elasticsearch", ndpi_struct, + ndpi_search_elasticsearch, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ELASTICSEARCH); } diff --git a/src/lib/protocols/epicgames.c b/src/lib/protocols/epicgames.c index 040806740..b5a064c1d 100644 --- a/src/lib/protocols/epicgames.c +++ b/src/lib/protocols/epicgames.c @@ -54,7 +54,7 @@ static void ndpi_search_epicgames(struct ndpi_detection_module_struct *ndpi_stru flow->l4.udp.epicgames_word = ntohl(get_u_int32_t(packet->payload, 0)); return; } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } else if(flow->l4.udp.epicgames_stage == 2 - packet->packet_direction) { @@ -63,26 +63,21 @@ static void ndpi_search_epicgames(struct ndpi_detection_module_struct *ndpi_stru ndpi_int_epicgames_add_connection(ndpi_struct, flow); return; } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } if(flow->packet_counter >= 4) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } -void init_epicgames_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_epicgames_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("EpicGames", ndpi_struct, *id, - NDPI_PROTOCOL_EPICGAMES, - ndpi_search_epicgames, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("EpicGames", ndpi_struct, + ndpi_search_epicgames, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_EPICGAMES); } diff --git a/src/lib/protocols/ethereum.c b/src/lib/protocols/ethereum.c index 3f2531597..37eb802da 100644 --- a/src/lib/protocols/ethereum.c +++ b/src/lib/protocols/ethereum.c @@ -86,7 +86,7 @@ static void ndpi_search_ethereum_udp(struct ndpi_detection_module_struct *ndpi_s return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************************** */ @@ -132,7 +132,7 @@ static void ndpi_search_ethereum_tcp(struct ndpi_detection_module_struct *ndpi_s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************************** */ @@ -149,16 +149,11 @@ static void ndpi_search_ethereum(struct ndpi_detection_module_struct *ndpi_struc /* ************************************************************************** */ -void init_ethereum_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ethereum_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Ethereum", ndpi_struct, *id, - NDPI_PROTOCOL_ETHEREUM, - ndpi_search_ethereum, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Ethereum", ndpi_struct, + ndpi_search_ethereum, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ETHEREUM); } diff --git a/src/lib/protocols/ethernet_ip.c b/src/lib/protocols/ethernet_ip.c index 125f48998..87e10898b 100644 --- a/src/lib/protocols/ethernet_ip.c +++ b/src/lib/protocols/ethernet_ip.c @@ -56,17 +56,13 @@ static void ndpi_search_ethernet_ip(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); /* No luck this time */ + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); /* No luck this time */ } -void init_ethernet_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("EthernetIP", ndpi_struct, *id, - NDPI_PROTOCOL_ETHERNET_IP, - ndpi_search_ethernet_ip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_ethernet_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("EthernetIP", ndpi_struct, + ndpi_search_ethernet_ip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ETHERNET_IP); } diff --git a/src/lib/protocols/ethersbus.c b/src/lib/protocols/ethersbus.c index 1e1973292..0ae748cdd 100644 --- a/src/lib/protocols/ethersbus.c +++ b/src/lib/protocols/ethersbus.c @@ -57,18 +57,13 @@ static void ndpi_search_ethersbus(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ethersbus_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ethersbus_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Ether-S-Bus", ndpi_struct, *id, - NDPI_PROTOCOL_ETHERSBUS, - ndpi_search_ethersbus, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Ether-S-Bus", ndpi_struct, + ndpi_search_ethersbus, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ETHERSBUS); } diff --git a/src/lib/protocols/ethersio.c b/src/lib/protocols/ethersio.c index add804553..5350e045c 100644 --- a/src/lib/protocols/ethersio.c +++ b/src/lib/protocols/ethersio.c @@ -29,14 +29,6 @@ #include "ndpi_api.h" #include "ndpi_private.h" -static void ndpi_int_ethersio_add_connection(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) -{ - NDPI_LOG_INFO(ndpi_struct, "found EtherSIO\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ETHERSIO, - NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - static void ndpi_search_ethersio(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { @@ -47,24 +39,22 @@ static void ndpi_search_ethersio(struct ndpi_detection_module_struct *ndpi_struc if (packet->payload_packet_len >= 20) { if ((memcmp(packet->payload, "ESIO", 4) == 0) && (packet->payload[4] == 0) && (packet->payload[5] <= 0x2) && - (packet->payload[6] == 0)) - { - ndpi_int_ethersio_add_connection(ndpi_struct, flow); + (packet->payload[6] == 0)) { + NDPI_LOG_INFO(ndpi_struct, "found EtherSIO\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ETHERSIO, + NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; - } + } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ethersio_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("EtherSIO", ndpi_struct, *id, - NDPI_PROTOCOL_ETHERSIO, - ndpi_search_ethersio, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_ethersio_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("EtherSIO", ndpi_struct, + ndpi_search_ethersio, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ETHERSIO); } diff --git a/src/lib/protocols/fastcgi.c b/src/lib/protocols/fastcgi.c index 52518b0c9..229a14563 100644 --- a/src/lib/protocols/fastcgi.c +++ b/src/lib/protocols/fastcgi.c @@ -136,20 +136,13 @@ static int fcgi_parse_params(struct ndpi_flow_struct * const flow, return 1; } - flow->http.method = ndpi_http_str2method((const char*)packet->http_method.ptr, - (u_int16_t)packet->http_method.len); + flow->protos.fast_cgi.method = ndpi_http_str2method((const char*)packet->http_method.ptr, + (u_int16_t)packet->http_method.len); ndpi_hostname_sni_set(flow, packet->host_line.ptr, packet->host_line.len, NDPI_HOSTNAME_NORM_ALL); - ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len); - - if (flow->http.url == NULL && packet->http_url_name.len > 0) - { - flow->http.url = ndpi_malloc(packet->http_url_name.len + 1); - if (flow->http.url != NULL) - { - strncpy(flow->http.url, (char const *)packet->http_url_name.ptr, packet->http_url_name.len); - flow->http.url[packet->http_url_name.len] = '\0'; - } - } + strncpy(flow->protos.fast_cgi.user_agent, (char *)packet->user_agent_line.ptr, + ndpi_min(sizeof(flow->protos.fast_cgi.user_agent) - 1, packet->user_agent_line.len)); + strncpy(flow->protos.fast_cgi.url, (char *)packet->http_url_name.ptr, + ndpi_min(sizeof(flow->protos.fast_cgi.url) - 1, packet->http_url_name.len)); return 0; } @@ -167,7 +160,7 @@ static void ndpi_search_fastcgi(struct ndpi_detection_module_struct *ndpi_struct if (packet->payload_packet_len < sizeof(struct FCGI_Header)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -175,21 +168,21 @@ static void ndpi_search_fastcgi(struct ndpi_detection_module_struct *ndpi_struct if (fcgi_hdr->version != 0x01) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } fcgi_type = (enum FCGI_Type)fcgi_hdr->type; if (fcgi_type < FCGI_MIN || fcgi_type > FCGI_MAX) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } content_len = ntohs(fcgi_hdr->contentLength); if (packet->payload_packet_len != sizeof(*fcgi_hdr) + content_len + fcgi_hdr->paddingLength) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -210,9 +203,9 @@ static void ndpi_search_fastcgi(struct ndpi_detection_module_struct *ndpi_struct ndpi_match_host_subprotocol(ndpi_struct, flow, flow->host_server_name, strlen(flow->host_server_name), - &ret_match, NDPI_PROTOCOL_FASTCGI); + &ret_match, NDPI_PROTOCOL_FASTCGI, 1); ndpi_check_dga_name(ndpi_struct, flow, - flow->host_server_name, 1, 0); + flow->host_server_name, 1, 0, 0); if(ndpi_is_valid_hostname((char *)packet->host_line.ptr, packet->host_line.len) == 0) { char str[128]; @@ -242,16 +235,10 @@ static int ndpi_search_fastcgi_extra(struct ndpi_detection_module_struct * ndpi_ return flow->extra_packets_func != NULL; } -void init_fastcgi_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_fastcgi_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("FastCGI", ndpi_struct, *id, - NDPI_PROTOCOL_FASTCGI, - ndpi_search_fastcgi, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("FastCGI", ndpi_struct, + ndpi_search_fastcgi, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_FASTCGI); } diff --git a/src/lib/protocols/fins.c b/src/lib/protocols/fins.c index 797b6662e..a966566b3 100644 --- a/src/lib/protocols/fins.c +++ b/src/lib/protocols/fins.c @@ -106,19 +106,13 @@ static void ndpi_search_fins(struct ndpi_detection_module_struct *ndpi_struct, } not_fins: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_fins_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_fins_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("FINS", ndpi_struct, *id, - NDPI_PROTOCOL_FINS, - ndpi_search_fins, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("FINS", ndpi_struct, + ndpi_search_fins, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_FINS); } diff --git a/src/lib/protocols/fix.c b/src/lib/protocols/fix.c index f0fed3360..145ad6b8d 100644 --- a/src/lib/protocols/fix.c +++ b/src/lib/protocols/fix.c @@ -59,17 +59,14 @@ static void ndpi_search_fix(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_fix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_fix_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("FIX", ndpi_struct, *id, - NDPI_PROTOCOL_FIX, - ndpi_search_fix, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("FIX", ndpi_struct, + ndpi_search_fix, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_FIX); } diff --git a/src/lib/protocols/flute.c b/src/lib/protocols/flute.c index 20fd4cec6..af3884423 100644 --- a/src/lib/protocols/flute.c +++ b/src/lib/protocols/flute.c @@ -44,7 +44,7 @@ static void ndpi_search_flute(struct ndpi_detection_module_struct *ndpi_struct, } u_int16_t lct_hdr_len = packet->payload[2] * 4; - if (packet->payload_packet_len <= lct_hdr_len + 43) { + if (packet->payload_packet_len <= lct_hdr_len + 43 + NDPI_STATICSTRING_LEN("<FDT")) { goto not_flute; } @@ -59,18 +59,13 @@ static void ndpi_search_flute(struct ndpi_detection_module_struct *ndpi_struct, } not_flute: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_flute_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_flute_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("FLUTE", ndpi_struct, *id, - NDPI_PROTOCOL_FLUTE, - ndpi_search_flute, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("FLUTE", ndpi_struct, + ndpi_search_flute, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_FLUTE); } diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 266fc414a..03d41d389 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -589,18 +589,18 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str /* Exclude SMTP, which uses similar commands. */ if(packet->tcp->dest == twentyfive || packet->tcp->source == twentyfive) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* Break after 8 packets. */ if(flow->packet_counter > 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* Check if we so far detected the protocol in the request or not. */ - if(flow->ftp_control_stage == 0) { + if(flow->l4.tcp.ftp_control_stage == 0) { NDPI_LOG_DBG2(ndpi_struct, "FTP_CONTROL stage 0: \n"); if((payload_len > 0) && ndpi_ftp_control_check_request(ndpi_struct, flow, @@ -612,16 +612,16 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->ftp_control_stage = packet->packet_direction + 1; + flow->l4.tcp.ftp_control_stage = packet->packet_direction + 1; } } else { - NDPI_LOG_DBG2(ndpi_struct, "FTP_CONTROL stage %u: \n", flow->ftp_control_stage); + NDPI_LOG_DBG2(ndpi_struct, "FTP_CONTROL stage %u: \n", flow->l4.tcp.ftp_control_stage); /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ - if((flow->ftp_control_stage - packet->packet_direction) == 1) { + if((flow->l4.tcp.ftp_control_stage - packet->packet_direction) == 1) { return; } @@ -637,7 +637,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str if(flow->l4.tcp.ftp_imap_pop_smtp.password[0] == '\0' && flow->l4.tcp.ftp_imap_pop_smtp.auth_done == 0 && flow->l4.tcp.ftp_imap_pop_smtp.auth_tls == 0) { - flow->ftp_control_stage = 0; + flow->l4.tcp.ftp_control_stage = 0; } else if (flow->l4.tcp.ftp_imap_pop_smtp.auth_tls == 1 && ndpi_struct->cfg.ftp_opportunistic_tls_enabled) { flow->host_server_name[0] = '\0'; /* Remove any data set by other dissectors (eg. SMTP) */ @@ -654,7 +654,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str } else { NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to FTP_CONTROL, " "resetting the stage to 0\n"); - flow->ftp_control_stage = 0; + flow->l4.tcp.ftp_control_stage = 0; } } } @@ -670,14 +670,9 @@ static void ndpi_search_ftp_control(struct ndpi_detection_module_struct *ndpi_st /* *************************************************************** */ -void init_ftp_control_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("FTP_CONTROL", ndpi_struct, *id, - NDPI_PROTOCOL_FTP_CONTROL, - ndpi_search_ftp_control, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_ftp_control_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("FTP_CONTROL", ndpi_struct, + ndpi_search_ftp_control, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_FTP_CONTROL); } diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c index 1b5d42ffd..29a0ac33b 100644 --- a/src/lib/protocols/ftp_data.c +++ b/src/lib/protocols/ftp_data.c @@ -238,7 +238,7 @@ static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { @@ -248,14 +248,10 @@ static void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struc } -void init_ftp_data_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ftp_data_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("FTP_DATA", ndpi_struct, *id, - NDPI_PROTOCOL_FTP_DATA, - ndpi_search_ftp_data, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("FTP_DATA", ndpi_struct, + ndpi_search_ftp_data, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_FTP_DATA); } diff --git a/src/lib/protocols/gaijin_entertainment.c b/src/lib/protocols/gaijin_entertainment.c index 7f089ab5d..7da0658d4 100644 --- a/src/lib/protocols/gaijin_entertainment.c +++ b/src/lib/protocols/gaijin_entertainment.c @@ -63,18 +63,13 @@ static void ndpi_search_gaijin(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_gaijin_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_gaijin_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("GaijinEntertainment", ndpi_struct, *id, - NDPI_PROTOCOL_GAIJIN, - ndpi_search_gaijin, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("GaijinEntertainment", ndpi_struct, + ndpi_search_gaijin, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_GAIJIN); } diff --git a/src/lib/protocols/gearman.c b/src/lib/protocols/gearman.c index 5cfb6b425..20b30683c 100644 --- a/src/lib/protocols/gearman.c +++ b/src/lib/protocols/gearman.c @@ -47,16 +47,13 @@ static void ndpi_search_gearman(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_gearman_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_gearman_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Gearman", ndpi_struct, *id, - NDPI_PROTOCOL_GEARMAN, - ndpi_search_gearman, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Gearman", ndpi_struct, + ndpi_search_gearman, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_GEARMAN); } diff --git a/src/lib/protocols/gearup_booster.c b/src/lib/protocols/gearup_booster.c new file mode 100644 index 000000000..6cdd1284f --- /dev/null +++ b/src/lib/protocols/gearup_booster.c @@ -0,0 +1,92 @@ +/* + * gearup_booster.c + * + * Copyright (C) 2011-25 - 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 + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_GEARUP_BOOSTER + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_int_gearup_booster_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow) +{ + NDPI_LOG_INFO(ndpi_struct, "found GearUP Booster\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, + NDPI_PROTOCOL_GEARUP_BOOSTER, + NDPI_PROTOCOL_UNKNOWN, + NDPI_CONFIDENCE_DPI); +} + +static void ndpi_search_gearup_booster(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search GearUP Booster\n"); + + if (packet->udp->source != htons(9999) && packet->udp->dest != htons(9999)) + { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + if (flow->packet_counter == 1) + { + if (packet->packet_direction != 0 || packet->udp->dest != htons(9999)) + { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + } + + if (packet->payload_packet_len == 4) + { + // mobile version + if (ntohl(get_u_int32_t(packet->payload, 0)) == 0x00000000) + { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + } else if (packet->payload_packet_len == 8) + { + // desktop version + if (ntohl(get_u_int32_t(packet->payload, 0)) == 0x00000000 || + packet->payload[7] != 0x00 || packet->payload[6] != 0x00 || packet->payload[5] != 0x00) + { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + } else { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + ndpi_int_gearup_booster_add_connection(ndpi_struct, flow); +} + +void init_gearup_booster_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("GeaUP_Booster", ndpi_struct, + ndpi_search_gearup_booster, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_GEARUP_BOOSTER); +} + diff --git a/src/lib/protocols/genshin_impact.c b/src/lib/protocols/genshin_impact.c index abe15afb5..3be67524a 100644 --- a/src/lib/protocols/genshin_impact.c +++ b/src/lib/protocols/genshin_impact.c @@ -67,21 +67,16 @@ static void ndpi_search_genshin_impact(struct ndpi_detection_module_struct *ndpi } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************************** */ -void init_genshin_impact_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_genshin_impact_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("GenshinImpact", - ndpi_struct, *id, - NDPI_PROTOCOL_GENSHIN_IMPACT, - ndpi_search_genshin_impact, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("GenshinImpact", ndpi_struct, + ndpi_search_genshin_impact, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_GENSHIN_IMPACT); } diff --git a/src/lib/protocols/git.c b/src/lib/protocols/git.c index a4db11363..6679bf03e 100644 --- a/src/lib/protocols/git.c +++ b/src/lib/protocols/git.c @@ -68,20 +68,16 @@ static void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************************** */ -void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Git", ndpi_struct, *id, - NDPI_PROTOCOL_GIT, - ndpi_search_git, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Git", ndpi_struct, + ndpi_search_git, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_GIT); } diff --git a/src/lib/protocols/glbp.c b/src/lib/protocols/glbp.c new file mode 100644 index 000000000..b5be147d8 --- /dev/null +++ b/src/lib/protocols/glbp.c @@ -0,0 +1,81 @@ +/* + * glbp.c + * + * Gateway Load Balancing Protocol + * + * Copyright (C) 2025 - ntop.org + * Copyright (C) 2025 - V.G <v.gavrilov@securitycode.ru> + * + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_GLBP + +#include "ndpi_api.h" +#include "ndpi_private.h" + +#define GLBP_PORT 3222 /* IANA registered */ + +static void ndpi_int_glbp_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow) +{ + NDPI_LOG_INFO(ndpi_struct, "found GLBP\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, + NDPI_PROTOCOL_GLBP, NDPI_PROTOCOL_UNKNOWN, + NDPI_CONFIDENCE_DPI); +} + +static void ndpi_search_glbp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search GLBP\n"); + + if (packet->payload_packet_len < 12) { + goto exclude; + } + + if ((packet->udp->source != htons(GLBP_PORT)) || + (packet->udp->dest != htons(GLBP_PORT))) + { + goto exclude; + } + + if ((packet->payload[0] > 1) || + (ntohs(get_u_int16_t(packet->payload, 2)) > 1023)) + { + goto exclude; + } + + ndpi_int_glbp_add_connection(ndpi_struct, flow); + return; + +exclude: + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +void init_glbp_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("GLBP", ndpi_struct, + ndpi_search_glbp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_GLBP); +} diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c index 1e0f307eb..0acfc1740 100644 --- a/src/lib/protocols/gnutella.c +++ b/src/lib/protocols/gnutella.c @@ -2,7 +2,7 @@ * gnutella.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,22 +42,10 @@ static void ndpi_int_gnutella_add_connection(struct ndpi_detection_module_struct static void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - u_int16_t c; NDPI_LOG_DBG(ndpi_struct, "search GNUTELLA\n"); - /* skip packets without payload */ - if (packet->payload_packet_len < 2) { - return; - } if (packet->tcp != NULL) { - /* this case works asymmetrically */ - if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) { - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - /* this case works asymmetrically */ if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) { ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); /* Extract some metadata HTTP-like */ @@ -66,281 +54,37 @@ static void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struc ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len); return; } - - if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) - || (memcmp(packet->payload, "GET /uri-res/", 13) == 0) - )) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - for (c = 0; c < packet->parsed_lines; c++) { - if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0) - || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0) - || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0) - || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr, - "Content-Type: application/x-gnutella-", 37) == 0)) { - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - /* Extract some metadata HTTP-like */ - if(packet->user_agent_line.ptr != NULL) - ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len); - return; - } - } - } - if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 10) == 0))) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15 - && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0) - || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24 - && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) { - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - /* Extract some metadata HTTP-like */ - if(packet->user_agent_line.ptr != NULL) - ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len); - } - - } - /* haven't found this pattern in any trace. */ - if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) - || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) { - c = 8; - while (c < (packet->payload_packet_len - 9)) { - if (packet->payload[c] == '?') { - c++; - break; - } - c++; - } - - if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected GET /get/ or GET /uri-res/\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - } - - } - - /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets, - * it is searched in the upper paragraph. */ - if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected HEAD /gnutella/push-proxy?\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - /* haven't found any trace with this pattern */ - if (packet->payload_packet_len == 46 - && memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) { - NDPI_LOG_DBG2(ndpi_struct, - "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - /* haven't found any trace with this pattern */ - if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0) - //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/: - { - const u_int16_t end = packet->payload_packet_len - 3; - - c = 13; - while (c < end) { - if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0) - || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0) - || (end - c > 44 - && memcmp(&packet->payload[c], - "\r\nAccept: application/tigertree-breadthfirst", - 44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0) - || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) { - - NDPI_LOG_DBG2(ndpi_struct, "FOXY :: GNUTELLA GET 2 DETECTED\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - - c++; - } - } - /* haven't found any trace with this pattern */ - if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a - && packet->payload[packet->payload_packet_len - 2] == 0x0a) { - if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "MORPHEUS GIV DETECTED\n"); - /* Not Excluding the flow now.. We shall Check the next Packet too for Gnutella Patterns */ - return; - } - } - /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */ - if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) && - get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) && - get_u_int16_t(packet->payload, 12) == htons(0x0034)) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella len == 46\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if (packet->payload_packet_len == 49 && - memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c", - 19) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella len == 49\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 && - memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 && - memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) { - NDPI_LOG_DBG2(ndpi_struct, - "detected gnutella asymmetrically len == 388.\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } else if (packet->payload_packet_len == 82) { - if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100) - && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000) - && get_u_int16_t(packet->payload, 8) == htons(0x4903) - && get_u_int16_t(packet->payload, 76) == htons(0x0002) - && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) { - NDPI_LOG_DBG2(ndpi_struct, "detected len == 82\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - } } else if (packet->udp != NULL) { /* Check for Mojito-DHT encapsulated gnutella (gtk-gnutella). */ - if (packet->payload_packet_len >= 28 && - ntohl(get_u_int32_t(packet->payload, 24)) == 0x47544b47 /* GTKG */) - { - u_int32_t gnutella_payload_len = le32toh(get_u_int32_t(packet->payload, 19)); - - if (gnutella_payload_len == (u_int32_t)packet->payload_packet_len - 23) - { - NDPI_LOG_DBG2(ndpi_struct, "detected mojito-dht/gnutella udp\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - } - - /* observations: - * all the following patterns send out many packets which are the only ones of their flows, - * often on the very beginning of the traces, or flows with many packets in one direction only. - * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483. - * Maybe gnutella tries to send out keys? - */ - if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00 - && packet->payload[16] == 0x41 && packet->payload[17] == 0x01 - && packet->payload[18] == 0x00 && packet->payload[19] == 0x00 - && packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 23\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - - return; - } - if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49 - && packet->payload[26] == 0x50 && packet->payload[27] == 0x40 - && packet->payload[28] == 0x83 && packet->payload[29] == 0x53 - && packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 35\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if (packet->payload_packet_len == 32 - && (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 32\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0) - && (memcmp(&packet->payload[30], "DNA@", 4) == 0)) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 34\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96) - && memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 73,96\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - - 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 - && - (memcmp - (&packet->payload[6], "\x01\x01\x4c\x05\x50", - 5) == 0)) - || (packet->payload_packet_len == 28 - && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0)) - || (packet->payload_packet_len == 41 - && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0)) - || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03) - || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, GND\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; + if (packet->payload_packet_len > 23) { + u_int32_t gnutella_payload_len = le32toh(get_u_int32_t(packet->payload, 19)); + + if (gnutella_payload_len == (u_int32_t)packet->payload_packet_len - 23 && + ((packet->payload_packet_len > 27 && + ntohl(get_u_int32_t(packet->payload, 24)) == 0x47544b47 /* GTKG */) || + ntohl(get_u_int32_t(packet->payload, packet->payload_packet_len - 4)) == 0x82514b40)) { + NDPI_LOG_DBG2(ndpi_struct, "detected mojito-dht/gnutella udp\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); + return; } } + if (packet->payload_packet_len >= 4 && memcmp(packet->payload, "GND\x10", 4) == 0) { NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, GND (2)\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); return; } - - if ((packet->payload_packet_len == 32) - && memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 32 ii\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - if ((packet->payload_packet_len == 23) - && memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) { - NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 23 ii\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } } - //neonet detection follows - /* haven't found any trace with this pattern */ - if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) { - if (flow->l4.tcp.gnutella_stage == 0) { - if (flow->packet_counter == 1 - && (packet->payload_packet_len == 11 - || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) { - flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4]; - flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6]; - flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8]; - flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction; - return; - } - } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) { - if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22) - && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] - && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] - && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]) { - NDPI_LOG_DBG2(ndpi_struct, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) { - if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75) - && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] - && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] - && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]) { - NDPI_LOG_DBG2(ndpi_struct, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); - ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI); - return; - } - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_gnutella_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_gnutella_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Gnutella", ndpi_struct, *id, - NDPI_PROTOCOL_GNUTELLA, - ndpi_search_gnutella, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Gnutella", ndpi_struct, + ndpi_search_gnutella, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_GNUTELLA); } diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c index b26247a9c..1a25a6315 100644 --- a/src/lib/protocols/gtp.c +++ b/src/lib/protocols/gtp.c @@ -1,7 +1,7 @@ /* * gtp.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -115,7 +115,7 @@ static void ndpi_check_gtp(struct ndpi_detection_module_struct *ndpi_struct, str } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -127,14 +127,10 @@ static void ndpi_search_gtp(struct ndpi_detection_module_struct *ndpi_struct, st } -void init_gtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_gtp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("GTP", ndpi_struct, *id, - NDPI_PROTOCOL_GTP, - ndpi_search_gtp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("GTP", ndpi_struct, + ndpi_search_gtp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_GTP); } diff --git a/src/lib/protocols/guildwars.c b/src/lib/protocols/guildwars.c deleted file mode 100644 index 202c425bd..000000000 --- a/src/lib/protocols/guildwars.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * guildwars.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_GUILDWARS - -#include "ndpi_api.h" -#include "ndpi_private.h" - - -static void ndpi_int_guildwars_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GUILDWARS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - -static void ndpi_search_guildwars_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search guildwars\n"); - - if (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 1) == ntohs(0x050c) - && memcmp(&packet->payload[50], "@2&P", 4) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found GuildWars version 29.350\n"); - ndpi_int_guildwars_add_connection(ndpi_struct, flow); - return; - } - if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 1) == ntohs(0x040c) - && get_u_int16_t(packet->payload, 4) == ntohs(0xa672) - && packet->payload[8] == 0x01 && packet->payload[12] == 0x04) { - NDPI_LOG_INFO(ndpi_struct, "found GuildWars version 29.350\n"); - ndpi_int_guildwars_add_connection(ndpi_struct, flow); - return; - } - if (packet->payload_packet_len == 21 && get_u_int16_t(packet->payload, 0) == ntohs(0x0100) - && get_u_int32_t(packet->payload, 5) == ntohl(0xf1001000) - && packet->payload[9] == 0x01) { - NDPI_LOG_INFO(ndpi_struct, "found GuildWars version 216.107.245.50\n"); - ndpi_int_guildwars_add_connection(ndpi_struct, flow); - return; - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_guildwars_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("Guildwars", ndpi_struct, *id, - NDPI_PROTOCOL_GUILDWARS, - ndpi_search_guildwars_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} diff --git a/src/lib/protocols/guildwars2.c b/src/lib/protocols/guildwars2.c new file mode 100644 index 000000000..be8740a94 --- /dev/null +++ b/src/lib/protocols/guildwars2.c @@ -0,0 +1,62 @@ +/* + * guildwars2.c + * + * Copyright (C) 2009-11 - ipoque GmbH + * Copyright (C) 2011-25 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_GUILDWARS2 + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_search_guildwars2_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search Guild Wars 2\n"); + + if (packet->payload_packet_len > 50) + { + /* The connection starts with this preamble containing client info. + * The TLS handshake begins around packet 12. */ + if ((memcmp(packet->payload, "P /Sts/Connect STS/1.0", 22) == 0) || + (memcmp(packet->payload, "P /Auth/StartTls STS/1.0", 24) == 0) || + (memcmp(packet->payload, "STS/1.0 400 Success", 19) == 0)) + { + NDPI_LOG_INFO(ndpi_struct, "found Guild Wars 2\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GUILDWARS2, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + return; + } + } + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + + +void init_guildwars2_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("GuildWars2", ndpi_struct, + ndpi_search_guildwars2_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_GUILDWARS2); +} diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c index 4a792a659..db6eb0b69 100644 --- a/src/lib/protocols/h323.c +++ b/src/lib/protocols/h323.c @@ -68,18 +68,13 @@ static void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_h323_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_h323_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("H323", ndpi_struct, *id, - NDPI_PROTOCOL_H323, - ndpi_search_h323, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("H323", ndpi_struct, + ndpi_search_h323, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_H323); } diff --git a/src/lib/protocols/halflife2_and_mods.c b/src/lib/protocols/halflife2_and_mods.c deleted file mode 100644 index e18434a95..000000000 --- a/src/lib/protocols/halflife2_and_mods.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * halflife2_and_mods.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HALFLIFE2 - -#include "ndpi_api.h" -#include "ndpi_private.h" - - -static void ndpi_int_halflife2_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HALFLIFE2, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - -static void ndpi_search_halflife2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search halflife2\n"); - - if (flow->l4.udp.halflife2_stage == 0) { - if (packet->payload_packet_len >= 20 - && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF - && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) { - flow->l4.udp.halflife2_stage = 1 + packet->packet_direction; - NDPI_LOG_DBG2(ndpi_struct, - "halflife2 client req detected, waiting for server reply\n"); - return; - } - } else if (flow->l4.udp.halflife2_stage == 2 - packet->packet_direction) { - if (packet->payload_packet_len >= 20 - && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF - && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) { - ndpi_int_halflife2_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "found halflife2\n"); - return; - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_halflife2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("HalfLife2", ndpi_struct, *id, - NDPI_PROTOCOL_HALFLIFE2, - ndpi_search_halflife2, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} diff --git a/src/lib/protocols/hamachi.c b/src/lib/protocols/hamachi.c new file mode 100644 index 000000000..b30f0935b --- /dev/null +++ b/src/lib/protocols/hamachi.c @@ -0,0 +1,173 @@ +/* + * hamachi.c + * + * LogMeIn Hamachi + * + * Copyright (C) 2025 - ntop.org + * Copyright (C) 2025 - V.G <v.gavrilov@securitycode.ru> + * + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HAMACHI + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_int_hamachi_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + NDPI_LOG_INFO(ndpi_struct, "found Hamachi\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HAMACHI, + NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); +} + +static void search_hamachi_tcp(struct ndpi_detection_module_struct* ndpi_struct, + struct ndpi_flow_struct* flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search Hamachi over TCP\n"); + + if (packet->payload_packet_len > 300 && + ntohl(get_u_int32_t(packet->payload, 0)) == (u_int32_t)(packet->payload_packet_len-4) && + ntohl(get_u_int32_t(packet->payload, 12)) == 0x7B7A0DAD) + { + ndpi_int_hamachi_add_connection(ndpi_struct, flow); + return; + } + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +static void search_hamachi_udp(struct ndpi_detection_module_struct* ndpi_struct, + struct ndpi_flow_struct* flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search Hamachi over UDP\n"); + + /* Skip initial 76-byte handshake (relay mode only) */ + if (flow->packet_counter <= 2 && packet->payload_packet_len == 76) + { + if (get_u_int64_t(packet->payload, 0) != 0 || + get_u_int64_t(packet->payload, 68) != 0) + { + goto exclude_hamachi; + } + return; /* Likely Hamachi handshake */ + } + + /* Empirically observed minimum */ + if (packet->payload_packet_len < 46) { + goto exclude_hamachi; + } + + /* Reasonable value for heuristics */ + u_int32_t seq = ntohl(get_u_int32_t(packet->payload, 4)); + if (seq == 0 || seq > 0xFFFF) { + goto exclude_hamachi; + } + + u_int32_t hamachi_l = ntohl(get_u_int32_t(packet->payload, 0)); + u_int16_t hamachi_s = ntohs(get_u_int16_t(packet->payload, 8)); + + if (hamachi_l == 0xFFFFFFFF || hamachi_l == 0) + { + goto exclude_hamachi; + } + + u_int8_t dir = packet->packet_direction; + + /* + * Hamachi detection logic using 4-stage state machine: + * Stage 0: Initial state, waiting for first packet + * Stage 1: Got packet from dir=0, waiting for dir=1 to complete verification + * Stage 2: Got packet from dir=1, waiting for dir=0 to complete verification + * Stage 3: Both directions verified, protocol identified + * + * Each direction has constant values in bytes 0-3 and 8-9 throughout the session. + * We need to verify consistency within each direction and collect samples from both. + */ + + if (flow->l4.udp.hamachi_stage == 0) { + /* Store signature values from first packet and set stage based on direction */ + flow->l4.udp.hamachi_long[dir] = hamachi_l; + flow->l4.udp.hamachi_short[dir] = hamachi_s; + flow->l4.udp.hamachi_stage = dir ? 2 : 1; /* Stage 1 for dir=0, stage 2 for dir=1 */ + return; + } + + if (flow->l4.udp.hamachi_stage == 1 || flow->l4.udp.hamachi_stage == 2) { + u_int8_t stored_dir = flow->l4.udp.hamachi_stage - 1; + /* Current packet is same direction - verify */ + if (dir == stored_dir) { + if (hamachi_l != flow->l4.udp.hamachi_long[dir] || + hamachi_s != flow->l4.udp.hamachi_short[dir]) + { + goto exclude_hamachi; + } + return; /* Still waiting for opposite direction */ + } + + /* Opposite direction - verify signatures differ */ + if (hamachi_l == flow->l4.udp.hamachi_long[stored_dir] || + hamachi_s == flow->l4.udp.hamachi_short[stored_dir]) + { + goto exclude_hamachi; + } + + flow->l4.udp.hamachi_long[dir] = hamachi_l; + flow->l4.udp.hamachi_short[dir] = hamachi_s; + flow->l4.udp.hamachi_stage = 3; + return; + } + + if (flow->l4.udp.hamachi_stage == 3) { + /* Final consistency check */ + if (hamachi_l != flow->l4.udp.hamachi_long[dir] || + hamachi_s != flow->l4.udp.hamachi_short[dir]) + { + goto exclude_hamachi; + } + + ndpi_int_hamachi_add_connection(ndpi_struct, flow); + return; + } + +exclude_hamachi: + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +static void ndpi_search_hamachi(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) +{ + if(flow->l4_proto == IPPROTO_TCP) + search_hamachi_tcp(ndpi_struct, flow); + else + search_hamachi_udp(ndpi_struct, flow); +} + +void init_hamachi_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("Hamachi", ndpi_struct, + ndpi_search_hamachi, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HAMACHI); +} diff --git a/src/lib/protocols/haproxy.c b/src/lib/protocols/haproxy.c index b932d99fa..63d1d63b0 100644 --- a/src/lib/protocols/haproxy.c +++ b/src/lib/protocols/haproxy.c @@ -39,13 +39,13 @@ static void ndpi_search_haproxy(struct ndpi_detection_module_struct *ndpi_struct if (packet->payload_packet_len < NDPI_STATICSTRING_LEN("PROXY TCP")) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (strncmp((char *)packet->payload, "PROXY TCP", NDPI_STATICSTRING_LEN("PROXY TCP")) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -53,27 +53,23 @@ static void ndpi_search_haproxy(struct ndpi_detection_module_struct *ndpi_struct haproxy_end = (uint8_t *)ndpi_strnstr((char *)packet->payload, "\r\n", packet->payload_packet_len); if (haproxy_end == NULL) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } haproxy_end += 2; if (packet->payload_packet_len - (haproxy_end - packet->payload) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ndpi_int_haproxy_add_connection(ndpi_struct, flow); } -void init_haproxy_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_haproxy_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HAProxy", ndpi_struct, *id, - NDPI_PROTOCOL_HAPROXY, - ndpi_search_haproxy, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("HAProxy", ndpi_struct, + ndpi_search_haproxy, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HAPROXY); } diff --git a/src/lib/protocols/hart-ip.c b/src/lib/protocols/hart-ip.c index 600470dd4..bd3c0fad9 100644 --- a/src/lib/protocols/hart-ip.c +++ b/src/lib/protocols/hart-ip.c @@ -97,17 +97,13 @@ static void ndpi_search_hart_ip(struct ndpi_detection_module_struct *ndpi_struct } not_hart_ip: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_hart_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_hart_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HART-IP", ndpi_struct, *id, - NDPI_PROTOCOL_HART_IP, - ndpi_search_hart_ip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("HART-IP", ndpi_struct, + ndpi_search_hart_ip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HART_IP); } diff --git a/src/lib/protocols/hcl_notes.c b/src/lib/protocols/hcl_notes.c new file mode 100644 index 000000000..aa75744e5 --- /dev/null +++ b/src/lib/protocols/hcl_notes.c @@ -0,0 +1,70 @@ +/* + * hcl_notes.c + * + * Copyright (C) 2012-22 - 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 + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HCL_NOTES + +#include "ndpi_api.h" +#include "ndpi_private.h" + +/* ************************************ */ + +static void ndpi_check_hcl_notes(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int32_t payload_len = packet->payload_packet_len; + + flow->l4.tcp.hcl_notes_packet_id++; + + if((flow->l4.tcp.hcl_notes_packet_id == 1) && + ndpi_seen_flow_beginning(flow)) { + if(payload_len > 16) { + char hcl_notes_header[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x02, 0x0F }; + + if(memcmp(&packet->payload[6], hcl_notes_header, sizeof(hcl_notes_header)) == 0) { + NDPI_LOG_INFO(ndpi_struct, "found HCL Notes\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HCL_NOTES, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + } + return; + } + + } else if(flow->l4.tcp.hcl_notes_packet_id <= 3) return; + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + +static void ndpi_search_hcl_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + NDPI_LOG_DBG(ndpi_struct, "search hcl_notes\n"); + + ndpi_check_hcl_notes(ndpi_struct, flow); +} + + +void init_hcl_notes_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("HCL_Notes", ndpi_struct, + ndpi_search_hcl_notes, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HCL_NOTES); +} + diff --git a/src/lib/protocols/hislip.c b/src/lib/protocols/hislip.c index 98eea373a..78d3a9928 100644 --- a/src/lib/protocols/hislip.c +++ b/src/lib/protocols/hislip.c @@ -56,17 +56,13 @@ static void ndpi_search_hislip(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_hislip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_hislip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HiSLIP", ndpi_struct, *id, - NDPI_PROTOCOL_HISLIP, - ndpi_search_hislip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("HiSLIP", ndpi_struct, + ndpi_search_hislip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HISLIP); } diff --git a/src/lib/protocols/hl7.c b/src/lib/protocols/hl7.c index baeaf69d7..2b086ebe2 100644 --- a/src/lib/protocols/hl7.c +++ b/src/lib/protocols/hl7.c @@ -66,17 +66,13 @@ static void ndpi_search_hl7(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_hl7_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_hl7_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HL7", ndpi_struct, *id, - NDPI_PROTOCOL_HL7, - ndpi_search_hl7, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("HL7", ndpi_struct, + ndpi_search_hl7, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HL7); } diff --git a/src/lib/protocols/hots.c b/src/lib/protocols/hots.c index 38420ce3a..5e91acfb6 100644 --- a/src/lib/protocols/hots.c +++ b/src/lib/protocols/hots.c @@ -60,17 +60,14 @@ void ndpi_search_hots(struct ndpi_detection_module_struct *ndpi_struct, struct n break; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_hots_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_hots_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HOTS", ndpi_struct, *id, - NDPI_PROTOCOL_HOTS, - ndpi_search_hots, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Only IPv4 UDP traffic is expected. */ - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("HOTS", ndpi_struct, + ndpi_search_hots, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Only IPv4 UDP traffic is expected. */ + 1, NDPI_PROTOCOL_HOTS); } diff --git a/src/lib/protocols/hpvirtgrp.c b/src/lib/protocols/hpvirtgrp.c index 3e8e03ccc..37d38d501 100644 --- a/src/lib/protocols/hpvirtgrp.c +++ b/src/lib/protocols/hpvirtgrp.c @@ -51,21 +51,16 @@ static void ndpi_search_hpvirtgrp(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************************** */ -void init_hpvirtgrp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_hpvirtgrp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HP Virtual Machine Group Management", - ndpi_struct, *id, - NDPI_PROTOCOL_HPVIRTGRP, - ndpi_search_hpvirtgrp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("HP Virtual Machine Group Management", ndpi_struct, + ndpi_search_hpvirtgrp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HPVIRTGRP); } diff --git a/src/lib/protocols/hsrp.c b/src/lib/protocols/hsrp.c index de980344c..d6bf51dba 100644 --- a/src/lib/protocols/hsrp.c +++ b/src/lib/protocols/hsrp.c @@ -1,7 +1,7 @@ /* * ayiya.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -77,18 +77,13 @@ static void ndpi_search_hsrp(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_hsrp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("HSRP", ndpi_struct, *id, - NDPI_PROTOCOL_HSRP, - ndpi_search_hsrp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_hsrp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("HSRP", ndpi_struct, + ndpi_search_hsrp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_HSRP); } diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 9064f7282..26375fc64 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -1,7 +1,7 @@ /* * http.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,11 +199,15 @@ static void ndpi_http_check_human_redeable_content(struct ndpi_detection_module_ && (content[3] == 0x00)) { /* Looks like compressed data */ } else { - char str[32]; - - snprintf(str, sizeof(str), "Susp content %02X%02X%02X%02X", - content[0], content[1], content[2], content[3]); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, str); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_CONTENT)) { + char str[32]; + + snprintf(str, sizeof(str), "Susp content %02X%02X%02X%02X", + content[0], content[1], content[2], content[3]); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, NULL); + } } } } @@ -281,7 +285,7 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo u_int app_len_avail = packet->content_line.len-app_len; if(strncasecmp(app, "mpeg", app_len_avail) == 0) { - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_STREAMING; + flow->category = NDPI_PROTOCOL_CATEGORY_STREAMING; return(flow->category); } else { if(app_len_avail > 3) { @@ -301,7 +305,7 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo if(strncasecmp(app, cmp_mimes[i], app_len_avail) == 0) { char str[64]; - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; + flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; NDPI_LOG_INFO(ndpi_struct, "found HTTP file transfer"); snprintf(str, sizeof(str), "Found binary mime %s", cmp_mimes[i]); @@ -330,7 +334,7 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo char str[64]; snprintf(str, sizeof(str), "Found mime exe %s", cmp_mimes[i]); - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; + flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; ndpi_set_binary_application_transfer(ndpi_struct, flow, str); NDPI_LOG_INFO(ndpi_struct, "Found executable HTTP transfer"); } @@ -393,7 +397,7 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo binary_exec_file_ext[i], ATTACHMENT_LEN) == 0) { snprintf(str, sizeof(str), "Found file extn %s", binary_exec_file_ext[i]); - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; + flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; ndpi_set_binary_application_transfer(ndpi_struct, flow, str); NDPI_LOG_INFO(ndpi_struct, "found executable HTTP transfer"); return(flow->category); @@ -413,13 +417,13 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo case 'a': if(strncasecmp((const char *)packet->content_line.ptr, "audio", ndpi_min(packet->content_line.len, 5)) == 0) - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; + flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; break; case 'v': if(strncasecmp((const char *)packet->content_line.ptr, "video", ndpi_min(packet->content_line.len, 5)) == 0) - flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; + flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; break; } } @@ -493,7 +497,7 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp if(packet->server_line.len > 7 && strncmp((const char *)packet->server_line.ptr, "ntopng ", 7) == 0) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTOP, NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); } /* Matching on Content-Type. @@ -571,7 +575,7 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp origin_hostname, origin_hostname_len, &ret_match, - master_protocol); + master_protocol, 1); } } } @@ -642,12 +646,22 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, master_protocol, NDPI_CONFIDENCE_DPI); } + if ((flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) && + flow->http.user_agent && strstr(flow->http.user_agent, "AirControl Agent v1.0")) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UBNTAC2, master_protocol, NDPI_CONFIDENCE_DPI); + } + + if ((flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) && + flow->http.user_agent && strstr(flow->http.user_agent, "gtk-gnutella")) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GNUTELLA, master_protocol, NDPI_CONFIDENCE_DPI); + } if(flow->http.request_header_observed) { if(flow->http.first_payload_after_header_observed == 0) { /* Skip the last part of the HTTP request */ flow->http.first_payload_after_header_observed = 1; - } else if(flow->http.is_form && (packet->payload_packet_len > 0)) { + } else if(flow->http.is_form && (packet->payload_packet_len > 0) && + (ndpi_struct->cfg.http_username_enabled || ndpi_struct->cfg.http_password_enabled)) { /* Response payload */ char *dup = ndpi_strndup((const char *)packet->payload, packet->payload_packet_len); @@ -664,9 +678,9 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp break; if((strcmp(key, "user") == 0) || (strcmp(key, "username") == 0)) { - if(!flow->http.username) flow->http.username = ndpi_strdup(value); + if(!flow->http.username && ndpi_struct->cfg.http_username_enabled) flow->http.username = ndpi_strdup(value); } else if((strcmp(key, "pwd") == 0) || (strcmp(key, "password") == 0)) { - if(!flow->http.password) flow->http.password = ndpi_strdup(value); + if(!flow->http.password && ndpi_struct->cfg.http_password_enabled) flow->http.password = ndpi_strdup(value); ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password"); } @@ -713,10 +727,14 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru float upper_case_ratio = (float)upper_case_count / (float)ua_len; if (upper_case_ratio >= 0.2f) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_USER_AGENT)) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } } } @@ -724,20 +742,28 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru if((!strncmp(ua, "<?", 2)) || strchr(ua, '$') ) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_USER_AGENT)) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } if((double_slash = strstr(ua, "://")) != NULL) { if(double_slash != ua) /* We're not at the beginning of the user agent */{ if((double_slash[-1] != 'p') /* http:// */ && (double_slash[-1] != 's') /* https:// */) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_USER_AGENT)) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } } } @@ -765,11 +791,15 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru || ndpi_strncasestr(ua, "Crawler", ua_len) || ndpi_strncasestr(ua, "Bot", ua_len) /* bot/robot */ ) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_CRAWLER_BOT)) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); + snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, str); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, NULL); + } } } @@ -838,7 +868,7 @@ static void http_process_user_agent(struct ndpi_detection_module_struct *ndpi_st } if(ndpi_user_agent_set(flow, ua_ptr, ua_ptr_len) != NULL) { - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); ndpi_check_user_agent(ndpi_struct, flow, flow->http.user_agent, ua_ptr_len); } else { NDPI_LOG_DBG2(ndpi_struct, "Could not set HTTP user agent (already set?)\n"); @@ -864,10 +894,14 @@ static void ndpi_check_numeric_ip(struct ndpi_detection_module_struct *ndpi_stru ip_addr.s_addr = inet_addr(buf); if(strcmp(inet_ntoa(ip_addr), buf) == 0) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_NUMERIC_IP_HOST)) { + char str[64]; - snprintf(str, sizeof(str), "Found host %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, str); + snprintf(str, sizeof(str), "Found host %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, NULL); + } } } @@ -876,12 +910,24 @@ static void ndpi_check_numeric_ip(struct ndpi_detection_module_struct *ndpi_stru static void ndpi_check_http_url(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *url) { - if(strstr(url, "<php>") != NULL /* PHP code in the URL */) - ndpi_set_risk(ndpi_struct, flow, NDPI_URL_POSSIBLE_RCE_INJECTION, "PHP code in URL"); - else if(strncmp(url, "/shell?", 7) == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_URL_POSSIBLE_RCE_INJECTION, "Possible WebShell detected"); - else if(strncmp(url, "/.", 2) == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "URL starting with dot"); + char msg[512]; + ndpi_risk_enum r; + + if(strstr(url, "<php>") != NULL /* PHP code in the URL */) { + r = NDPI_URL_POSSIBLE_RCE_INJECTION; + snprintf(msg, sizeof(msg), "PHP code in URL [%s]", url); + } else if(strncmp(url, "/shell?", 7) == 0) { + r = NDPI_URL_POSSIBLE_RCE_INJECTION; + snprintf(msg, sizeof(msg), "Possible WebShell detected [%s]", url); + } else if(strncmp(url, "/.", 2) == 0) { + r = NDPI_POSSIBLE_EXPLOIT; + snprintf(msg, sizeof(msg), "URL starting with dot [%s]", url); + } else { + r = ndpi_validate_url(ndpi_struct, flow, url); + return; + } + + ndpi_set_risk(ndpi_struct, flow, r, msg); } /* ************************************************************* */ @@ -910,11 +956,19 @@ static void ndpi_check_http_server(struct ndpi_detection_module_struct *ndpi_str char msg[64]; if((off == 7) && (version < MIN_APACHE_VERSION)) { - snprintf(msg, sizeof(msg), "Obsolete Apache server %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_OBSOLETE_SERVER)) { + snprintf(msg, sizeof(msg), "Obsolete Apache server %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, NULL); + } } else if((off == 6) && (version < MIN_NGINX_VERSION)) { - snprintf(msg, sizeof(msg), "Obsolete nginx server %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_OBSOLETE_SERVER)) { + snprintf(msg, sizeof(msg), "Obsolete nginx server %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, NULL); + } } } } @@ -922,7 +976,11 @@ static void ndpi_check_http_server(struct ndpi_detection_module_struct *ndpi_str /* Check server content */ for(i=0; i<server_len; i++) { if(!ndpi_isprint(server[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, "Suspicious Agent"); + char msg[64]; + + snprintf(msg, sizeof(msg), "Suspicious Agent [%.*s]", server_len, server); + + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, msg); break; } } @@ -1025,7 +1083,8 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } } - if(packet->authorization_line.ptr != NULL) { + if(packet->authorization_line.ptr != NULL && + (ndpi_struct->cfg.http_username_enabled || ndpi_struct->cfg.http_password_enabled)) { const char *a = NULL, *b = NULL; NDPI_LOG_DBG2(ndpi_struct, "Authorization line found %.*s\n", @@ -1048,8 +1107,10 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(double_dot) { double_dot[0] = '\0'; - flow->http.username = ndpi_strdup((char*)content); - flow->http.password = ndpi_strdup(&double_dot[1]); + if(ndpi_struct->cfg.http_username_enabled) + flow->http.username = ndpi_strdup((char*)content); + if(ndpi_struct->cfg.http_password_enabled) + flow->http.password = ndpi_strdup(&double_dot[1]); } ndpi_free(content); @@ -1063,10 +1124,12 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } if((packet->referer_line.ptr != NULL) && (flow->http.referer == NULL)) - flow->http.referer = ndpi_strndup(packet->referer_line.ptr, packet->referer_line.len); + if(ndpi_struct->cfg.http_referer_enabled) + flow->http.referer = ndpi_strndup((const char *)packet->referer_line.ptr, packet->referer_line.len); if((packet->host_line.ptr != NULL) && (flow->http.host == NULL)) - flow->http.host = ndpi_strndup(packet->host_line.ptr, packet->host_line.len); + if(ndpi_struct->cfg.http_host_enabled) + flow->http.host = ndpi_strndup((const char *)packet->host_line.ptr, packet->host_line.len); if(packet->content_line.ptr != NULL) { NDPI_LOG_DBG2(ndpi_struct, "Content Type line found %.*s\n", @@ -1075,16 +1138,18 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(flow->http.response_status_code == 0) { /* Request */ if((flow->http.request_content_type == NULL) && (packet->content_line.len > 0)) { - int len = packet->content_line.len + 1; - - flow->http.request_content_type = ndpi_malloc(len); - if(flow->http.request_content_type) { - strncpy(flow->http.request_content_type, (char*)packet->content_line.ptr, - packet->content_line.len); - flow->http.request_content_type[packet->content_line.len] = '\0'; + if(ndpi_struct->cfg.http_request_content_type_enabled) { + int len = packet->content_line.len + 1; + + flow->http.request_content_type = ndpi_malloc(len); + if(flow->http.request_content_type) { + strncpy(flow->http.request_content_type, (char*)packet->content_line.ptr, + packet->content_line.len); + flow->http.request_content_type[packet->content_line.len] = '\0'; + } } - if(ndpi_strnstr(flow->http.request_content_type, "x-www-form-urlencoded", packet->content_line.len)) + if(ndpi_strnstr((char*)packet->content_line.ptr, "x-www-form-urlencoded", packet->content_line.len)) flow->http.is_form = 1; } } else { @@ -1098,7 +1163,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ packet->content_line.len); flow->http.content_type[packet->content_line.len] = '\0'; - flow->guessed_category = flow->category = ndpi_http_check_content(ndpi_struct, flow); + flow->category = ndpi_http_check_content(ndpi_struct, flow); } } } @@ -1122,12 +1187,18 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(ndpi_is_valid_hostname((char *)packet->host_line.ptr, packet->host_line.len) == 0) { char str[128]; - - snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_INVALID_CHARACTERS)) { + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } /* This looks like an attack */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious hostname: attack ?"); + + snprintf(str, sizeof(str), "Suspicious hostname [%.*s]: attack ?", packet->host_line.len, (char *)packet->host_line.ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, str); } double_col = strchr((char*)flow->host_server_name, ':'); @@ -1137,11 +1208,15 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ /* IPv4 */ if(ndpi_struct->packet.iph->daddr != inet_addr(flow->host_server_name)) { - char buf[64], msg[128]; - - snprintf(msg, sizeof(msg), "Expected %s, found %s", - ndpi_intoav4(ntohl(ndpi_struct->packet.iph->daddr), buf, sizeof(buf)), flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, msg); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char buf[64], msg[128]; + + snprintf(msg, sizeof(msg), "Expected %s, found %s", + ndpi_intoav4(ntohl(ndpi_struct->packet.iph->daddr), buf, sizeof(buf)), flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } } } } @@ -1151,7 +1226,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ ndpi_http_parse_subprotocol(ndpi_struct, flow, hostname_just_set); if(hostname_just_set && strlen(flow->host_server_name) > 0) { - ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0); + ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0, 0); } ndpi_check_http_header(ndpi_struct, flow); @@ -1278,82 +1353,118 @@ static void ndpi_check_http_header(struct ndpi_detection_module_struct *ndpi_str switch(packet->line[i].ptr[0]) { case 'A': if(is_a_suspicious_header(suspicious_http_header_keys_A, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'C': if(is_a_suspicious_header(suspicious_http_header_keys_C, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'M': if(is_a_suspicious_header(suspicious_http_header_keys_M, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'O': if(is_a_suspicious_header(suspicious_http_header_keys_O, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'R': if(is_a_suspicious_header(suspicious_http_header_keys_R, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'S': if(is_a_suspicious_header(suspicious_http_header_keys_S, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'T': if(is_a_suspicious_header(suspicious_http_header_keys_T, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'U': if(is_a_suspicious_header(suspicious_http_header_keys_U, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'X': if(is_a_suspicious_header(suspicious_http_header_keys_X, packet->line[i])) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_HTTP_SUSPICIOUS_HEADER)) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } @@ -1394,7 +1505,10 @@ static void parse_response_code(struct ndpi_detection_module_struct *ndpi_struct || ((flow->http.method == NDPI_HTTP_METHOD_GET) && (strncmp(slash, "/wp-content/uploads/", 20) == 0)) )) { /* Example of popular exploits https://www.wordfence.com/blog/2022/05/millions-of-attacks-target-tatsu-builder-plugin/ */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Possible Wordpress Exploit"); + char str[128]; + + snprintf(str, sizeof(str), "Possible Wordpress Exploit [%s]", slash); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, str); } } } @@ -1490,7 +1604,7 @@ static void reset(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct, "Reset status and risks\n"); - /* Reset everthing in flow->http. + /* Reset everything in flow->http. TODO: Could we be smarter? Probably some info don't change across different req-res transactions... */ @@ -1517,6 +1631,14 @@ static void reset(struct ndpi_detection_module_struct *ndpi_struct, ndpi_free(flow->http.server); flow->http.server = NULL; } + if(flow->http.referer) { + ndpi_free(flow->http.referer); + flow->http.referer = NULL; + } + if(flow->http.host) { + ndpi_free(flow->http.host); + flow->http.host = NULL; + } if(flow->http.detected_os) { ndpi_free(flow->http.detected_os); flow->http.detected_os = NULL; @@ -1529,23 +1651,31 @@ static void reset(struct ndpi_detection_module_struct *ndpi_struct, ndpi_free(flow->http.filename); flow->http.filename = NULL; } + if(flow->http.username) { + ndpi_free(flow->http.username); + flow->http.username = NULL; + } + if(flow->http.password) { + ndpi_free(flow->http.password); + flow->http.password = NULL; + } /* Reset flow risks. We should reset only those risks triggered by the previous HTTP response... */ /* TODO */ - ndpi_unset_risk(flow, NDPI_BINARY_APPLICATION_TRANSFER); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_CONTENT); - ndpi_unset_risk(flow, NDPI_POSSIBLE_EXPLOIT); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); - ndpi_unset_risk(flow, NDPI_HTTP_CRAWLER_BOT); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); - ndpi_unset_risk(flow, NDPI_URL_POSSIBLE_RCE_INJECTION); - ndpi_unset_risk(flow, NDPI_HTTP_OBSOLETE_SERVER); - ndpi_unset_risk(flow, NDPI_CLEAR_TEXT_CREDENTIALS); - ndpi_unset_risk(flow, NDPI_INVALID_CHARACTERS); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_HEADER); - ndpi_unset_risk(flow, NDPI_ERROR_CODE_DETECTED); - ndpi_unset_risk(flow, NDPI_MALFORMED_PACKET); + ndpi_unset_risk(ndpi_struct, flow, NDPI_BINARY_APPLICATION_TRANSFER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_URL_POSSIBLE_RCE_INJECTION); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + ndpi_unset_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); } static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, @@ -1580,7 +1710,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct } /* The first pkt is neither a request nor a response -> no http */ NDPI_LOG_DBG2(ndpi_struct, "Neither req nor response -> exclude\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } NDPI_LOG_DBG2(ndpi_struct, "Request where expected\n"); @@ -1658,7 +1788,7 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc struct ndpi_flow_struct *flow) { /* Break after 20 packets. */ if(flow->packet_counter > 20) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -1685,40 +1815,9 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc } } -/* ********************************* */ - -ndpi_http_method ndpi_get_http_method(struct ndpi_flow_struct *flow) { - if(!flow) { - return(NDPI_HTTP_METHOD_UNKNOWN); - } else - return(flow->http.method); -} - -/* ********************************* */ - -char* ndpi_get_http_url(struct ndpi_flow_struct *flow) { - if((!flow) || (!flow->http.url)) - return(""); - else - return(flow->http.url); -} - -/* ********************************* */ - -char* ndpi_get_http_content_type(struct ndpi_flow_struct *flow) { - if((!flow) || (!flow->http.content_type)) - return(""); - else - return(flow->http.content_type); -} - - -void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("HTTP",ndpi_struct, *id, - NDPI_PROTOCOL_HTTP, - ndpi_search_http_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("HTTP", ndpi_struct, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HTTP); } diff --git a/src/lib/protocols/http2.c b/src/lib/protocols/http2.c index cde354a1e..c14585e80 100644 --- a/src/lib/protocols/http2.c +++ b/src/lib/protocols/http2.c @@ -43,7 +43,7 @@ void ndpi_search_http2(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search http2\n"); if(packet->payload_packet_len < NDPI_STATICSTRING_LEN(magic)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -52,17 +52,13 @@ void ndpi_search_http2(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_http2_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_http2_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("HTTP2", ndpi_struct, *id, - NDPI_PROTOCOL_HTTP2, - ndpi_search_http2, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("HTTP2", ndpi_struct, + ndpi_search_http2, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_HTTP2); } diff --git a/src/lib/protocols/i3d.c b/src/lib/protocols/i3d.c index c0cd8e447..2d579a239 100644 --- a/src/lib/protocols/i3d.c +++ b/src/lib/protocols/i3d.c @@ -50,7 +50,7 @@ static void ndpi_search_i3d(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 74) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -71,20 +71,14 @@ static void ndpi_search_i3d(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_i3d_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_i3d_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("i3D", ndpi_struct, *id, - NDPI_PROTOCOL_I3D, - ndpi_search_i3d, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("i3D", ndpi_struct, + ndpi_search_i3d, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_I3D); } diff --git a/src/lib/protocols/iax.c b/src/lib/protocols/iax.c index 45204229c..0482ffd19 100644 --- a/src/lib/protocols/iax.c +++ b/src/lib/protocols/iax.c @@ -2,7 +2,7 @@ * iax.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -82,7 +82,7 @@ static void ndpi_search_setup_iax(struct ndpi_detection_module_struct *ndpi_stru } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } @@ -96,14 +96,10 @@ static void ndpi_search_iax(struct ndpi_detection_module_struct *ndpi_struct, st } -void init_iax_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_iax_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IAX", ndpi_struct, *id, - NDPI_PROTOCOL_IAX, - ndpi_search_iax, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IAX", ndpi_struct, + ndpi_search_iax, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_IAX); } diff --git a/src/lib/protocols/icecast.c b/src/lib/protocols/icecast.c index 38967a781..04ea79d17 100644 --- a/src/lib/protocols/icecast.c +++ b/src/lib/protocols/icecast.c @@ -2,7 +2,7 @@ * icecast.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -84,18 +84,14 @@ static void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_icecast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_icecast_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IceCast", ndpi_struct, *id, - NDPI_PROTOCOL_ICECAST, - ndpi_search_icecast_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IceCast", ndpi_struct, + ndpi_search_icecast_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ICECAST); } diff --git a/src/lib/protocols/iec60870-5-104.c b/src/lib/protocols/iec60870-5-104.c index ed28313b2..dead4fba1 100644 --- a/src/lib/protocols/iec60870-5-104.c +++ b/src/lib/protocols/iec60870-5-104.c @@ -68,17 +68,13 @@ static void ndpi_search_iec60870_tcp(struct ndpi_detection_module_struct *ndpi_s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_104_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("IEC60870", ndpi_struct, *id, - NDPI_PROTOCOL_IEC60870, - ndpi_search_iec60870_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_104_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("IEC60870", ndpi_struct, + ndpi_search_iec60870_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_IEC60870); } diff --git a/src/lib/protocols/iec62056.c b/src/lib/protocols/iec62056.c index 14ede3d76..8793a8fc5 100644 --- a/src/lib/protocols/iec62056.c +++ b/src/lib/protocols/iec62056.c @@ -58,17 +58,13 @@ static void ndpi_search_iec62056(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_iec62056_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_iec62056_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IEC62056", ndpi_struct, *id, - NDPI_PROTOCOL_IEC62056, - ndpi_search_iec62056, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IEC62056", ndpi_struct, + ndpi_search_iec62056, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_IEC62056); } diff --git a/src/lib/protocols/ieee-c37118.c b/src/lib/protocols/ieee-c37118.c index dbfdbaea2..7847fe97a 100644 --- a/src/lib/protocols/ieee-c37118.c +++ b/src/lib/protocols/ieee-c37118.c @@ -63,17 +63,13 @@ static void ndpi_search_ieee_c37118(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ieee_c37118_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ieee_c37118_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IEEE-C37118", ndpi_struct, *id, - NDPI_PROTOCOL_IEEE_C37118, - ndpi_search_ieee_c37118, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IEEE-C37118", ndpi_struct, + ndpi_search_ieee_c37118, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_IEEE_C37118); } diff --git a/src/lib/protocols/imo.c b/src/lib/protocols/imo.c index 3807e5010..9b60e251f 100644 --- a/src/lib/protocols/imo.c +++ b/src/lib/protocols/imo.c @@ -61,21 +61,17 @@ static void ndpi_search_imo(struct ndpi_detection_module_struct *ndpi_struct, st ndpi_int_imo_add_connection(ndpi_struct, flow); } else { if(flow->num_processed_pkts > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); else flow->l4.udp.imo_last_one_byte_pkt = 0; } } -void init_imo_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("IMO", ndpi_struct, *id, - NDPI_PROTOCOL_IMO, - ndpi_search_imo, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_imo_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("IMO", ndpi_struct, + ndpi_search_imo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_IMO); } diff --git a/src/lib/protocols/ipp.c b/src/lib/protocols/ipp.c index 13d10bed2..86be5040e 100644 --- a/src/lib/protocols/ipp.c +++ b/src/lib/protocols/ipp.c @@ -2,7 +2,7 @@ * ipp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -52,18 +52,14 @@ static void ndpi_search_ipp(struct ndpi_detection_module_struct *ndpi_struct, st return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ipp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ipp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IPP", ndpi_struct, *id, - NDPI_PROTOCOL_IPP, - ndpi_search_ipp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IPP", ndpi_struct, + ndpi_search_ipp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_IPP); } diff --git a/src/lib/protocols/ipsec.c b/src/lib/protocols/ipsec.c index fdd08cb6f..ba6b5441c 100644 --- a/src/lib/protocols/ipsec.c +++ b/src/lib/protocols/ipsec.c @@ -39,7 +39,7 @@ static void ndpi_int_ipsec_add_connection(struct ndpi_detection_module_struct * switch (isakmp_type) { case ISAKMP_INVALID: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; case ISAKMP_MALFORMED: NDPI_LOG_INFO(ndpi_struct, "found malformed ISAKMP (UDP)\n"); @@ -138,7 +138,7 @@ static void ndpi_search_ipsec(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 28) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -148,7 +148,7 @@ static void ndpi_search_ipsec(struct ndpi_detection_module_struct *ndpi_struct, isakmp_offset = 4; if (packet->payload_packet_len < 32) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -157,7 +157,7 @@ static void ndpi_search_ipsec(struct ndpi_detection_module_struct *ndpi_struct, { if (packet->payload[isakmp_offset + 17] != 0x10 /* Major Version 1 */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { /* Version 1 is obsolete, but still used by some embedded devices. */ @@ -169,7 +169,7 @@ static void ndpi_search_ipsec(struct ndpi_detection_module_struct *ndpi_struct, if (ntohl(get_u_int32_t(packet->payload, isakmp_offset + 24)) != (u_int32_t)packet->payload_packet_len - isakmp_offset) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -183,17 +183,11 @@ static void ndpi_search_ipsec(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_ipsec_add_connection(ndpi_struct, flow, isakmp_type); } -void init_ipsec_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ipsec_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IPSec", ndpi_struct, *id, - NDPI_PROTOCOL_IPSEC, - ndpi_search_ipsec, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("IPSec", ndpi_struct, + ndpi_search_ipsec, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_IPSEC); } diff --git a/src/lib/protocols/iqiyi.c b/src/lib/protocols/iqiyi.c index 28600a4fc..d9acc2601 100644 --- a/src/lib/protocols/iqiyi.c +++ b/src/lib/protocols/iqiyi.c @@ -52,18 +52,13 @@ static void ndpi_search_iqiyi(struct ndpi_detection_module_struct *ndpi_struct, /* Add more iQiyi signatures */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_iqiyi_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_iqiyi_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("iQIYI", ndpi_struct, *id, - NDPI_PROTOCOL_IQIYI, - ndpi_search_iqiyi, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("iQIYI", ndpi_struct, + ndpi_search_iqiyi, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_IQIYI); } diff --git a/src/lib/protocols/irc.c b/src/lib/protocols/irc.c index 2ef11edb5..033aed9e6 100644 --- a/src/lib/protocols/irc.c +++ b/src/lib/protocols/irc.c @@ -2,7 +2,7 @@ * irc.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -99,8 +99,7 @@ static void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct NDPI_LOG_DBG(ndpi_struct, "search irc\n"); if((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && (flow->packet_counter > 10)) || (flow->packet_counter >= 10)) { - NDPI_LOG_DBG(ndpi_struct, "exclude irc, packet_counter too high0\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -225,16 +224,11 @@ static void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct } } -void init_irc_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_irc_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("IRC", ndpi_struct, *id, - NDPI_PROTOCOL_IRC, - ndpi_search_irc_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("IRC", ndpi_struct, + ndpi_search_irc_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_IRC); } diff --git a/src/lib/protocols/iso9506-1-mms.c b/src/lib/protocols/iso9506-1-mms.c index 970f49e73..9f44b4d31 100644 --- a/src/lib/protocols/iso9506-1-mms.c +++ b/src/lib/protocols/iso9506-1-mms.c @@ -68,18 +68,14 @@ static void ndpi_search_iso9506_1_mms(struct ndpi_detection_module_struct *ndpi_ } if (flow->packet_direction_counter[packet->packet_direction] > 2) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_iso9506_1_mms_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_iso9506_1_mms_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("ISO9506-1-MMS", ndpi_struct, *id, - NDPI_PROTOCOL_ISO9506_1_MMS, - ndpi_search_iso9506_1_mms, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("ISO9506-1-MMS", ndpi_struct, + ndpi_search_iso9506_1_mms, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ISO9506_1_MMS); } diff --git a/src/lib/protocols/jabber.c b/src/lib/protocols/jabber.c index 53ec251c5..864d2d57a 100644 --- a/src/lib/protocols/jabber.c +++ b/src/lib/protocols/jabber.c @@ -2,7 +2,7 @@ * jabber.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,9 +42,10 @@ static struct jabber_string jabber_strings[] = { static void ndpi_int_jabber_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + u_int32_t master, u_int32_t protocol, ndpi_confidence_t confidence) { - ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN, confidence); + ndpi_set_detected_protocol(ndpi_struct, flow, protocol, master, confidence); } static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, @@ -55,7 +56,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ for(i=0; jabber_strings[i].string != NULL; i++) { if(ndpi_strnstr((const char*)&packet->payload[x], jabber_strings[i].string, left) != NULL) { - ndpi_int_jabber_add_connection(ndpi_struct, flow, jabber_strings[i].ndpi_protocol, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, jabber_strings[i].ndpi_protocol, NDPI_CONFIDENCE_DPI); return; } } @@ -76,7 +77,7 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str /* Old style Jabber/XMPP SSL. */ if (flow->packet_counter > max_packets - 1) { - ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); return; } for (i = 0; i < NDPI_ARRAY_LENGTH(valid_patterns); ++i) @@ -86,7 +87,7 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -97,7 +98,7 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str ndpi_strnstr((const char *)&packet->payload[0], "xmlns='http://jabber.org/protocol/", packet->payload_packet_len) != NULL) { - ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); return; } @@ -106,14 +107,14 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str ndpi_strnstr((const char *)&packet->payload[0], "xmlns='http://jabber.org/protocol/commands'", packet->payload_packet_len) != NULL) { - ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); return; } if (packet->payload_packet_len == NDPI_STATICSTRING_LEN("</stream:stream>") && memcmp(packet->payload, "</stream:stream>", NDPI_STATICSTRING_LEN("</stream:stream>")) == 0) { - ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); return; } @@ -126,7 +127,7 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str || ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream=\"http://etherx.jabber.org/streams\"", start)) { /* Protocol family */ - ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_JABBER, NDPI_CONFIDENCE_DPI); /* search for subprotocols */ check_content_type_and_change_protocol(ndpi_struct, flow, 13); @@ -134,20 +135,16 @@ static void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_str return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_jabber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_jabber_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Jabber", ndpi_struct, *id, - NDPI_PROTOCOL_JABBER, - ndpi_search_jabber_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Jabber", ndpi_struct, + ndpi_search_jabber_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_JABBER); } diff --git a/src/lib/protocols/jrmi.c b/src/lib/protocols/jrmi.c index e5d9848dc..30c685a5b 100644 --- a/src/lib/protocols/jrmi.c +++ b/src/lib/protocols/jrmi.c @@ -49,18 +49,14 @@ static void ndpi_search_jrmi(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_jrmi_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("JRMI", ndpi_struct, *id, - NDPI_PROTOCOL_JRMI, - ndpi_search_jrmi, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_jrmi_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("JRMI", ndpi_struct, + ndpi_search_jrmi, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_JRMI); } diff --git a/src/lib/protocols/json-rpc.c b/src/lib/protocols/json-rpc.c index c29be2ef2..6a26ccccd 100644 --- a/src/lib/protocols/json-rpc.c +++ b/src/lib/protocols/json-rpc.c @@ -58,16 +58,13 @@ static void ndpi_search_json_rpc(struct ndpi_detection_module_struct *ndpi_struc return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_json_rpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_json_rpc_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("JSON-RPC", ndpi_struct, *id, - NDPI_PROTOCOL_JSON_RPC, - ndpi_search_json_rpc, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("JSON-RPC", ndpi_struct, + ndpi_search_json_rpc, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_JSON_RPC); } diff --git a/src/lib/protocols/kafka.c b/src/lib/protocols/kafka.c index abf0ae3ca..a50332721 100644 --- a/src/lib/protocols/kafka.c +++ b/src/lib/protocols/kafka.c @@ -52,7 +52,7 @@ static void ndpi_search_kafka(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 8 /* min. required packet length */ || ntohl(get_u_int32_t(packet->payload, 0)) != (uint32_t)(packet->payload_packet_len - 4)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -62,19 +62,19 @@ static void ndpi_search_kafka(struct ndpi_detection_module_struct *ndpi_struct, { if (packet->payload_packet_len < 14) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } const uint16_t client_id_len = ntohs(get_u_int16_t(packet->payload, 12)); if (client_id_len + 12 + 2 > packet->payload_packet_len) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (ndpi_is_printable_buffer(&packet->payload[14], client_id_len) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -82,16 +82,13 @@ static void ndpi_search_kafka(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_kafka_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_kafka_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Kafka", ndpi_struct, *id, - NDPI_PROTOCOL_APACHE_KAFKA, - ndpi_search_kafka, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Kafka", ndpi_struct, + ndpi_search_kafka, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_APACHE_KAFKA); } diff --git a/src/lib/protocols/kakaotalk_voice.c b/src/lib/protocols/kakaotalk_voice.c index 1913fe156..ead616012 100644 --- a/src/lib/protocols/kakaotalk_voice.c +++ b/src/lib/protocols/kakaotalk_voice.c @@ -61,19 +61,15 @@ static void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndp } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_kakaotalk_voice_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_kakaotalk_voice_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("KakaoTalk_Voice", ndpi_struct, *id, - NDPI_PROTOCOL_KAKAOTALK_VOICE, - ndpi_search_kakaotalk_voice, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("KakaoTalk_Voice", ndpi_struct, + ndpi_search_kakaotalk_voice, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_KAKAOTALK_VOICE); } diff --git a/src/lib/protocols/kcp.c b/src/lib/protocols/kcp.c index 906737179..0e01eaa2b 100644 --- a/src/lib/protocols/kcp.c +++ b/src/lib/protocols/kcp.c @@ -66,7 +66,7 @@ static void ndpi_search_kcp(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < sizeof(*kcp_header)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -78,30 +78,24 @@ static void ndpi_search_kcp(struct ndpi_detection_module_struct *ndpi_struct, case IKCP_CMD_WINS: break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } uint32_t const kcp_pdu_length = le32toh(kcp_header->length); if (kcp_pdu_length + sizeof(*kcp_header) != packet->payload_packet_len) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ndpi_int_kcp_add_connection(ndpi_struct, flow); } -void init_kcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_kcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("KCP", ndpi_struct, *id, - NDPI_PROTOCOL_KCP, - ndpi_search_kcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("KCP", ndpi_struct, + ndpi_search_kcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_KCP); } diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c index 7ff120982..bfae1e2ef 100644 --- a/src/lib/protocols/kerberos.c +++ b/src/lib/protocols/kerberos.c @@ -1,7 +1,7 @@ /* * kerberos.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -314,7 +314,7 @@ static void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struc u_int16_t original_payload_packet_len = 0; if((sport != KERBEROS_PORT) && (dport != KERBEROS_PORT)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -672,7 +672,7 @@ static void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_struct, @@ -697,14 +697,9 @@ static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_ return flow->extra_packets_func != NULL; } -void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Kerberos", ndpi_struct, *id, - NDPI_PROTOCOL_KERBEROS, - ndpi_search_kerberos, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Kerberos", ndpi_struct, + ndpi_search_kerberos, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_KERBEROS); } diff --git a/src/lib/protocols/kismet.c b/src/lib/protocols/kismet.c index 9c292de54..951906ff1 100644 --- a/src/lib/protocols/kismet.c +++ b/src/lib/protocols/kismet.c @@ -45,7 +45,7 @@ static void ndpi_search_kismet(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < NDPI_STATICSTRING_LEN("*KISMET: ")) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -55,19 +55,13 @@ static void ndpi_search_kismet(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_kismet_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_kismet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("kismet", ndpi_struct, *id, - NDPI_PROTOCOL_KISMET, - ndpi_search_kismet, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("kismet", ndpi_struct, + ndpi_search_kismet, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_KISMET); } diff --git a/src/lib/protocols/knxnet_ip.c b/src/lib/protocols/knxnet_ip.c index acab2e3df..99021bccb 100644 --- a/src/lib/protocols/knxnet_ip.c +++ b/src/lib/protocols/knxnet_ip.c @@ -115,17 +115,13 @@ static void ndpi_search_knxnet_ip(struct ndpi_detection_module_struct *ndpi_stru } not_knxnet_ip: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_knxnet_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_knxnet_ip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("KNXnet_IP", ndpi_struct, *id, - NDPI_PROTOCOL_KNXNET_IP, - ndpi_search_knxnet_ip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("KNXnet_IP", ndpi_struct, + ndpi_search_knxnet_ip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_KNXNET_IP); } diff --git a/src/lib/protocols/lagofast.c b/src/lib/protocols/lagofast.c new file mode 100644 index 000000000..c0f6d41c2 --- /dev/null +++ b/src/lib/protocols/lagofast.c @@ -0,0 +1,72 @@ +/* + * lagofast.c + * + * Copyright (C) 2011-25 - 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 + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_LAGOFAST + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_int_lagofast_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow) +{ + NDPI_LOG_INFO(ndpi_struct, "found LagoFast\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, + NDPI_PROTOCOL_LAGOFAST, + NDPI_PROTOCOL_UNKNOWN, + NDPI_CONFIDENCE_DPI); +} + +static void ndpi_search_lagofast(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search LagoFast\n"); + if (packet->payload_packet_len < 6) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + // LagoFast identifier + if (get_u_int32_t(packet->payload, 0) != htonl(0x006e5d03)) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + // Check encoded length + const uint16_t encoded_length = ntohs(get_u_int16_t(packet->payload, 4)); + if (packet->payload_packet_len != encoded_length + 6 /* identifier + length */) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + + ndpi_int_lagofast_add_connection(ndpi_struct, flow); +} + +void init_lagofast_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("LagoFast", ndpi_struct, + ndpi_search_lagofast, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_LAGOFAST); +} + diff --git a/src/lib/protocols/ldap.c b/src/lib/protocols/ldap.c index b4df469f9..4343c0321 100644 --- a/src/lib/protocols/ldap.c +++ b/src/lib/protocols/ldap.c @@ -2,7 +2,7 @@ * ldap.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -66,19 +66,15 @@ static void ndpi_search_ldap(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ldap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ldap_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("LDAP", ndpi_struct, *id, - NDPI_PROTOCOL_LDAP, - ndpi_search_ldap, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("LDAP", ndpi_struct, + ndpi_search_ldap, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_LDAP); } diff --git a/src/lib/protocols/ldp.c b/src/lib/protocols/ldp.c index 7d059b6f0..6a41310f9 100644 --- a/src/lib/protocols/ldp.c +++ b/src/lib/protocols/ldp.c @@ -111,17 +111,13 @@ static void ndpi_search_ldp(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ldp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ldp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("LDP", ndpi_struct, *id, - NDPI_PROTOCOL_LDP, - ndpi_search_ldp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("LDP", ndpi_struct, + ndpi_search_ldp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_LDP); } diff --git a/src/lib/protocols/line.c b/src/lib/protocols/line.c index 933693ed9..232d629e0 100644 --- a/src/lib/protocols/line.c +++ b/src/lib/protocols/line.c @@ -98,7 +98,7 @@ static void ndpi_search_line(struct ndpi_detection_module_struct *ndpi_struct, if(flow->l4.udp.line_base_cnt[0] != flow->l4.udp.line_base_cnt[1]) ndpi_int_line_add_connection(ndpi_struct, flow); else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; } @@ -106,19 +106,14 @@ static void ndpi_search_line(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_line_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_line_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("LineCall", ndpi_struct, *id, - NDPI_PROTOCOL_LINE_CALL, - ndpi_search_line, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("LineCall", ndpi_struct, + ndpi_search_line, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_LINE_CALL); } diff --git a/src/lib/protocols/lisp.c b/src/lib/protocols/lisp.c index b66a2e52d..bfec1ca5e 100644 --- a/src/lib/protocols/lisp.c +++ b/src/lib/protocols/lisp.c @@ -69,7 +69,7 @@ static void ndpi_check_lisp(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_lisp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -80,14 +80,11 @@ static void ndpi_search_lisp(struct ndpi_detection_module_struct *ndpi_struct, s } -void init_lisp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_lisp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("LISP", ndpi_struct, *id, - NDPI_PROTOCOL_LISP, - ndpi_search_lisp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("LISP", ndpi_struct, + ndpi_search_lisp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_LISP); } diff --git a/src/lib/protocols/lol_wild_rift.c b/src/lib/protocols/lol_wild_rift.c index 84b91a9b5..d0a5afa6c 100644 --- a/src/lib/protocols/lol_wild_rift.c +++ b/src/lib/protocols/lol_wild_rift.c @@ -69,18 +69,13 @@ static void ndpi_search_lolwildrift(struct ndpi_detection_module_struct *ndpi_st return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_lolwildrift_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_lolwildrift_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("LoLWildRift", ndpi_struct, *id, - NDPI_PROTOCOL_LOLWILDRIFT, - ndpi_search_lolwildrift, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("LoLWildRift", ndpi_struct, + ndpi_search_lolwildrift, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_LOLWILDRIFT); } diff --git a/src/lib/protocols/lotus_notes.c b/src/lib/protocols/lotus_notes.c deleted file mode 100644 index bb2ca18ad..000000000 --- a/src/lib/protocols/lotus_notes.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * lotus_notes.c - * - * Copyright (C) 2012-22 - 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 - * 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_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_LOTUS_NOTES - -#include "ndpi_api.h" -#include "ndpi_private.h" - -/* ************************************ */ - -static void ndpi_check_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - u_int32_t payload_len = packet->payload_packet_len; - - flow->l4.tcp.lotus_notes_packet_id++; - - if((flow->l4.tcp.lotus_notes_packet_id == 1) && - ndpi_seen_flow_beginning(flow)) { - if(payload_len > 16) { - char lotus_notes_header[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x02, 0x0F }; - - if(memcmp(&packet->payload[6], lotus_notes_header, sizeof(lotus_notes_header)) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found lotus_notes\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_LOTUS_NOTES, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - } - return; - } - - } else if(flow->l4.tcp.lotus_notes_packet_id <= 3) return; - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - -static void ndpi_search_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - NDPI_LOG_DBG(ndpi_struct, "search lotus_notes\n"); - - ndpi_check_lotus_notes(ndpi_struct, flow); -} - - -void init_lotus_notes_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("LotusNotes", ndpi_struct, *id, - NDPI_PROTOCOL_LOTUS_NOTES, - ndpi_search_lotus_notes, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - diff --git a/src/lib/protocols/lustre.c b/src/lib/protocols/lustre.c index 6965fe51a..dd4997ca1 100644 --- a/src/lib/protocols/lustre.c +++ b/src/lib/protocols/lustre.c @@ -74,16 +74,13 @@ static void ndpi_search_lustre(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_lustre_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_lustre_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Lustre", ndpi_struct, *id, - NDPI_PROTOCOL_LUSTRE, - ndpi_search_lustre, - NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION /* Ipv4 only; Lustre doesn't support IPv6 */, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Lustre", ndpi_struct, + ndpi_search_lustre, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, /* Ipv4 only; Lustre doesn't support IPv6 */ + 1, NDPI_PROTOCOL_LUSTRE); } diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c index 2c7095942..3bb858f9c 100644 --- a/src/lib/protocols/mail_imap.c +++ b/src/lib/protocols/mail_imap.c @@ -29,6 +29,15 @@ #include "ndpi_api.h" #include "ndpi_private.h" +/* Safely increments IMAP stage counter preventing 3-bit mail_imap_stage overflow. + * Even though current tests don't trigger overflow, better safe than sorry. */ +#define SAFE_INC_IMAP_STAGE(flow) \ + do { \ + if ((flow)->l4.tcp.mail_imap_stage < 7) { \ + (flow)->l4.tcp.mail_imap_stage += 1; \ + } \ + } while(0) + /* #define IMAP_DEBUG 1*/ static void ndpi_int_mail_imap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, @@ -53,11 +62,8 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ 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 - if(packet->payload_packet_len == 6 && ((packet->payload[0] == 'D' || packet->payload[0] == 'd') - && (packet->payload[1] == 'O' || packet->payload[1] == 'o') - && (packet->payload[2] == 'N' || packet->payload[2] == 'n') - && (packet->payload[3] == 'E' || packet->payload[3] == 'e'))) { - flow->l4.tcp.mail_imap_stage += 1; + if(packet->payload_packet_len == 6 && ndpi_memcasecmp(packet->payload, "DONE", 4) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } else { if(flow->l4.tcp.mail_imap_stage < 5) { @@ -102,10 +108,8 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ } if((command_start + 3) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'O' || packet->payload[command_start] == 'o') - && (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(ndpi_memcasecmp(packet->payload + command_start, "OK ", 3) == 0) { + SAFE_INC_IMAP_STAGE(flow); if(flow->l4.tcp.mail_imap_starttls == 1) { NDPI_LOG_DBG2(ndpi_struct, "starttls detected\n"); ndpi_int_mail_imap_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAPS); @@ -118,62 +122,37 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ } } 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') - && (packet->payload[command_start + 2] == 'D' || packet->payload[command_start + 2] == 'd')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "UID", 3) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n') - && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o') - && packet->payload[command_start + 2] == ' ') { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "NO ", 3) == 0) { + SAFE_INC_IMAP_STAGE(flow); if(flow->l4.tcp.mail_imap_starttls == 1) flow->l4.tcp.mail_imap_starttls = 0; saw_command = 1; } } if((command_start + 10) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c') - && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a') - && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p') - && (packet->payload[command_start + 3] == 'A' || packet->payload[command_start + 3] == 'a') - && (packet->payload[command_start + 4] == 'B' || packet->payload[command_start + 4] == 'b') - && (packet->payload[command_start + 5] == 'I' || packet->payload[command_start + 5] == 'i') - && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l') - && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i') - && (packet->payload[command_start + 8] == 'T' || packet->payload[command_start + 8] == 't') - && (packet->payload[command_start + 9] == 'Y' || packet->payload[command_start + 9] == 'y')) { - flow->l4.tcp.mail_imap_stage += 1; + if(ndpi_memcasecmp(packet->payload + command_start, "CAPABILITY", 10) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } } if((command_start + 8) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') - && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't') - && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a') - && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r') - && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't') - && (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; + if(ndpi_memcasecmp(packet->payload + command_start, "STARTTLS", 8) == 0) { + SAFE_INC_IMAP_STAGE(flow); flow->l4.tcp.mail_imap_starttls = 1; saw_command = 1; } } if((command_start + 5) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') - && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o') - && (packet->payload[command_start + 2] == 'G' || packet->payload[command_start + 2] == 'g') - && (packet->payload[command_start + 3] == 'I' || packet->payload[command_start + 3] == 'i') - && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')) { + if(ndpi_memcasecmp(packet->payload + command_start, "LOGIN", 5) == 0) { /* xxxx LOGIN "username" "password" xxxx LOGIN username password */ char str[256], *user, *saveptr; u_int len = ndpi_min(packet->payload_packet_len - (command_start + 5), (int)sizeof(str) - 1); - strncpy(str, (const char*)packet->payload + command_start + 5, len); - str[len] = '\0'; + ndpi_strlcpy(str, (const char*)packet->payload + command_start + 5, sizeof(str), len); user = strtok_r(str, " \"\r\n", &saveptr); if(user) { @@ -195,52 +174,25 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ } } - flow->l4.tcp.mail_imap_stage += 1; + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f') - && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e') - && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't') - && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c') - && (packet->payload[command_start + 4] == 'H' || packet->payload[command_start + 4] == 'h')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "FETCH", 5) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f') - && (packet->payload[command_start + 1] == 'L' || packet->payload[command_start + 1] == 'l') - && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a') - && (packet->payload[command_start + 3] == 'G' || packet->payload[command_start + 3] == 'g') - && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "FLAGS", 5) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c') - && (packet->payload[command_start + 1] == 'H' || packet->payload[command_start + 1] == 'h') - && (packet->payload[command_start + 2] == 'E' || packet->payload[command_start + 2] == 'e') - && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c') - && (packet->payload[command_start + 4] == 'K' || packet->payload[command_start + 4] == 'k')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "CHECK", 5) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') - && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't') - && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o') - && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r') - && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "STORE", 5) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } } if((command_start + 12) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a') - && (packet->payload[command_start + 1] == 'U' || packet->payload[command_start + 1] == 'u') - && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't') - && (packet->payload[command_start + 3] == 'H' || packet->payload[command_start + 3] == 'h') - && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e') - && (packet->payload[command_start + 5] == 'N' || packet->payload[command_start + 5] == 'n') - && (packet->payload[command_start + 6] == 'T' || packet->payload[command_start + 6] == 't') - && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i') - && (packet->payload[command_start + 8] == 'C' || packet->payload[command_start + 8] == 'c') - && (packet->payload[command_start + 9] == 'A' || packet->payload[command_start + 9] == 'a') - && (packet->payload[command_start + 10] == 'T' || packet->payload[command_start + 10] == 't') - && (packet->payload[command_start + 11] == 'E' || packet->payload[command_start + 11] == 'e')) { - flow->l4.tcp.mail_imap_stage += 1; + if(ndpi_memcasecmp(packet->payload + command_start, "AUTHENTICATE", 12) == 0) { + SAFE_INC_IMAP_STAGE(flow); /* Authenticate phase may have multiple messages. Ignore them since they are somehow encrypted anyway. */ ndpi_int_mail_imap_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAPS); @@ -248,70 +200,35 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ } } if((command_start + 9) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n') - && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a') - && (packet->payload[command_start + 2] == 'M' || packet->payload[command_start + 2] == 'm') - && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') - && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's') - && (packet->payload[command_start + 5] == 'P' || packet->payload[command_start + 5] == 'p') - && (packet->payload[command_start + 6] == 'A' || packet->payload[command_start + 6] == 'a') - && (packet->payload[command_start + 7] == 'C' || packet->payload[command_start + 7] == 'c') - && (packet->payload[command_start + 8] == 'E' || packet->payload[command_start + 8] == 'e')) { - flow->l4.tcp.mail_imap_stage += 1; + if(ndpi_memcasecmp(packet->payload + command_start, "NAMESPACE", 9) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } } if((command_start + 4) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') - && (packet->payload[command_start + 1] == 'S' || packet->payload[command_start + 1] == 's') - && (packet->payload[command_start + 2] == 'U' || packet->payload[command_start + 2] == 'u') - && (packet->payload[command_start + 3] == 'B' || packet->payload[command_start + 3] == 'b')) { - flow->l4.tcp.mail_imap_stage += 1; + if(ndpi_memcasecmp(packet->payload + command_start, "LSUB", 4) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') - && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i') - && (packet->payload[command_start + 2] == 'S' || packet->payload[command_start + 2] == 's') - && (packet->payload[command_start + 3] == 'T' || packet->payload[command_start + 3] == 't')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "LIST", 4) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n') - && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o') - && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o') - && (packet->payload[command_start + 3] == 'P' || packet->payload[command_start + 3] == 'p')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "NOOP", 4) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'I' || packet->payload[command_start] == 'i') - && (packet->payload[command_start + 1] == 'D' || packet->payload[command_start + 1] == 'd') - && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l') - && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "IDLE", 4) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } } if((command_start + 6) < packet->payload_packet_len) { - if((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') - && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e') - && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l') - && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') - && (packet->payload[command_start + 4] == 'C' || packet->payload[command_start + 4] == 'c') - && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')) { - flow->l4.tcp.mail_imap_stage += 1; + if(ndpi_memcasecmp(packet->payload + command_start, "SELECT", 6) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'E' || packet->payload[command_start] == 'e') - && (packet->payload[command_start + 1] == 'X' || packet->payload[command_start + 1] == 'x') - && (packet->payload[command_start + 2] == 'I' || packet->payload[command_start + 2] == 'i') - && (packet->payload[command_start + 3] == 'S' || packet->payload[command_start + 3] == 's') - && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't') - && (packet->payload[command_start + 5] == 'S' || packet->payload[command_start + 5] == 's')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "EXISTS", 6) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; - } else if((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a') - && (packet->payload[command_start + 1] == 'P' || packet->payload[command_start + 1] == 'p') - && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p') - && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') - && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n') - && (packet->payload[command_start + 5] == 'D' || packet->payload[command_start + 5] == 'd')) { - flow->l4.tcp.mail_imap_stage += 1; + } else if(ndpi_memcasecmp(packet->payload + command_start, "APPEND", 6) == 0) { + SAFE_INC_IMAP_STAGE(flow); saw_command = 1; } } @@ -352,18 +269,14 @@ static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_ return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mail_imap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_mail_imap_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MAIL_IMAP", ndpi_struct, *id, - NDPI_PROTOCOL_MAIL_IMAP, - ndpi_search_mail_imap_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MAIL_IMAP", ndpi_struct, + ndpi_search_mail_imap_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MAIL_IMAP); } diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c index b51ad629c..2ba8b8d5e 100644 --- a/src/lib/protocols/mail_pop.c +++ b/src/lib/protocols/mail_pop.c @@ -1,7 +1,7 @@ /* * mail_pop.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -63,22 +63,13 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod struct ndpi_packet_struct *packet = &ndpi_struct->packet; if(packet->payload_packet_len > 4) { - if((packet->payload[0] == 'A' || packet->payload[0] == 'a') - && (packet->payload[1] == 'U' || packet->payload[1] == 'u') - && (packet->payload[2] == 'T' || packet->payload[2] == 't') - && (packet->payload[3] == 'H' || packet->payload[3] == 'h')) { + if(ndpi_memcasecmp(packet->payload, "AUTH", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_AUTH; return 1; - } else if((packet->payload[0] == 'A' || packet->payload[0] == 'a') - && (packet->payload[1] == 'P' || packet->payload[1] == 'p') - && (packet->payload[2] == 'O' || packet->payload[2] == 'o') - && (packet->payload[3] == 'P' || packet->payload[3] == 'p')) { + } else if(ndpi_memcasecmp(packet->payload, "APOP", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_APOP; return 1; - } else if((packet->payload[0] == 'U' || packet->payload[0] == 'u') - && (packet->payload[1] == 'S' || packet->payload[1] == 's') - && (packet->payload[2] == 'E' || packet->payload[2] == 'e') - && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) { + } else if(ndpi_memcasecmp(packet->payload, "USER", 4) == 0) { char buf[64]; ndpi_user_pwd_payload_copy((u_int8_t*)flow->l4.tcp.ftp_imap_pop_smtp.username, @@ -91,10 +82,7 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod flow->l4.tcp.pop_command_bitmask |= POP_BIT_USER; return 1; - } else if((packet->payload[0] == 'P' || packet->payload[0] == 'p') - && (packet->payload[1] == 'A' || packet->payload[1] == 'a') - && (packet->payload[2] == 'S' || packet->payload[2] == 's') - && (packet->payload[3] == 'S' || packet->payload[3] == 's')) { + } else if(ndpi_memcasecmp(packet->payload, "PASS", 4) == 0) { ndpi_user_pwd_payload_copy((u_int8_t*)flow->l4.tcp.ftp_imap_pop_smtp.password, sizeof(flow->l4.tcp.ftp_imap_pop_smtp.password), 5, packet->payload, packet->payload_packet_len); @@ -102,46 +90,25 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password"); flow->l4.tcp.pop_command_bitmask |= POP_BIT_PASS; return 1; - } else if((packet->payload[0] == 'C' || packet->payload[0] == 'c') - && (packet->payload[1] == 'A' || packet->payload[1] == 'a') - && (packet->payload[2] == 'P' || packet->payload[2] == 'p') - && (packet->payload[3] == 'A' || packet->payload[3] == 'a')) { + } else if(ndpi_memcasecmp(packet->payload, "CAPA", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_CAPA; return 1; - } else if((packet->payload[0] == 'L' || packet->payload[0] == 'l') - && (packet->payload[1] == 'I' || packet->payload[1] == 'i') - && (packet->payload[2] == 'S' || packet->payload[2] == 's') - && (packet->payload[3] == 'T' || packet->payload[3] == 't')) { + } else if(ndpi_memcasecmp(packet->payload, "LIST", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_LIST; return 1; - } else if((packet->payload[0] == 'S' || packet->payload[0] == 's') - && (packet->payload[1] == 'T' || packet->payload[1] == 't') - && (packet->payload[2] == 'A' || packet->payload[2] == 'a') - && (packet->payload[3] == 'T' || packet->payload[3] == 't')) { + } else if(ndpi_memcasecmp(packet->payload, "STAT", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_STAT; return 1; - } else if((packet->payload[0] == 'U' || packet->payload[0] == 'u') - && (packet->payload[1] == 'I' || packet->payload[1] == 'i') - && (packet->payload[2] == 'D' || packet->payload[2] == 'd') - && (packet->payload[3] == 'L' || packet->payload[3] == 'l')) { + } else if(ndpi_memcasecmp(packet->payload, "UIDL", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_UIDL; return 1; - } else if((packet->payload[0] == 'R' || packet->payload[0] == 'r') - && (packet->payload[1] == 'E' || packet->payload[1] == 'e') - && (packet->payload[2] == 'T' || packet->payload[2] == 't') - && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) { + } else if(ndpi_memcasecmp(packet->payload, "RETR", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_RETR; return 1; - } else if((packet->payload[0] == 'D' || packet->payload[0] == 'd') - && (packet->payload[1] == 'E' || packet->payload[1] == 'e') - && (packet->payload[2] == 'L' || packet->payload[2] == 'l') - && (packet->payload[3] == 'E' || packet->payload[3] == 'e')) { + } else if(ndpi_memcasecmp(packet->payload, "DELE", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_DELE; return 1; - } else if((packet->payload[0] == 'S' || packet->payload[0] == 's') - && (packet->payload[1] == 'T' || packet->payload[1] == 't') - && (packet->payload[2] == 'L' || packet->payload[2] == 'l') - && (packet->payload[3] == 'S' || packet->payload[3] == 's')) { + } else if(ndpi_memcasecmp(packet->payload, "STLS", 4) == 0) { flow->l4.tcp.pop_command_bitmask |= POP_BIT_STLS; flow->l4.tcp.mail_imap_starttls = 1; return 1; @@ -162,12 +129,9 @@ static void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct NDPI_LOG_DBG(ndpi_struct, "search mail_pop\n"); if((packet->payload_packet_len > 3 - && (packet->payload[0] == '+' && (packet->payload[1] == 'O' || packet->payload[1] == 'o') - && (packet->payload[2] == 'K' || packet->payload[2] == 'k'))) + && ndpi_memcasecmp(packet->payload, "+OK", 3) == 0) || (packet->payload_packet_len > 4 - && (packet->payload[0] == '-' && (packet->payload[1] == 'E' || packet->payload[1] == 'e') - && (packet->payload[2] == 'R' || packet->payload[2] == 'r') - && (packet->payload[3] == 'R' || packet->payload[3] == 'r')))) { + && ndpi_memcasecmp(packet->payload, "-ERR", 4) == 0)) { // +OK or -ERR seen flow->l4.tcp.mail_pop_stage += 1; if(packet->payload[0] == '+' && flow->l4.tcp.mail_imap_starttls == 1) { @@ -231,7 +195,7 @@ static void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } @@ -266,14 +230,9 @@ static void popInitExtraPacketProcessing(struct ndpi_flow_struct *flow) { /* **************************************** */ -void init_mail_pop_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("MAIL_POP", ndpi_struct, *id, - NDPI_PROTOCOL_MAIL_POP, - ndpi_search_mail_pop_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_mail_pop_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("MAIL_POP", ndpi_struct, + ndpi_search_mail_pop_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MAIL_POP); } diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c index 6e4629ac9..9a968f622 100644 --- a/src/lib/protocols/mail_smtp.c +++ b/src/lib/protocols/mail_smtp.c @@ -1,7 +1,7 @@ /* * mail_smtp.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -179,38 +179,21 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ // expected client requests if(packet->line[a].len >= 5) { - if((((packet->line[a].ptr[0] == 'H' || packet->line[a].ptr[0] == 'h') - && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e')) - || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e') - && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h'))) - && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l') - && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o') - && packet->line[a].ptr[4] == ' ') { + if(ndpi_memcasecmp(packet->line[a].ptr, "HELO ", 5) == 0 || + ndpi_memcasecmp(packet->line[a].ptr, "EHLO ", 5) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO; flow->l4.tcp.ftp_imap_pop_smtp.auth_found = 0; - } else if((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm') - && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') - && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i') - && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l') - && packet->line[a].ptr[4] == ' ') { + } else if(ndpi_memcasecmp(packet->line[a].ptr, "MAIL ", 5) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL; flow->l4.tcp.ftp_imap_pop_smtp.auth_found = 0; /* We shouldn't be here if there are credentials */ flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 1; - } else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') - && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c') - && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p') - && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't') - && packet->line[a].ptr[4] == ' ') { + } else if(ndpi_memcasecmp(packet->line[a].ptr, "RCPT ", 5) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT; flow->l4.tcp.ftp_imap_pop_smtp.auth_found = 0; /* We shouldn't be here if there are credentials */ flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 1; - } else if((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a') - && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u') - && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') - && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h') - && packet->line[a].ptr[4] == ' ') { + } else if(ndpi_memcasecmp(packet->line[a].ptr, "AUTH ", 5) == 0) { #ifdef SMTP_DEBUG printf("%s() AUTH [%.*s]\n", __FUNCTION__, packet->line[a].len, packet->line[a].ptr); #endif @@ -292,7 +275,7 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 1; } else { flow->host_server_name[0] = '\0'; - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -301,14 +284,7 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ } if(packet->line[a].len >= 8) { - if((packet->line[a].ptr[0] == 'S' || packet->line[a].ptr[0] == 's') - && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't') - && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a') - && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r') - && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[4] == 't') - && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't') - && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l') - && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) { + if(ndpi_memcasecmp(packet->line[a].ptr, "STARTTLS", 8) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS; flow->l4.tcp.ftp_imap_pop_smtp.auth_tls = 1; flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 0; @@ -316,20 +292,7 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ } if(packet->line[a].len >= 14) { - if((packet->line[a].ptr[0] == 'X' || packet->line[a].ptr[0] == 'x') - && (packet->line[a].ptr[1] == '-' || packet->line[a].ptr[1] == '-') - && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a') - && (packet->line[a].ptr[3] == 'N' || packet->line[a].ptr[3] == 'n') - && (packet->line[a].ptr[4] == 'O' || packet->line[a].ptr[4] == 'o') - && (packet->line[a].ptr[5] == 'N' || packet->line[a].ptr[5] == 'n') - && (packet->line[a].ptr[6] == 'Y' || packet->line[a].ptr[6] == 'y') - && (packet->line[a].ptr[7] == 'M' || packet->line[a].ptr[6] == 'm') - && (packet->line[a].ptr[8] == 'O' || packet->line[a].ptr[6] == 'o') - && (packet->line[a].ptr[9] == 'U' || packet->line[a].ptr[6] == 'u') - && (packet->line[a].ptr[10] == 'S' || packet->line[a].ptr[6] == 's') - && (packet->line[a].ptr[11] == 'T' || packet->line[a].ptr[6] == 't') - && (packet->line[a].ptr[12] == 'L' || packet->line[a].ptr[6] == 'l') - && (packet->line[a].ptr[13] == 'S' || packet->line[a].ptr[7] == 's')) { + if(ndpi_memcasecmp(packet->line[a].ptr, "X-AnonymousTLS", 14) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS; flow->l4.tcp.ftp_imap_pop_smtp.auth_tls = 1; flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 0; @@ -337,20 +300,11 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ } if(packet->line[a].len >= 4) { - if((packet->line[a].ptr[0] == 'D' || packet->line[a].ptr[0] == 'd') - && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') - && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') - && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) { + if(ndpi_memcasecmp(packet->line[a].ptr, "DATA", 4) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_DATA; - } else if((packet->line[a].ptr[0] == 'N' || packet->line[a].ptr[0] == 'n') - && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o') - && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o') - && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) { + } else if(ndpi_memcasecmp(packet->line[a].ptr, "NOOP", 4) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_NOOP; - } else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') - && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's') - && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e') - && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) { + } else if(ndpi_memcasecmp(packet->line[a].ptr, "RSET", 4) == 0) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RSET; } } @@ -397,7 +351,7 @@ static void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_ } if((!flow->extra_packets_func) || (flow->packet_counter > 12)) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* **************************************** */ @@ -470,14 +424,9 @@ static void smtpInitExtraPacketProcessing(struct ndpi_flow_struct *flow) { /* **************************************** */ -void init_mail_smtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("MAIL_SMTP", ndpi_struct, *id, - NDPI_PROTOCOL_MAIL_SMTP, - ndpi_search_mail_smtp_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_mail_smtp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("MAIL_SMTP", ndpi_struct, + ndpi_search_mail_smtp_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MAIL_SMTP); } diff --git a/src/lib/protocols/maplestory.c b/src/lib/protocols/maplestory.c deleted file mode 100644 index aa5370082..000000000 --- a/src/lib/protocols/maplestory.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * maplestory.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MAPLESTORY - -#include "ndpi_api.h" -#include "ndpi_private.h" - -static void ndpi_int_maplestory_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAPLESTORY, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - - -static void ndpi_search_maplestory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search maplestory\n"); - - if (packet->payload_packet_len == 16 - && (ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003a00 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003b00 - || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e004200) - && ntohs(get_u_int16_t(packet->payload, 4)) == 0x0100 && (packet->payload[6] == 0x32 || packet->payload[6] == 0x33)) { - NDPI_LOG_INFO(ndpi_struct, "found maplestory\n"); - ndpi_int_maplestory_add_connection(ndpi_struct, flow); - return; - } - - if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple") - && memcmp(packet->payload, "GET /maple", NDPI_STATICSTRING_LEN("GET /maple")) == 0) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - /* Maplestory update */ - if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple/patch") - && packet->payload[NDPI_STATICSTRING_LEN("GET /maple")] == '/') { - if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL - && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Patcher") - && packet->host_line.len > NDPI_STATICSTRING_LEN("patch.") - && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple/")], "patch", - NDPI_STATICSTRING_LEN("patch")) == 0 - && memcmp(packet->user_agent_line.ptr, "Patcher", NDPI_STATICSTRING_LEN("Patcher")) == 0 - && memcmp(packet->host_line.ptr, "patch.", NDPI_STATICSTRING_LEN("patch.")) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found maplestory update\n"); - ndpi_int_maplestory_add_connection(ndpi_struct, flow); - return; - } - } else if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("AspINet") - && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple")], "story/", - NDPI_STATICSTRING_LEN("story/")) == 0 - && memcmp(packet->user_agent_line.ptr, "AspINet", NDPI_STATICSTRING_LEN("AspINet")) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found maplestory update\n"); - ndpi_int_maplestory_add_connection(ndpi_struct, flow); - return; - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - -} - - -void init_maplestory_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("MapleStory", ndpi_struct, *id, - NDPI_PROTOCOL_MAPLESTORY, - ndpi_search_maplestory, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} diff --git a/src/lib/protocols/megaco.c b/src/lib/protocols/megaco.c index 98d2d8e97..98cb86046 100644 --- a/src/lib/protocols/megaco.c +++ b/src/lib/protocols/megaco.c @@ -47,18 +47,14 @@ static void ndpi_search_megaco(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_megaco_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_megaco_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Megaco", ndpi_struct, *id, - NDPI_PROTOCOL_MEGACO, - ndpi_search_megaco, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Megaco", ndpi_struct, + ndpi_search_megaco, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MEGACO); } diff --git a/src/lib/protocols/melsec.c b/src/lib/protocols/melsec.c new file mode 100644 index 000000000..f12d6ea71 --- /dev/null +++ b/src/lib/protocols/melsec.c @@ -0,0 +1,63 @@ +/* + * melsec.c + * + * MELSEC Communication Protocol + * + * Copyright (C) 2025 - ntop.org + * Copyright (C) 2025 - V.G <v.gavrilov@securitycode.ru> + * + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MELSEC + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_search_melsec(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search MELSEC\n"); + + if (packet->payload_packet_len > 40 && + (packet->payload[0] == 0x57 || packet->payload[0] == 0xD7)) + { + u_int16_t melsec_payload_len = packet->payload_packet_len - 21; + if (le16toh(get_u_int16_t(packet->payload, 19)) == melsec_payload_len && + ntohl(get_u_int32_t(packet->payload, 3)) == 0x00001111) + { + NDPI_LOG_INFO(ndpi_struct, "found MELSEC\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MELSEC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + } + } + + if (flow->packet_counter > 2) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + } +} + +void init_melsec_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("MELSEC", ndpi_struct, + ndpi_search_melsec, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MELSEC); +} diff --git a/src/lib/protocols/memcached.c b/src/lib/protocols/memcached.c index 0210a028a..9fc477bae 100644 --- a/src/lib/protocols/memcached.c +++ b/src/lib/protocols/memcached.c @@ -2,7 +2,7 @@ * memcached.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2018 - eGloo Incorporated * * This file is part of nDPI, an open source deep packet inspection @@ -112,21 +112,21 @@ static void ndpi_search_memcached(struct ndpi_detection_module_struct *ndpi_stru if (packet->tcp != NULL) { if (packet->payload_packet_len < MEMCACHED_MIN_LEN) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } matches = &flow->l4.tcp.memcached_matches; } - else if (packet->udp != NULL) { + else { if (packet->payload_packet_len < MEMCACHED_MIN_UDP_LEN) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if ((offset[4] == 0x00 && offset[5] == 0x00) || offset[6] != 0x00 || offset[7] != 0x00) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -170,20 +170,13 @@ static void ndpi_search_memcached(struct ndpi_detection_module_struct *ndpi_stru if (*matches >= MEMCACHED_MIN_MATCH) ndpi_int_memcached_add_connection(ndpi_struct, flow); else if(flow->packet_counter > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_memcached_dissector( - struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_memcached_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MEMCACHED", - ndpi_struct, *id, - NDPI_PROTOCOL_MEMCACHED, - ndpi_search_memcached, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MEMCACHED", ndpi_struct, + ndpi_search_memcached, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MEMCACHED); } diff --git a/src/lib/protocols/merakicloud.c b/src/lib/protocols/merakicloud.c index 5a0f0991f..c3b7c7a73 100644 --- a/src/lib/protocols/merakicloud.c +++ b/src/lib/protocols/merakicloud.c @@ -1,7 +1,7 @@ /* * merakicloud.c * - * Copyright (C) 2011-23 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -46,18 +46,13 @@ static void ndpi_search_merakicloud(struct ndpi_detection_module_struct *ndpi_st ndpi_int_merakicloud_add_connection(ndpi_struct, flow); return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_merakicloud_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_merakicloud_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MerakiCloud", ndpi_struct, *id, - NDPI_PROTOCOL_MERAKI_CLOUD, - ndpi_search_merakicloud, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MerakiCloud", ndpi_struct, + ndpi_search_merakicloud, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MERAKI_CLOUD); } diff --git a/src/lib/protocols/mgcp.c b/src/lib/protocols/mgcp.c index f48001ddc..7ae291ff3 100644 --- a/src/lib/protocols/mgcp.c +++ b/src/lib/protocols/mgcp.c @@ -97,19 +97,15 @@ static void ndpi_search_mgcp(struct ndpi_detection_module_struct *ndpi_struct, s } } while(0); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mgcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_mgcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MGCP", ndpi_struct, *id, - NDPI_PROTOCOL_MGCP, - ndpi_search_mgcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MGCP", ndpi_struct, + ndpi_search_mgcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MGCP); } diff --git a/src/lib/protocols/mikrotik.c b/src/lib/protocols/mikrotik.c index 83556bcbe..506bbc056 100644 --- a/src/lib/protocols/mikrotik.c +++ b/src/lib/protocols/mikrotik.c @@ -40,7 +40,7 @@ static void ndpi_search_mikrotik(struct ndpi_detection_module_struct *ndpi_struc u_int16_t offset; if (packet->payload_packet_len < 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { offset = 4; @@ -103,18 +103,14 @@ static void ndpi_search_mikrotik(struct ndpi_detection_module_struct *ndpi_struc NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ********************************* */ -void init_mikrotik_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("MIKROTIK", ndpi_struct, - *id, NDPI_PROTOCOL_MIKROTIK, ndpi_search_mikrotik, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_mikrotik_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("MIKROTIK", ndpi_struct, + ndpi_search_mikrotik, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MIKROTIK); } diff --git a/src/lib/protocols/mining.c b/src/lib/protocols/mining.c index 22d215927..aecad9951 100644 --- a/src/lib/protocols/mining.c +++ b/src/lib/protocols/mining.c @@ -58,7 +58,7 @@ static void ndpi_search_mining(struct ndpi_detection_module_struct *ndpi_struct, /* Quick test: we are looking for only Json format */ if(packet->payload[0] != '{') { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -89,21 +89,16 @@ static void ndpi_search_mining(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************************** */ -void init_mining_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_mining_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Mining", ndpi_struct, *id, - NDPI_PROTOCOL_MINING, - ndpi_search_mining, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Mining", ndpi_struct, + ndpi_search_mining, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MINING); } diff --git a/src/lib/protocols/modbus.c b/src/lib/protocols/modbus.c index d0b6bd593..e86fdf43c 100644 --- a/src/lib/protocols/modbus.c +++ b/src/lib/protocols/modbus.c @@ -61,20 +61,16 @@ static void ndpi_search_modbus_tcp(struct ndpi_detection_module_struct *ndpi_str } } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_modbus_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - - ndpi_set_bitmask_protocol_detection("Modbus", ndpi_struct, *id, - NDPI_PROTOCOL_MODBUS, - ndpi_search_modbus_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_modbus_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + + register_dissector("Modbus", ndpi_struct, + ndpi_search_modbus_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MODBUS); } diff --git a/src/lib/protocols/monero.c b/src/lib/protocols/monero.c index ef36dabd5..eb2583b7b 100644 --- a/src/lib/protocols/monero.c +++ b/src/lib/protocols/monero.c @@ -55,7 +55,7 @@ static void ndpi_search_monero(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -65,18 +65,13 @@ static void ndpi_search_monero(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_monero_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_monero_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Monero", ndpi_struct, *id, - NDPI_PROTOCOL_MONERO, - ndpi_search_monero, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Monero", ndpi_struct, + ndpi_search_monero, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MONERO); } diff --git a/src/lib/protocols/mongodb.c b/src/lib/protocols/mongodb.c index 38cac1622..12e1fcc4b 100644 --- a/src/lib/protocols/mongodb.c +++ b/src/lib/protocols/mongodb.c @@ -68,7 +68,7 @@ static void ndpi_check_mongodb(struct ndpi_detection_module_struct *ndpi_struct, uint32_t responseFlags; if (packet->payload_packet_len <= sizeof(mongodb_hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -81,7 +81,7 @@ static void ndpi_check_mongodb(struct ndpi_detection_module_struct *ndpi_struct, || (le32toh(mongodb_hdr.message_length) > 1000000) /* Used to avoid false positives */ ) { NDPI_LOG_DBG(ndpi_struct, "Invalid MONGODB length"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -115,7 +115,7 @@ static void ndpi_check_mongodb(struct ndpi_detection_module_struct *ndpi_struct, default: NDPI_LOG_DBG(ndpi_struct, "Invalid MONGODB length"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); break; } } @@ -125,7 +125,7 @@ static void ndpi_search_mongodb(struct ndpi_detection_module_struct *ndpi_struct { // Break after 6 packets. if(flow->packet_counter > 6) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -138,13 +138,9 @@ static void ndpi_search_mongodb(struct ndpi_detection_module_struct *ndpi_struct /* ********************************* */ -void init_mongodb_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("MongoDB", ndpi_struct, - *id, NDPI_PROTOCOL_MONGODB, ndpi_search_mongodb, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_mongodb_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("MongoDB", ndpi_struct, + ndpi_search_mongodb, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MONGODB); } diff --git a/src/lib/protocols/mpegdash.c b/src/lib/protocols/mpegdash.c index ee09dfefc..18e0510f8 100644 --- a/src/lib/protocols/mpegdash.c +++ b/src/lib/protocols/mpegdash.c @@ -49,7 +49,7 @@ static void ndpi_search_mpegdash_http(struct ndpi_detection_module_struct *ndpi_ { if (flow->packet_counter > 2) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; } @@ -83,18 +83,14 @@ static void ndpi_search_mpegdash_http(struct ndpi_detection_module_struct *ndpi_ } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_mpegdash_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_mpegdash_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MpegDash", ndpi_struct, *id, - NDPI_PROTOCOL_MPEGDASH, - ndpi_search_mpegdash_http, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("MpegDash", ndpi_struct, + ndpi_search_mpegdash_http, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MPEGDASH); } diff --git a/src/lib/protocols/mpegts.c b/src/lib/protocols/mpegts.c index 27aa6d63d..3388d2af5 100644 --- a/src/lib/protocols/mpegts.c +++ b/src/lib/protocols/mpegts.c @@ -48,19 +48,15 @@ static void ndpi_search_mpegts(struct ndpi_detection_module_struct *ndpi_struct, } no_mpegts: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mpegts_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_mpegts_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MPEG_TS", ndpi_struct, *id, - NDPI_PROTOCOL_MPEGTS, - ndpi_search_mpegts, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MPEG_TS", ndpi_struct, + ndpi_search_mpegts, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MPEGTS); } diff --git a/src/lib/protocols/mqtt.c b/src/lib/protocols/mqtt.c index 535cd02b1..6846501ce 100644 --- a/src/lib/protocols/mqtt.c +++ b/src/lib/protocols/mqtt.c @@ -93,7 +93,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_packet_struct *packet = &ndpi_struct->packet; if (flow->packet_counter > 10) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt .. mandatory header not found!\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -105,20 +105,20 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, packet->payload_packet_len); if (packet->payload_packet_len < 2) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt .. mandatory header not found!\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // we extract the remaining length rl = get_var_int(&packet->payload[1], packet->payload_packet_len - 1, &rl_len); if (rl < 0) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt .. invalid length!\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } NDPI_LOG_DBG(ndpi_struct, "Mqtt: msg_len %d\n", (unsigned long long)rl); if (packet->payload_packet_len != rl + 1 + rl_len) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt .. maximum packet size exceeded!\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // we extract the packet type @@ -126,7 +126,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct,"====>>>> Mqtt packet type: [%d]\n",pt); if ((pt == 0) || (pt == 15)) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt .. invalid packet type!\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // we extract the flags @@ -137,12 +137,12 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, (pt == PUBCOMP) || (pt == SUBACK) || (pt == UNSUBACK) || (pt == PINGREQ) || (pt == PINGRESP) || (pt == DISCONNECT)) && (flags > 0)) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid Packet-Flag combination flag!=0\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (((pt == PUBREL) || (pt == SUBSCRIBE) || (pt == UNSUBSCRIBE)) && (flags != 2)) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid Packet-Flag combination flag!=2\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } NDPI_LOG_DBG2(ndpi_struct,"====>>>> Passed first stage of identification\n"); @@ -151,7 +151,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, (pt == PUBREC) || (pt == PUBCOMP) || (pt == UNSUBACK)) { if (packet->payload_packet_len != 4) { // these packets are always 4 bytes long NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid Packet-Length < 4 \n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_INFO(ndpi_struct, "found Mqtt CONNACK/PUBACK/PUBREL/PUBREC/PUBCOMP/UNSUBACK\n"); @@ -162,7 +162,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, if ((pt == PINGREQ) || (pt == PINGRESP) || (pt == DISCONNECT)) { if (packet->payload_packet_len != 2) { // these packets are always 2 bytes long NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid Packet-Length <2 \n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_INFO(ndpi_struct, "found Mqtt PING/PINGRESP/DISCONNECT\n"); @@ -183,25 +183,25 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t dup = (u_int8_t) (flags & 0x08) >> 3; if (qos > 2) { // qos values possible are 0,1,2 NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (qos == 0) { if (dup != 0) { NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos0 and dup combination\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (packet->payload_packet_len < 5) { // at least topic (3Bytes + 2Bytes fixed header) NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos0 size\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } if ((qos == 1) || (qos == 2)) { if (packet->payload_packet_len < 7 ) { // at least topic + pkt identifier (3Bytes + 2Bytes + 2Bytes fixed header) NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos1&2\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -212,7 +212,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, if (pt == SUBSCRIBE) { if (packet->payload_packet_len < 8) { // at least one topic+filter is required in the payload NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid SUBSCRIBE\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_INFO(ndpi_struct, "found Mqtt SUBSCRIBE\n"); @@ -223,7 +223,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, if (pt == SUBACK ) { if (packet->payload_packet_len <5 ) { // must have at least a response code NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid SUBACK\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_INFO(ndpi_struct, "found Mqtt SUBACK\n"); @@ -234,7 +234,7 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, if (pt == UNSUBSCRIBE) { if (packet->payload_packet_len < 7) { // at least a topic NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid UNSUBSCRIBE\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_INFO(ndpi_struct, "found Mqtt UNSUBSCRIBE\n"); @@ -247,15 +247,12 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct, /** * Entry point for the ndpi library */ -void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection ("MQTT", ndpi_struct, *id, - NDPI_PROTOCOL_MQTT, - ndpi_search_mqtt, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id +=1; + register_dissector("MQTT", ndpi_struct, + ndpi_search_mqtt, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MQTT); } diff --git a/src/lib/protocols/msdo.c b/src/lib/protocols/msdo.c new file mode 100644 index 000000000..1c072f1bd --- /dev/null +++ b/src/lib/protocols/msdo.c @@ -0,0 +1,73 @@ +/* + * msdo.c + * + * Microsoft Delivery Optimization + * + * Copyright (C) 2025 - ntop.org + * Copyright (C) 2025 - V.G <v.gavrilov@securitycode.ru> + * + * 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_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MSDO + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_int_msdo_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow) +{ + NDPI_LOG_INFO(ndpi_struct, "found Microsoft Delivery Optimization protocol\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, + NDPI_PROTOCOL_MSDO, + NDPI_PROTOCOL_UNKNOWN, + NDPI_CONFIDENCE_DPI); +} + +static void ndpi_search_msdo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search Microsoft Delivery Optimization protocol\n"); + + /* + * Usually the handshake starts with 0x0E and the string "Swarm protocol" at the start of the payload, + * but this may vary. + */ + if (packet->payload_packet_len > 16 && packet->payload[0] == 0x0E) + { + if (memcmp(&packet->payload[1], "Swarm protocol", NDPI_STATICSTRING_LEN("Swarm protocol")) == 0) + { + ndpi_int_msdo_add_connection(ndpi_struct, flow); + return; + } + } + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); +} + + +void init_msdo_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("MSDO", ndpi_struct, + ndpi_search_msdo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MSDO); +} diff --git a/src/lib/protocols/mssql_tds.c b/src/lib/protocols/mssql_tds.c index 38efe578d..835602015 100644 --- a/src/lib/protocols/mssql_tds.c +++ b/src/lib/protocols/mssql_tds.c @@ -58,7 +58,7 @@ static void ndpi_search_mssql_tds(struct ndpi_detection_module_struct *ndpi_stru to this potocol and it can cause false positives */ || (packet->tcp->dest == ntohs(102))) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -72,18 +72,14 @@ static void ndpi_search_mssql_tds(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mssql_tds_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_mssql_tds_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MsSQL_TDS", ndpi_struct, *id, - NDPI_PROTOCOL_MSSQL_TDS, - ndpi_search_mssql_tds, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MsSQL_TDS", ndpi_struct, + ndpi_search_mssql_tds, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MSSQL_TDS); } diff --git a/src/lib/protocols/mumble.c b/src/lib/protocols/mumble.c index 588ac48dd..ed1ddfc53 100644 --- a/src/lib/protocols/mumble.c +++ b/src/lib/protocols/mumble.c @@ -58,18 +58,13 @@ static void ndpi_search_mumble(struct ndpi_detection_module_struct *ndpi_struct, } not_mumble: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mumble_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_mumble_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Mumble", ndpi_struct, *id, - NDPI_PROTOCOL_MUMBLE, - ndpi_search_mumble, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Mumble", ndpi_struct, + ndpi_search_mumble, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_MUMBLE); } diff --git a/src/lib/protocols/munin.c b/src/lib/protocols/munin.c index 06e50d3a6..5e40adbb2 100644 --- a/src/lib/protocols/munin.c +++ b/src/lib/protocols/munin.c @@ -50,13 +50,13 @@ static void ndpi_search_munin(struct ndpi_detection_module_struct *ndpi_struct, // "# munin node at " if (packet->payload_packet_len < NDPI_STATICSTRING_LEN(munin_prefix)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (memcmp(packet->payload, munin_prefix, NDPI_STATICSTRING_LEN(munin_prefix)) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -79,16 +79,10 @@ static void ndpi_search_munin(struct ndpi_detection_module_struct *ndpi_struct, /* ***************************************************** */ -void init_munin_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_munin_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Munin", ndpi_struct, *id, - NDPI_PROTOCOL_MUNIN, - ndpi_search_munin, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Munin", ndpi_struct, + ndpi_search_munin, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MUNIN); } diff --git a/src/lib/protocols/mysql.c b/src/lib/protocols/mysql.c index dbe75eb14..20df5df00 100644 --- a/src/lib/protocols/mysql.c +++ b/src/lib/protocols/mysql.c @@ -2,7 +2,7 @@ * mysql.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-24 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2024 - V.G <v.gavrilov@securitycode.ru> * * This file is part of nDPI, an open source deep packet inspection @@ -58,18 +58,14 @@ static void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_mysql_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_mysql_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("MySQL", ndpi_struct, *id, - NDPI_PROTOCOL_MYSQL, - ndpi_search_mysql_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("MySQL", ndpi_struct, + ndpi_search_mysql_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_MYSQL); } diff --git a/src/lib/protocols/nano.c b/src/lib/protocols/nano.c index 861614b82..ff9abf125 100644 --- a/src/lib/protocols/nano.c +++ b/src/lib/protocols/nano.c @@ -76,17 +76,13 @@ static void ndpi_search_nano(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_nano_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_nano_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Nano", ndpi_struct, *id, - NDPI_PROTOCOL_NANO, - ndpi_search_nano, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Nano", ndpi_struct, + ndpi_search_nano, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NANO); } diff --git a/src/lib/protocols/natpmp.c b/src/lib/protocols/natpmp.c index 4c259c91c..bdd5b308d 100644 --- a/src/lib/protocols/natpmp.c +++ b/src/lib/protocols/natpmp.c @@ -173,7 +173,7 @@ static void ndpi_search_natpmp(struct ndpi_detection_module_struct *ndpi_struct, if (natpmp_is_valid(packet, &natpmp_type) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -188,16 +188,10 @@ static void ndpi_search_natpmp(struct ndpi_detection_module_struct *ndpi_struct, } } -void init_natpmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_natpmp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NAT-PMP", ndpi_struct, *id, - NDPI_PROTOCOL_NATPMP, - ndpi_search_natpmp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("NAT-PMP", ndpi_struct, + ndpi_search_natpmp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NATPMP); } diff --git a/src/lib/protocols/nats.c b/src/lib/protocols/nats.c index d7bb79bef..a6a56754a 100644 --- a/src/lib/protocols/nats.c +++ b/src/lib/protocols/nats.c @@ -49,7 +49,7 @@ static void ndpi_search_nats_tcp(struct ndpi_detection_module_struct *ndpi_struc int i; if(packet->payload_packet_len <= 4) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); for(i=0; commands[i] != NULL; i++) { int len = ndpi_min(strlen(commands[i]), packet->payload_packet_len); @@ -67,19 +67,15 @@ static void ndpi_search_nats_tcp(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_nats_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Nats", ndpi_struct, *id, - NDPI_PROTOCOL_NATS, - ndpi_search_nats_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_nats_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Nats", ndpi_struct, + ndpi_search_nats_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NATS); } diff --git a/src/lib/protocols/nest_log_sink.c b/src/lib/protocols/nest_log_sink.c index d2a3f62d0..3b08ecdac 100644 --- a/src/lib/protocols/nest_log_sink.c +++ b/src/lib/protocols/nest_log_sink.c @@ -2,7 +2,7 @@ * nest_log_sink.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2018 - eGloo Incorporated * * This file is part of nDPI, an open source deep packet inspection @@ -42,13 +42,13 @@ static void ndpi_search_nest_log_sink(struct ndpi_detection_module_struct *ndpi_ NDPI_LOG_DBG(ndpi_struct, "search nest_log_sink\n"); if (packet->payload_packet_len < NEST_LOG_SINK_MIN_LEN) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (ntohs(packet->tcp->source) != NEST_LOG_SINK_PORT && ntohs(packet->tcp->dest) != NEST_LOG_SINK_PORT) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -63,17 +63,10 @@ static void ndpi_search_nest_log_sink(struct ndpi_detection_module_struct *ndpi_ } } -void init_nest_log_sink_dissector( - struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_nest_log_sink_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NEST_LOG_SINK", - ndpi_struct, *id, - NDPI_PROTOCOL_NEST_LOG_SINK, - ndpi_search_nest_log_sink, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NEST_LOG_SINK", ndpi_struct, + ndpi_search_nest_log_sink, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NEST_LOG_SINK); } diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c index e01c980b8..bb1e34f6a 100644 --- a/src/lib/protocols/netbios.c +++ b/src/lib/protocols/netbios.c @@ -1,7 +1,7 @@ /* * netbios.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -105,7 +105,7 @@ static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct (u_int)(packet->payload_packet_len - off), name, sizeof(name)-1) > 0) { ndpi_hostname_sni_set(flow, (const u_int8_t *)name, strlen((char *)name), NDPI_HOSTNAME_NORM_ALL); - ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 1); + ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 1, 0); } if(sub_protocol == NDPI_PROTOCOL_UNKNOWN) @@ -410,19 +410,15 @@ static void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ****************************************************************** */ -void init_netbios_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_netbios_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NETBIOS", ndpi_struct, *id, - NDPI_PROTOCOL_NETBIOS, - ndpi_search_netbios, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NETBIOS", ndpi_struct, + ndpi_search_netbios, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NETBIOS); } diff --git a/src/lib/protocols/netease_games.c b/src/lib/protocols/netease_games.c index 47b01b09c..0747ea053 100644 --- a/src/lib/protocols/netease_games.c +++ b/src/lib/protocols/netease_games.c @@ -73,18 +73,13 @@ static void ndpi_search_netease(struct ndpi_detection_module_struct *ndpi_struct /* TODO: add more NetEase Games signatures */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_netease_games_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_netease_games_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NetEaseGames", ndpi_struct, *id, - NDPI_PROTOCOL_NETEASE_GAMES, - ndpi_search_netease, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NetEaseGames", ndpi_struct, + ndpi_search_netease, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NETEASE_GAMES); } diff --git a/src/lib/protocols/netflow.c b/src/lib/protocols/netflow.c index ccb5b2762..7e3d7580f 100644 --- a/src/lib/protocols/netflow.c +++ b/src/lib/protocols/netflow.c @@ -1,7 +1,7 @@ /* * netflow.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -119,7 +119,7 @@ static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct case 7: case 9: if((n == 0) || (n > 30)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -142,7 +142,7 @@ static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct } if((expected_len > 0) && (expected_len != payload_len)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -154,7 +154,7 @@ static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct u_int16_t ipfix_len = n; if(ipfix_len != payload_len) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -162,7 +162,7 @@ static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -179,18 +179,14 @@ static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct return; } } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_netflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_netflow_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NetFlow", ndpi_struct, *id, - NDPI_PROTOCOL_NETFLOW, - ndpi_search_netflow, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NetFlow", ndpi_struct, + ndpi_search_netflow, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NETFLOW); } diff --git a/src/lib/protocols/nexon.c b/src/lib/protocols/nexon.c new file mode 100644 index 000000000..25fca5ac6 --- /dev/null +++ b/src/lib/protocols/nexon.c @@ -0,0 +1,71 @@ +/* + * nexon.c + * + * Copyright (C) 2009-11 - ipoque GmbH + * Copyright (C) 2011-25 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_protocol_ids.h" + +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_NEXON + +#include "ndpi_api.h" +#include "ndpi_private.h" + +static void ndpi_int_nexon_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NEXON, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); +} + + +static void ndpi_search_nexon(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + + NDPI_LOG_DBG(ndpi_struct, "search nexon\n"); + + if(packet->payload_packet_len == 24 && + ntohl(get_u_int32_t(packet->payload, 0)) == 0x18000000 && + ntohl(get_u_int32_t(packet->payload, 4)) == 0x64000000) { + NDPI_LOG_INFO(ndpi_struct, "found nexon\n"); + ndpi_int_nexon_add_connection(ndpi_struct, flow); + return; + } + if(packet->payload_packet_len == 20 && + ntohl(get_u_int32_t(packet->payload, 4)) == 0x163A992E) { + NDPI_LOG_INFO(ndpi_struct, "found nexon\n"); + ndpi_int_nexon_add_connection(ndpi_struct, flow); + return; + } + + /* TODO: detect UDP traffic */ + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + +} + + +void init_nexon_dissector(struct ndpi_detection_module_struct *ndpi_struct) +{ + register_dissector("Nexon", ndpi_struct, + ndpi_search_nexon, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NEXON); +} diff --git a/src/lib/protocols/nfs.c b/src/lib/protocols/nfs.c index 5fe9f78c3..b978c697b 100644 --- a/src/lib/protocols/nfs.c +++ b/src/lib/protocols/nfs.c @@ -2,7 +2,7 @@ * nfs.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -84,19 +84,15 @@ static void ndpi_search_nfs(struct ndpi_detection_module_struct *ndpi_struct, st return; exclude_nfs: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_nfs_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_nfs_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NFS", ndpi_struct, *id, - NDPI_PROTOCOL_NFS, - ndpi_search_nfs, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NFS", ndpi_struct, + ndpi_search_nfs, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NFS); } diff --git a/src/lib/protocols/nintendo.c b/src/lib/protocols/nintendo.c index 7c46439ff..99e5b5be8 100644 --- a/src/lib/protocols/nintendo.c +++ b/src/lib/protocols/nintendo.c @@ -51,17 +51,13 @@ static void ndpi_search_nintendo(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_nintendo_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Nintendo", ndpi_struct, *id, - NDPI_PROTOCOL_NINTENDO, - ndpi_search_nintendo, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_nintendo_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Nintendo", ndpi_struct, + ndpi_search_nintendo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NINTENDO); } diff --git a/src/lib/protocols/noe.c b/src/lib/protocols/noe.c index 37bfb8c71..d0faf0d00 100644 --- a/src/lib/protocols/noe.c +++ b/src/lib/protocols/noe.c @@ -2,7 +2,7 @@ * noe.c (Alcatel new office environment) * * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -67,19 +67,15 @@ static void ndpi_search_noe(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_noe_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_noe_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NOE", ndpi_struct, *id, - NDPI_PROTOCOL_NOE, - ndpi_search_noe, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NOE", ndpi_struct, + ndpi_search_noe, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NOE); } diff --git a/src/lib/protocols/nomachine.c b/src/lib/protocols/nomachine.c index 4cf4e1d8d..b675e2c65 100644 --- a/src/lib/protocols/nomachine.c +++ b/src/lib/protocols/nomachine.c @@ -67,16 +67,12 @@ static void ndpi_search_nomachine(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_nomachine_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_nomachine_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NoMachine", ndpi_struct, *id, - NDPI_PROTOCOL_NOMACHINE, - ndpi_search_nomachine, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NoMachine", ndpi_struct, + ndpi_search_nomachine, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_NOMACHINE); } diff --git a/src/lib/protocols/non_tcp_udp.c b/src/lib/protocols/non_tcp_udp.c index 1aa993eb5..ee4981817 100644 --- a/src/lib/protocols/non_tcp_udp.c +++ b/src/lib/protocols/non_tcp_udp.c @@ -2,7 +2,7 @@ * non_tcp_udp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -30,7 +30,7 @@ #define set_protocol_and_bmask(nprot) \ { \ - if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask,nprot) != 0) \ + if (is_proto_enabled(ndpi_struct, nprot)) \ { \ ndpi_set_detected_protocol(ndpi_struct, flow, \ nprot, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); \ @@ -41,10 +41,15 @@ static void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + switch (flow->l4_proto) { case NDPI_IPSEC_PROTOCOL_ESP: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_ESP); + break; + case NDPI_IPSEC_PROTOCOL_AH: - set_protocol_and_bmask(NDPI_PROTOCOL_IPSEC); + set_protocol_and_bmask(NDPI_PROTOCOL_IP_AH); break; case NDPI_GRE_PROTOCOL_TYPE: @@ -53,6 +58,43 @@ static void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct case NDPI_ICMP_PROTOCOL_TYPE: set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMP); + + if(packet->payload_packet_len < sizeof(struct ndpi_icmphdr)) { + char buf[64]; + + snprintf(buf, sizeof(buf), "Packet too short (%d vs %u)", + packet->payload_packet_len, (unsigned int)sizeof(struct ndpi_icmphdr)); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, buf); + } else { + u_int8_t icmp_type = (u_int8_t)packet->payload[0]; + u_int8_t icmp_code = (u_int8_t)packet->payload[1]; + + /* https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml */ + if(((icmp_type >= 44) && (icmp_type <= 252)) + || (icmp_code > 15)) { + char buf[64]; + + snprintf(buf, sizeof(buf), "Invalid type (%u)/code(%u)", + icmp_type, icmp_code); + + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, buf); + } + + if(packet->payload_packet_len > sizeof(struct ndpi_icmphdr)) { + if(ndpi_struct->cfg.compute_entropy && (flow->skip_entropy_check == 0)) { + flow->entropy = ndpi_entropy(packet->payload + sizeof(struct ndpi_icmphdr), + packet->payload_packet_len - sizeof(struct ndpi_icmphdr)); + ndpi_entropy2risk(ndpi_struct, flow); + } + + u_int16_t chksm = icmp4_checksum(packet->payload, packet->payload_packet_len); + + if(chksm) { + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid ICMP checksum"); + } + } + } + break; case NDPI_IGMP_PROTOCOL_TYPE: @@ -81,6 +123,30 @@ static void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct case NDPI_ICMPV6_PROTOCOL_TYPE: set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMPV6); + + if(packet->payload_packet_len < sizeof(struct ndpi_icmp6hdr)) { + char buf[64]; + + snprintf(buf, sizeof(buf), "Packet too short (%d vs %u)", + packet->payload_packet_len, (unsigned int)sizeof(struct ndpi_icmp6hdr)); + + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, buf); + } else { + u_int8_t icmp6_type = (u_int8_t)packet->payload[0]; + u_int8_t icmp6_code = (u_int8_t)packet->payload[1]; + + /* https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_for_IPv6 */ + if(((icmp6_type >= 5) && (icmp6_type <= 127)) + || ((icmp6_code >= 156) && (icmp6_type != 255))) { + char buf[64]; + + snprintf(buf, sizeof(buf), "Invalid type (%u)/code(%u)", + icmp6_type, icmp6_code); + + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, buf); + } + } + break; case NDPI_PIM_PROTOCOL_TYPE: @@ -91,100 +157,28 @@ static void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct set_protocol_and_bmask(NDPI_PROTOCOL_IP_VRRP); break; } + + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_non_tcp_udp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_non_tcp_udp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - - /* always add non tcp/udp if one protocol is compiled in */ - NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[*id].detection_bitmask, NDPI_PROTOCOL_UNKNOWN); - - ndpi_set_bitmask_protocol_detection("IPSec", ndpi_struct, *id, - NDPI_PROTOCOL_IPSEC, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_GRE", ndpi_struct, *id, - NDPI_PROTOCOL_IP_GRE, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_ICMP", ndpi_struct, *id, - NDPI_PROTOCOL_IP_ICMP, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_IGMP", ndpi_struct, *id, - NDPI_PROTOCOL_IP_IGMP, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_EGP", ndpi_struct, *id, - NDPI_PROTOCOL_IP_EGP, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_SCTP", ndpi_struct, *id, - NDPI_PROTOCOL_IP_SCTP, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_PGM", ndpi_struct, *id, - NDPI_PROTOCOL_IP_PGM, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_OSPF", ndpi_struct, *id, - NDPI_PROTOCOL_IP_OSPF, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_IP_IN_IP", ndpi_struct, *id, - NDPI_PROTOCOL_IP_IP_IN_IP, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_ICMPV6", ndpi_struct, *id, - NDPI_PROTOCOL_IP_ICMPV6, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; - - ndpi_set_bitmask_protocol_detection("IP_PIM", ndpi_struct, *id, - NDPI_PROTOCOL_IP_PIM, - ndpi_search_in_non_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, - NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Non_TCP_UDP", ndpi_struct, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + 13, + NDPI_PROTOCOL_IP_ESP, + NDPI_PROTOCOL_IP_AH, + NDPI_PROTOCOL_IP_GRE, + NDPI_PROTOCOL_IP_ICMP, + NDPI_PROTOCOL_IP_IGMP, + NDPI_PROTOCOL_IP_EGP, + NDPI_PROTOCOL_IP_SCTP, + NDPI_PROTOCOL_IP_PGM, + NDPI_PROTOCOL_IP_OSPF, + NDPI_PROTOCOL_IP_IP_IN_IP, + NDPI_PROTOCOL_IP_ICMPV6, + NDPI_PROTOCOL_IP_PIM, + NDPI_PROTOCOL_IP_VRRP); } diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c index 8e08b391a..95ef7dddd 100644 --- a/src/lib/protocols/ntp.c +++ b/src/lib/protocols/ntp.c @@ -2,7 +2,7 @@ * ntp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,15 +44,11 @@ static void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct if (packet->udp->dest == htons(123) || packet->udp->source == htons(123)) { NDPI_LOG_DBG2(ndpi_struct, "NTP port and length detected\n"); - - if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { - - // 38 in binary representation is 00111000 - flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; - - if (packet->payload_packet_len > 3 && flow->protos.ntp.version == 2) { - flow->protos.ntp.request_code = packet->payload[3]; - } + uint8_t version = (packet->payload[0] & 56) >> 3; + + if (version <= 4) { + flow->protos.ntp.version = version; + flow->protos.ntp.mode = packet->payload[0] & 7; NDPI_LOG_INFO(ndpi_struct, "found NTP\n"); ndpi_int_ntp_add_connection(ndpi_struct, flow); @@ -60,19 +56,15 @@ static void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ntp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ntp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("NTP", ndpi_struct, *id, - NDPI_PROTOCOL_NTP, - ndpi_search_ntp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("NTP", ndpi_struct, + ndpi_search_ntp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_NTP); } diff --git a/src/lib/protocols/oicq.c b/src/lib/protocols/oicq.c index 50585fe9e..d97886144 100644 --- a/src/lib/protocols/oicq.c +++ b/src/lib/protocols/oicq.c @@ -59,19 +59,19 @@ static void ndpi_search_oicq(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < sizeof(*hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (hdr->flag != 0x02) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (ntohs(hdr->version) != 0x3b0b) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -79,7 +79,7 @@ static void ndpi_search_oicq(struct ndpi_detection_module_struct *ndpi_struct, if (command == 0x0000 || (command > 0x00b5 && command < 0x03f7) || command > 0x03f7) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -88,16 +88,10 @@ static void ndpi_search_oicq(struct ndpi_detection_module_struct *ndpi_struct, /* ***************************************************** */ -void init_oicq_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_oicq_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("OICQ", ndpi_struct, *id, - NDPI_PROTOCOL_OICQ, - ndpi_search_oicq, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("OICQ", ndpi_struct, + ndpi_search_oicq, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_OICQ); } diff --git a/src/lib/protocols/ookla.c b/src/lib/protocols/ookla.c index dd15636dd..eec8778b1 100644 --- a/src/lib/protocols/ookla.c +++ b/src/lib/protocols/ookla.c @@ -92,7 +92,7 @@ void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct NDPI_LOG_DBG(ndpi_struct, "Ookla detection\n"); if(ntohs(flow->s_port) != ookla_port && ntohs(flow->c_port) != ookla_port) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -113,19 +113,14 @@ void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************* */ -void init_ookla_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Ookla", ndpi_struct, *id, - NDPI_PROTOCOL_OOKLA, - ndpi_search_ookla, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_ookla_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Ookla", ndpi_struct, + ndpi_search_ookla, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_OOKLA); } diff --git a/src/lib/protocols/opc-ua.c b/src/lib/protocols/opc-ua.c index a950664d3..78766c86a 100644 --- a/src/lib/protocols/opc-ua.c +++ b/src/lib/protocols/opc-ua.c @@ -66,16 +66,13 @@ static void ndpi_search_opc_ua(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_opc_ua_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_opc_ua_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("OPC-UA", ndpi_struct, *id, - NDPI_PROTOCOL_OPC_UA, - ndpi_search_opc_ua, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("OPC-UA", ndpi_struct, + ndpi_search_opc_ua, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_OPC_UA); } diff --git a/src/lib/protocols/openflow.c b/src/lib/protocols/openflow.c index 966e56527..e577de210 100644 --- a/src/lib/protocols/openflow.c +++ b/src/lib/protocols/openflow.c @@ -53,18 +53,14 @@ static void ndpi_search_openflow(struct ndpi_detection_module_struct *ndpi_struc return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_openflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_openflow_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("OpenFlow", ndpi_struct, *id, - NDPI_PROTOCOL_OPENFLOW, - ndpi_search_openflow, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("OpenFlow", ndpi_struct, + ndpi_search_openflow, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_OPENFLOW); } diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c index 43076590a..768e181f8 100644 --- a/src/lib/protocols/openvpn.c +++ b/src/lib/protocols/openvpn.c @@ -1,7 +1,7 @@ /* * openvpn.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * * * nDPI is free software: you can redistribute it and/or modify @@ -461,7 +461,7 @@ static void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct if(packet->payload_packet_len > 10 && ntohl(*(u_int32_t *)&packet->payload[4 + 2 * (packet->tcp != NULL)]) == 0x2112A442) { NDPI_LOG_DBG2(ndpi_struct, "Avoid collision with STUN\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -491,19 +491,14 @@ static void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Obfuscated OpenVPN"); } else if(flow->ovpn_alg_standard_state == 1 && flow->ovpn_alg_heur_opcode_state == 1) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, *id, - NDPI_PROTOCOL_OPENVPN, - ndpi_search_openvpn, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("OpenVPN", ndpi_struct, + ndpi_search_openvpn, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_OPENVPN); } diff --git a/src/lib/protocols/openwire.c b/src/lib/protocols/openwire.c index a5e824be3..050e7a263 100644 --- a/src/lib/protocols/openwire.c +++ b/src/lib/protocols/openwire.c @@ -47,16 +47,13 @@ static void ndpi_search_openwire(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_openwire_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_openwire_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("OpenWire", ndpi_struct, *id, - NDPI_PROTOCOL_OPENWIRE, - ndpi_search_openwire, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("OpenWire", ndpi_struct, + ndpi_search_openwire, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_OPENWIRE); } diff --git a/src/lib/protocols/oracle.c b/src/lib/protocols/oracle.c index 56e9a0fb4..78aac3df0 100644 --- a/src/lib/protocols/oracle.c +++ b/src/lib/protocols/oracle.c @@ -56,18 +56,14 @@ static void ndpi_search_oracle(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_oracle_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_oracle_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Oracle", ndpi_struct, *id, - NDPI_PROTOCOL_ORACLE, - ndpi_search_oracle, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Oracle", ndpi_struct, + ndpi_search_oracle, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ORACLE); } diff --git a/src/lib/protocols/paltalk.c b/src/lib/protocols/paltalk.c index ecf147bf7..763a5c2a7 100644 --- a/src/lib/protocols/paltalk.c +++ b/src/lib/protocols/paltalk.c @@ -57,17 +57,13 @@ static void ndpi_search_paltalk(struct ndpi_detection_module_struct *ndpi_struct return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_paltalk_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_paltalk_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Paltalk", ndpi_struct, *id, - NDPI_PROTOCOL_PALTALK, - ndpi_search_paltalk, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Paltalk", ndpi_struct, + ndpi_search_paltalk, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_PALTALK); } diff --git a/src/lib/protocols/path_of_exile.c b/src/lib/protocols/path_of_exile.c index 7a14b50d6..4f235a94d 100644 --- a/src/lib/protocols/path_of_exile.c +++ b/src/lib/protocols/path_of_exile.c @@ -66,17 +66,13 @@ static void ndpi_search_pathofexile(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_pathofexile_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_pathofexile_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PathofExile", ndpi_struct, *id, - NDPI_PROTOCOL_PATHOFEXILE, - ndpi_search_pathofexile, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("PathofExile", ndpi_struct, + ndpi_search_pathofexile, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_PATHOFEXILE); } diff --git a/src/lib/protocols/pfcp.c b/src/lib/protocols/pfcp.c index ca36ea471..2b3ef3b8e 100644 --- a/src/lib/protocols/pfcp.c +++ b/src/lib/protocols/pfcp.c @@ -56,17 +56,12 @@ static void ndpi_search_pfcp(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_pfcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_pfcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PFCP", ndpi_struct, *id, - NDPI_PROTOCOL_PFCP, - ndpi_search_pfcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("PFCP", ndpi_struct, + ndpi_search_pfcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_PFCP); } diff --git a/src/lib/protocols/postgres.c b/src/lib/protocols/postgres.c index 56e215862..a9712500d 100644 --- a/src/lib/protocols/postgres.c +++ b/src/lib/protocols/postgres.c @@ -2,7 +2,7 @@ * postgres.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -119,19 +119,15 @@ static void ndpi_search_postgres_tcp(struct ndpi_detection_module_struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_postgres_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_postgres_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PostgreSQL", ndpi_struct, *id, - NDPI_PROTOCOL_POSTGRES, - ndpi_search_postgres_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("PostgreSQL", ndpi_struct, + ndpi_search_postgres_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_POSTGRES); } diff --git a/src/lib/protocols/pptp.c b/src/lib/protocols/pptp.c index 8951d091e..8e0fcc458 100644 --- a/src/lib/protocols/pptp.c +++ b/src/lib/protocols/pptp.c @@ -2,7 +2,7 @@ * pptp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,18 +53,14 @@ static void ndpi_search_pptp(struct ndpi_detection_module_struct return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_pptp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_pptp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PPTP", ndpi_struct, *id, - NDPI_PROTOCOL_PPTP, - ndpi_search_pptp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("PPTP", ndpi_struct, + ndpi_search_pptp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_PPTP); } diff --git a/src/lib/protocols/profinet_io.c b/src/lib/protocols/profinet_io.c index 797bba63d..09b96f53d 100644 --- a/src/lib/protocols/profinet_io.c +++ b/src/lib/protocols/profinet_io.c @@ -72,18 +72,13 @@ static void ndpi_search_profinet_io(struct ndpi_detection_module_struct *ndpi_st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_profinet_io_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_profinet_io_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PROFINET_IO", ndpi_struct, *id, - NDPI_PROTOCOL_PROFINET_IO, - ndpi_search_profinet_io, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("PROFINET_IO", ndpi_struct, + ndpi_search_profinet_io, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_PROFINET_IO); } diff --git a/src/lib/protocols/protobuf.c b/src/lib/protocols/protobuf.c index 4306e81ad..1a70747bd 100644 --- a/src/lib/protocols/protobuf.c +++ b/src/lib/protocols/protobuf.c @@ -125,7 +125,7 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc enum protobuf_type type = protobuf_dissect_tag(tag, &field_number); if (type == PT_INVALID || field_number == 0 || field_number > (UINT_MAX >> 3)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -139,7 +139,7 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc uint64_t value; if (protobuf_dissect_varint(packet, &offset, &value) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } #ifdef DEBUG_PROTOBUF @@ -151,7 +151,7 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc case PT_I64: { if (packet->payload_packet_len < offset + sizeof(uint64_t)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } #ifdef DEBUG_PROTOBUF @@ -176,13 +176,13 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc { break; // We are not excluding the protocol immediately. Let's wait for more packets to arrive.. } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } if (length == 0 || length > INT_MAX) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } offset += length; @@ -195,12 +195,12 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc case PT_SGROUP: case PT_EGROUP: // Start/End groups are deprecated and therefor ignored to reduce false positives. - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; case PT_I32: { if (packet->payload_packet_len < offset + sizeof(uint32_t)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } #ifdef DEBUG_PROTOBUF @@ -245,18 +245,14 @@ static void ndpi_search_protobuf(struct ndpi_detection_module_struct *ndpi_struc return; // We probably need more packets to dissect. } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_protobuf_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_protobuf_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Protobuf", ndpi_struct, *id, - NDPI_PROTOCOL_PROTOBUF, - ndpi_search_protobuf, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Protobuf", ndpi_struct, + ndpi_search_protobuf, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_PROTOBUF); } diff --git a/src/lib/protocols/ptpv2.c b/src/lib/protocols/ptpv2.c index 6e254bff0..6ec0b5410 100644 --- a/src/lib/protocols/ptpv2.c +++ b/src/lib/protocols/ptpv2.c @@ -63,17 +63,13 @@ static void ndpi_search_ptpv2_udp(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ptpv2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ptpv2_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("PTPv2", ndpi_struct, *id, - NDPI_PROTOCOL_PTPV2, - ndpi_search_ptpv2_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("PTPv2", ndpi_struct, + ndpi_search_ptpv2_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_PTPV2); } diff --git a/src/lib/protocols/qq.c b/src/lib/protocols/qq.c index efe35e8e5..5eeddaf16 100644 --- a/src/lib/protocols/qq.c +++ b/src/lib/protocols/qq.c @@ -53,19 +53,15 @@ static void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, str ndpi_int_qq_add_connection(ndpi_struct, flow); } else { if(flow->num_processed_pkts > 4) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_qq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_qq_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, *id, - NDPI_PROTOCOL_QQ, - ndpi_search_qq, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("QQ", ndpi_struct, + ndpi_search_qq, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_QQ); } diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index e7b217862..95ea29ea9 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1460,18 +1460,22 @@ void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, ndpi_match_host_subprotocol(ndpi_struct, flow, flow->host_server_name, strlen(flow->host_server_name), - &ret_match, NDPI_PROTOCOL_QUIC); + &ret_match, NDPI_PROTOCOL_QUIC, 1); flow->protos.tls_quic.client_hello_processed = 1; /* Allow matching of custom categories */ ndpi_check_dga_name(ndpi_struct, flow, - flow->host_server_name, 1, 0); + flow->host_server_name, 1, 0, 0); if(ndpi_is_valid_hostname((char *)&crypto_data[tag_offset_start + prev_offset], len) == 0) { - char str[128]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_INVALID_CHARACTERS)) { + char str[128]; - snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } /* This looks like an attack */ ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious hostname: attack ?"); @@ -1973,7 +1977,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, if(ret == -1) { NDPI_LOG_DBG2(ndpi_struct, "Keep looking for SH by client\n"); if(flow->packet_counter > 10 /* TODO */) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ret = may_be_gquic_rej(ndpi_struct); @@ -1984,7 +1988,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -2002,7 +2006,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, if(!is_version_supported(version)) { NDPI_LOG_DBG(ndpi_struct, "Unsupported version 0x%x\n", version); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -2025,7 +2029,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, */ clear_payload = get_clear_payload(ndpi_struct, flow, version, &clear_payload_len); if(!clear_payload) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -2057,18 +2061,16 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, flow->max_extra_packets_to_check = 24; /* TODO */ flow->extra_packets_func = ndpi_search_quic_extra; } else if(!crypto_data) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* ***************************************************************** */ -void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, *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); - - *id += 1; + register_dissector("QUIC", ndpi_struct, + ndpi_search_quic, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_QUIC); } diff --git a/src/lib/protocols/radius_proto.c b/src/lib/protocols/radius_proto.c index 00bbcad04..e8063d136 100644 --- a/src/lib/protocols/radius_proto.c +++ b/src/lib/protocols/radius_proto.c @@ -48,7 +48,7 @@ static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, struct radius_header *h = (struct radius_header*)packet->payload; /* RFC2865: The minimum length is 20 and maximum length is 4096. */ if((payload_len < 20) || (payload_len > 4096)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -61,7 +61,7 @@ static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, } } if(flow->packet_counter > 3) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -73,14 +73,10 @@ static void ndpi_search_radius(struct ndpi_detection_module_struct *ndpi_struct, } -void init_radius_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_radius_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Radius", ndpi_struct, *id, - NDPI_PROTOCOL_RADIUS, - ndpi_search_radius, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Radius", ndpi_struct, + ndpi_search_radius, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RADIUS); } diff --git a/src/lib/protocols/radmin.c b/src/lib/protocols/radmin.c index b9ab63631..c7fcfa85a 100644 --- a/src/lib/protocols/radmin.c +++ b/src/lib/protocols/radmin.c @@ -85,16 +85,13 @@ static void ndpi_search_radmin(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_radmin_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_radmin_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Radmin", ndpi_struct, *id, - NDPI_PROTOCOL_RADMIN, - ndpi_search_radmin, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Radmin", ndpi_struct, + ndpi_search_radmin, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RADMIN); } diff --git a/src/lib/protocols/raft.c b/src/lib/protocols/raft.c index 6f0428561..67ae23e6a 100644 --- a/src/lib/protocols/raft.c +++ b/src/lib/protocols/raft.c @@ -61,7 +61,7 @@ static void ndpi_search_raft(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < sizeof(*raft_header)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -77,7 +77,7 @@ static void ndpi_search_raft(struct ndpi_detection_module_struct *ndpi_struct, break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -96,16 +96,11 @@ static void ndpi_search_raft(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_raft_add_connection(ndpi_struct, flow); } -void init_raft_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_raft_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Raft", ndpi_struct, *id, - NDPI_PROTOCOL_RAFT, - ndpi_search_raft, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Raft", ndpi_struct, + ndpi_search_raft, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RAFT); } diff --git a/src/lib/protocols/raknet.c b/src/lib/protocols/raknet.c index 3e3200e1a..bdbd4706e 100644 --- a/src/lib/protocols/raknet.c +++ b/src/lib/protocols/raknet.c @@ -1,7 +1,7 @@ /* * raknet.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -79,7 +79,7 @@ static void exclude_proto(struct ndpi_detection_module_struct *ndpi_struct, other protocols too. Keep the generic classification, for the time being */ ndpi_int_raknet_add_connection(ndpi_struct, flow); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } @@ -391,15 +391,10 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_raknet_add_connection(ndpi_struct, flow); } -void init_raknet_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_raknet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RakNet", ndpi_struct, *id, - NDPI_PROTOCOL_RAKNET, - ndpi_search_raknet, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RakNet", ndpi_struct, + ndpi_search_raknet, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RAKNET); } diff --git a/src/lib/protocols/rdp.c b/src/lib/protocols/rdp.c index e7683d16e..42a7ba6fe 100644 --- a/src/lib/protocols/rdp.c +++ b/src/lib/protocols/rdp.c @@ -2,7 +2,7 @@ * rdp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-24 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -91,7 +91,7 @@ static void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, if((rdp_requested_proto & 0x1) == 0x1) { /* RDP Response + Client Hello + Server hello */ flow->max_extra_packets_to_check = 5; - + flow->tls_quic.from_rdp = 1; flow->extra_packets_func = ndpi_search_tls_over_rdp; } } @@ -110,7 +110,7 @@ static void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, } } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else if(packet->udp != NULL) { u_int16_t s_port = ntohs(packet->udp->source); u_int16_t d_port = ntohs(packet->udp->dest); @@ -137,7 +137,7 @@ static void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, } } else { if(memcmp(flow->l4.udp.rdp_from_srv, packet->payload, 3) != 0) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); else { flow->l4.udp.rdp_from_srv_pkts = 2 /* stage 2 */; @@ -163,7 +163,7 @@ static void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, } } else { if(memcmp(flow->l4.udp.rdp_to_srv, packet->payload, 3) != 0) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); else { flow->l4.udp.rdp_to_srv_pkts = 2 /* stage 2 */; @@ -175,20 +175,16 @@ static void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, } } } else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* **************************************** */ -void init_rdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rdp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RDP", ndpi_struct, *id, - NDPI_PROTOCOL_RDP, - ndpi_search_rdp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RDP", ndpi_struct, + ndpi_search_rdp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RDP); } diff --git a/src/lib/protocols/resp.c b/src/lib/protocols/resp.c index 6cf49f6e4..04ec98d14 100644 --- a/src/lib/protocols/resp.c +++ b/src/lib/protocols/resp.c @@ -66,16 +66,13 @@ static void ndpi_search_resp(struct ndpi_detection_module_struct *ndpi_struct, } exclude: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_resp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_resp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RESP", ndpi_struct, *id, - NDPI_PROTOCOL_RESP, - ndpi_search_resp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("RESP", ndpi_struct, + ndpi_search_resp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RESP); } diff --git a/src/lib/protocols/riotgames.c b/src/lib/protocols/riotgames.c index df20618d4..9b2626f6b 100644 --- a/src/lib/protocols/riotgames.c +++ b/src/lib/protocols/riotgames.c @@ -63,20 +63,14 @@ static void ndpi_search_riotgames(struct ndpi_detection_module_struct *ndpi_stru * Please add new patterns for games made by RiotGames here */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_riotgames_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_riotgames_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RiotGames", ndpi_struct, *id, - NDPI_PROTOCOL_RIOTGAMES, - ndpi_search_riotgames, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("RiotGames", ndpi_struct, + ndpi_search_riotgames, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RIOTGAMES); } diff --git a/src/lib/protocols/ripe_atlas.c b/src/lib/protocols/ripe_atlas.c index ac95f949c..d9d226da2 100644 --- a/src/lib/protocols/ripe_atlas.c +++ b/src/lib/protocols/ripe_atlas.c @@ -47,7 +47,7 @@ static void ndpi_search_ripe_atlas(struct ndpi_detection_module_struct *ndpi_str NDPI_LOG_DBG(ndpi_struct, "search (Magellan) Ripe Atlas Tool\n"); if (packet->payload_packet_len != 25) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -56,18 +56,13 @@ static void ndpi_search_ripe_atlas(struct ndpi_detection_module_struct *ndpi_str return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ripe_atlas_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ripe_atlas_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RipeAtlas", ndpi_struct, *id, - NDPI_PROTOCOL_RIPE_ATLAS, - ndpi_search_ripe_atlas, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RipeAtlas", ndpi_struct, + ndpi_search_ripe_atlas, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RIPE_ATLAS); } diff --git a/src/lib/protocols/rmcp.c b/src/lib/protocols/rmcp.c index 19402e5ba..4ffb320d7 100644 --- a/src/lib/protocols/rmcp.c +++ b/src/lib/protocols/rmcp.c @@ -58,27 +58,27 @@ static void ndpi_search_rmcp(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search RMCP\n"); if (packet->payload_packet_len < sizeof(struct rmcp_header)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } struct rmcp_header const * const rmcp_header = (struct rmcp_header *)packet->payload; if (rmcp_header->version != 0x06 || rmcp_header->reserved != 0x00) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (rmcp_header->type != 0 && rmcp_header->sequence == 0xFF) { // No ACK allowed if SEQUENCE number is 255. - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (rmcp_header->class != 0x06 /* Alert Standard Forum (ASF)*/ && rmcp_header->class != 0x07 /* Intelligent Platform Management Interface (IPMI) */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -86,15 +86,11 @@ static void ndpi_search_rmcp(struct ndpi_detection_module_struct *ndpi_struct, } -void init_rmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RMCP", ndpi_struct, *id, - NDPI_PROTOCOL_RMCP, - ndpi_search_rmcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RMCP", ndpi_struct, + ndpi_search_rmcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RMCP); } diff --git a/src/lib/protocols/roughtime.c b/src/lib/protocols/roughtime.c index 5ebd00b84..2d64fe1c1 100644 --- a/src/lib/protocols/roughtime.c +++ b/src/lib/protocols/roughtime.c @@ -77,7 +77,7 @@ static void ndpi_search_roughtime(struct ndpi_detection_module_struct *ndpi_stru if (packet->payload_packet_len < 4) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -88,7 +88,7 @@ static void ndpi_search_roughtime(struct ndpi_detection_module_struct *ndpi_stru if (number_of_tags < 1 || packet->payload_packet_len < minimum_length || number_of_tags > NDPI_ARRAY_LENGTH(valid_tags)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -96,7 +96,7 @@ static void ndpi_search_roughtime(struct ndpi_detection_module_struct *ndpi_stru u_int32_t tag_offset = le32toh(get_u_int32_t(packet->payload, 4 + (number_of_tags - 2) * 4)); if (packet->payload_packet_len < 4 + (number_of_tags - 1) * 4 + tag_offset) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -116,7 +116,7 @@ static void ndpi_search_roughtime(struct ndpi_detection_module_struct *ndpi_stru } if (j == NDPI_ARRAY_LENGTH(valid_tags)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -124,16 +124,10 @@ static void ndpi_search_roughtime(struct ndpi_detection_module_struct *ndpi_stru ndpi_int_roughtime_add_connection(ndpi_struct, flow); } -void init_roughtime_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_roughtime_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Roughtime", ndpi_struct, *id, - NDPI_PROTOCOL_ROUGHTIME, - ndpi_search_roughtime, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Roughtime", ndpi_struct, + ndpi_search_roughtime, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ROUGHTIME); } diff --git a/src/lib/protocols/rsh.c b/src/lib/protocols/rsh.c index 6addb7404..4bb49f8d5 100644 --- a/src/lib/protocols/rsh.c +++ b/src/lib/protocols/rsh.c @@ -71,12 +71,12 @@ static void ndpi_search_rsh(struct ndpi_detection_module_struct * ndpi_struct, { if (ndpi_isdigit(packet->payload[i]) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; @@ -84,7 +84,7 @@ static void ndpi_search_rsh(struct ndpi_detection_module_struct * ndpi_struct, if (packet->payload_packet_len < 3 || packet->payload[packet->payload_packet_len - 1] != '\0') { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -103,7 +103,7 @@ static void ndpi_search_rsh(struct ndpi_detection_module_struct * ndpi_struct, ndpi_is_printable_buffer((uint8_t const *)dissected_info[i - 1], (dissected_info[i] - dissected_info[i - 1])) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -111,7 +111,7 @@ static void ndpi_search_rsh(struct ndpi_detection_module_struct * ndpi_struct, { if (dissected_info[NDPI_ARRAY_LENGTH(dissected_info) - 1] == NULL) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } break; @@ -144,20 +144,16 @@ static void ndpi_search_rsh(struct ndpi_detection_module_struct * ndpi_struct, return; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } -void init_rsh_dissector(struct ndpi_detection_module_struct * ndpi_struct, - u_int32_t * id) +void init_rsh_dissector(struct ndpi_detection_module_struct * ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RSH", ndpi_struct, *id, - NDPI_PROTOCOL_RSH, ndpi_search_rsh, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RSH", ndpi_struct, + ndpi_search_rsh, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RSH); } diff --git a/src/lib/protocols/rsync.c b/src/lib/protocols/rsync.c index b2ab8e681..d354e0f50 100644 --- a/src/lib/protocols/rsync.c +++ b/src/lib/protocols/rsync.c @@ -54,18 +54,14 @@ static void ndpi_search_rsync(struct ndpi_detection_module_struct *ndpi_struct, } } if(flow->packet_counter > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_rsync_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rsync_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RSYNC", ndpi_struct, *id, - NDPI_PROTOCOL_RSYNC, - ndpi_search_rsync, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RSYNC", ndpi_struct, + ndpi_search_rsync, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RSYNC); } diff --git a/src/lib/protocols/rtmp.c b/src/lib/protocols/rtmp.c index a1da9760c..e0f953815 100644 --- a/src/lib/protocols/rtmp.c +++ b/src/lib/protocols/rtmp.c @@ -46,7 +46,7 @@ static void ndpi_check_rtmp(struct ndpi_detection_module_struct *ndpi_struct, st See: https://en.wikipedia.org/w/index.php?title=Real-Time_Messaging_Protocol§ion=12#Handshake */ if(!ndpi_seen_flow_beginning(flow)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -80,7 +80,7 @@ static void ndpi_check_rtmp(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -91,15 +91,11 @@ static void ndpi_search_rtmp(struct ndpi_detection_module_struct *ndpi_struct, s } -void init_rtmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rtmp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RTMP", ndpi_struct, *id, - NDPI_PROTOCOL_RTMP, - ndpi_search_rtmp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RTMP", ndpi_struct, + ndpi_search_rtmp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RTMP); } diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c index 2dc653dfb..7c1bdceed 100644 --- a/src/lib/protocols/rtp.c +++ b/src/lib/protocols/rtp.c @@ -2,7 +2,7 @@ * rtp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,6 +32,11 @@ #define RTP_MIN_HEADER 12 #define RTCP_MIN_HEADER 8 +static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + +/* *************************************************************** */ + /* https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml */ int is_valid_rtp_payload_type(uint8_t type) { @@ -40,6 +45,8 @@ int is_valid_rtp_payload_type(uint8_t type) return 1; } +/* *************************************************************** */ + u_int8_t rtp_get_stream_type(u_int8_t payloadType, u_int8_t *s_type, u_int16_t sub_proto) { /* General, from IANA */ @@ -201,10 +208,14 @@ u_int8_t rtp_get_stream_type(u_int8_t payloadType, u_int8_t *s_type, u_int16_t s return(0); } +/* *************************************************************** */ + static int is_valid_rtcp_payload_type(uint8_t type) { return (type >= 192 && type <= 213); } +/* *************************************************************** */ + int is_rtp_or_rtcp(struct ndpi_detection_module_struct *ndpi_struct, const u_int8_t *payload, u_int16_t payload_len, u_int16_t *seq) { @@ -214,7 +225,7 @@ int is_rtp_or_rtcp(struct ndpi_detection_module_struct *ndpi_struct, if(payload_len < 2) return NO_RTP_RTCP; - + if((payload[0] & 0xC0) != 0x80) { /* Version 2 */ NDPI_LOG_DBG(ndpi_struct, "Not version 2\n"); return NO_RTP_RTCP; @@ -239,8 +250,8 @@ int is_rtp_or_rtcp(struct ndpi_detection_module_struct *ndpi_struct, return NO_RTP_RTCP; } /* Check on padding doesn't work because: - * we may have multiple RTP packets in the same TCP/UDP datagram - * with SRTP, padding_length field is encrypted */ + * we may have multiple RTP packets in the same TCP/UDP datagram + * with SRTP, padding_length field is encrypted */ if(seq) *seq = ntohs(*(unsigned short *)&payload[2]); return IS_RTP; @@ -257,6 +268,98 @@ int is_rtp_or_rtcp(struct ndpi_detection_module_struct *ndpi_struct, return NO_RTP_RTCP; } +/* ************************************************************ */ + +static int get_rtp_info(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const u_int8_t *payload, + u_int16_t payload_len) { + u_int8_t packet_direction = current_pkt_from_client_to_server(ndpi_struct, flow) ? 0 : 1; + + if(flow->rtp[packet_direction].payload_detected == false) { + flow->rtp[packet_direction].payload_type = payload[1] & 0x7F; + flow->rtp[packet_direction].payload_detected = true; + + /* printf("********* [direction: %d] payload_type=%u\n", packet_direction, flow->protos.rtp[packet_direction].payload_type); */ + + if(((flow->rtp[packet_direction].payload_type == 126 /* Enhanced Voice Services (EVS) */) + || (flow->rtp[packet_direction].payload_type == 127 /* Enhanced Voice Services (EVS) */)) + && (payload_len > 12 /* RTP header */)) { + const u_int8_t *evs = &payload[12]; + u_int packet_len = payload_len - 12; + u_int num_bits = packet_len * 8; + + flow->flow_multimedia_types = ndpi_multimedia_audio_flow; + /* printf("********* %02X [bits %u]\n", evs[0], num_bits); */ + + if(num_bits == 56) { + /* A.2.1.3 Special case for 56 bit payload size (EVS Primary or EVS AMR-WB IO SID) */ + + if((evs[0] & 0x80) == 0) + flow->rtp[packet_direction].evs_subtype = evs[0] & 0xF; + else + flow->rtp[packet_direction].evs_subtype = evs[1] & 0xF; + } else { + + /* See ndpi_rtp_payload_type2str() */ + switch(num_bits) { + case 48: + case 136: + case 144: + case 160: + case 184: + case 192: + case 256: + case 264: + case 288: + case 320: + case 328: + case 368: + case 400: + case 464: + case 480: + case 488: + case 640: + case 960: + case 1280: + case 1920: + case 2560: + flow->rtp[packet_direction].evs_subtype = num_bits; + break; + + default: + if((evs[0] >> 7) == 1) { + /* EVS Codec Mode Request (EVS-CMR) */ + u_int8_t d_bits = evs[0] & 0X0F; + + flow->rtp[packet_direction].evs_subtype = d_bits + 30 /* dummy offset */; + } + break; + } + } + } + } + return 0; +} + +/* ************************************************************ */ + +static int keep_extra_dissection(struct ndpi_flow_struct *flow) { + return ((flow->rtp[0].payload_detected && flow->rtp[1].payload_detected) ? false :true); +} + +/* ************************************************************ */ + +static int rtp_search_again(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + NDPI_LOG_DBG2(ndpi_struct, "Again\n"); + + ndpi_rtp_search(ndpi_struct, flow); + + return keep_extra_dissection(flow); +} + +/* *************************************************************** */ static void ndpi_int_rtp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, @@ -272,6 +375,14 @@ static void ndpi_int_rtp_add_connection(struct ndpi_detection_module_struct *ndp NDPI_LOG_DBG(ndpi_struct, "Enabling (STUN) extra dissection\n"); switch_extra_dissection_to_stun(ndpi_struct, flow, 1); } + } else if(proto == NDPI_PROTOCOL_RTP) { + if(!flow->extra_packets_func && + keep_extra_dissection(flow) && + ndpi_struct->cfg.rtp_max_packets_extra_dissection > 0) { + NDPI_LOG_DBG(ndpi_struct, "Enabling extra dissection\n"); + flow->max_extra_packets_to_check = ndpi_struct->cfg.rtp_max_packets_extra_dissection; + flow->extra_packets_func = rtp_search_again; + } } } @@ -285,22 +396,28 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t payload_len = packet->payload_packet_len; u_int16_t seq; + if(packet->payload_packet_len == 0 || packet->tcp_retransmission) + return; + if(packet->tcp != NULL) { - payload += 2; /* Skip the length field */ - payload_len -= 2; + if (payload_len < 2) { + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); + return; + } + payload += 2; /* Skip the length field */ + payload_len -= 2; } NDPI_LOG_DBG(ndpi_struct, "search RTP (stage %d/%d)\n", flow->rtp_stage, flow->rtcp_stage); /* * Let some "unknown" packets at the beginning: - * search for 3/4 consecutive RTP/RTCP packets. - * Wait a little longer (4 vs 3 pkts) for RTCP to try to tell if there are only - * RTCP packets in the flow or if RTP/RTCP are multiplexed together */ + * search for 3/4 consecutive RTP/RTCP packets. + * Wait a little longer (4 vs 3 pkts) for RTCP to try to tell if there are only + * RTCP packets in the flow or if RTP/RTCP are multiplexed together */ if(flow->packet_counter > 3 && flow->rtp_stage == 0 && flow->rtcp_stage == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -311,21 +428,21 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, if(flow->l4_proto == IPPROTO_UDP && flow->l4.udp.line_pkts[0] >= 2 && flow->l4.udp.line_pkts[1] >= 2) { /* It seems that it is a LINE stuff; let its dissector to evaluate */ - } else if(flow->l4_proto == IPPROTO_UDP && - flow->l4.udp.epicgames_stage > 0) { + } else if(flow->l4_proto == IPPROTO_UDP && flow->l4.udp.epicgames_stage > 0) { /* It seems that it is a EpicGames stuff; let its dissector to evaluate */ } else if(flow->rtp_seq_set[packet->packet_direction] && flow->rtp_seq[packet->packet_direction] == seq) { - /* Simple heuristic to avoid false positives. tradeoff between: - * consecutive RTP packets should have different sequence number - * we should handle duplicated traffic */ + /* Simple heuristic to avoid false positives. Tradeoff between: + - consecutive RTP packets should have different sequence number + - we should handle duplicated traffic */ NDPI_LOG_DBG(ndpi_struct, "Same seq on consecutive pkts\n"); flow->rtp_stage = 0; flow->rtcp_stage = 0; - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else { - rtp_get_stream_type(payload[1] & 0x7F, &flow->flow_multimedia_types, NDPI_PROTOCOL_UNKNOWN); + get_rtp_info(ndpi_struct, flow, payload, payload_len); + rtp_get_stream_type(flow->rtp[packet->packet_direction].payload_type, + &flow->flow_multimedia_types, NDPI_PROTOCOL_UNKNOWN); NDPI_LOG_INFO(ndpi_struct, "Found RTP\n"); ndpi_int_rtp_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTP); @@ -350,16 +467,16 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, if(flow->rtp_stage || flow->rtcp_stage) { u_int32_t unused; u_int16_t app_proto = NDPI_PROTOCOL_UNKNOWN; - + ndpi_protocol_category_t category; + /* TODO: we should switch to the demultiplexing-code in stun dissector */ - if(is_stun(ndpi_struct, flow, &app_proto) != 0 && + if(is_stun(ndpi_struct, flow, &app_proto, &category) != 0 && !is_dtls(packet->payload, packet->payload_packet_len, &unused)) { flow->rtp_stage = 0; flow->rtcp_stage = 0; - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } - } + } } } @@ -373,21 +490,19 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, * --------------------------------------------------------------- */ static void ndpi_search_rtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; const u_int8_t *payload = packet->payload; - + if(packet->payload_packet_len < 4){ /* (2) len field + (2) min rtp/rtcp*/ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } u_int16_t len = ntohs(get_u_int16_t(payload, 0)); if(len + sizeof(len) != packet->payload_packet_len) { /*fragmented packets are not handled*/ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } else { ndpi_rtp_search(ndpi_struct, flow); } @@ -396,12 +511,12 @@ static void ndpi_search_rtp_tcp(struct ndpi_detection_module_struct *ndpi_struct /* *************************************************************** */ static void ndpi_search_rtp_udp(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int16_t source = ntohs(packet->udp->source); u_int16_t dest = ntohs(packet->udp->dest); - /* + /* * XXX: not sure if rtp/rtcp over tcp will also mix with Ethereum * for now, will not add it unitl we have a false positive. */ @@ -410,8 +525,7 @@ static void ndpi_search_rtp_udp(struct ndpi_detection_module_struct *ndpi_struct || (dest == 5353 /* MDNS_PORT */) || (dest == 9600 /* FINS_PORT */) || (dest <= 1023)){ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_RTCP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ndpi_rtp_search(ndpi_struct, flow); @@ -423,21 +537,16 @@ static void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, st struct ndpi_packet_struct *packet = &ndpi_struct->packet; if(packet->tcp != NULL) { ndpi_search_rtp_tcp(ndpi_struct, flow); - } else { - ndpi_search_rtp_udp(ndpi_struct, flow); - } + } else { + ndpi_search_rtp_udp(ndpi_struct, flow); + } } /* *************************************************************** */ -void init_rtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("RTP", ndpi_struct, *id, - NDPI_PROTOCOL_RTP, - ndpi_search_rtp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_rtp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("RT(C)P", ndpi_struct, + ndpi_search_rtp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 2, NDPI_PROTOCOL_RTP, NDPI_PROTOCOL_RTCP); } diff --git a/src/lib/protocols/rtps.c b/src/lib/protocols/rtps.c index 574642df5..930872b9d 100644 --- a/src/lib/protocols/rtps.c +++ b/src/lib/protocols/rtps.c @@ -57,18 +57,13 @@ static void ndpi_search_rtps(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_rtps_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rtps_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RTPS", ndpi_struct, *id, - NDPI_PROTOCOL_RTPS, - ndpi_search_rtps, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("RTPS", ndpi_struct, + ndpi_search_rtps, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RTPS); } diff --git a/src/lib/protocols/rtsp.c b/src/lib/protocols/rtsp.c index 014553b5b..d5b418232 100644 --- a/src/lib/protocols/rtsp.c +++ b/src/lib/protocols/rtsp.c @@ -2,7 +2,7 @@ * rtsp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -33,6 +33,7 @@ static void ndpi_int_rtsp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + NDPI_LOG_INFO(ndpi_struct, "found RTSP\n"); ndpi_set_detected_protocol_keeping_master(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, NDPI_CONFIDENCE_DPI); } @@ -52,8 +53,10 @@ static void ndpi_search_rtsp_tcp_udp(struct ndpi_detection_module_struct *ndpi_s if (packet->parsed_lines > 0 && (LINE_ENDS(packet->line[0], "RTSP/1.0") != 0 || + LINE_STARTS(packet->line[0], "RTSP/1.0") != 0 || /* Response */ LINE_ENDS(packet->accept_line, "application/x-rtsp-tunnelled") != 0 || - LINE_ENDS(packet->content_line, "application/x-rtsp-tunnelled") != 0)) + LINE_ENDS(packet->content_line, "application/x-rtsp-tunnelled") != 0 + /* Should we also check for "rtsp://" in the packet? */)) { ndpi_int_rtsp_add_connection(ndpi_struct, flow); @@ -64,59 +67,14 @@ static void ndpi_search_rtsp_tcp_udp(struct ndpi_detection_module_struct *ndpi_s return; } - if (flow->rtsprdt_stage == 0 - && !(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_RTCP) - ) { - flow->rtsprdt_stage = 1 + packet->packet_direction; - NDPI_LOG_DBG2(ndpi_struct, "maybe handshake 1; need next packet, return\n"); - return; - } - - if (flow->packet_counter < 3 && flow->rtsprdt_stage == 1 + packet->packet_direction) { - - NDPI_LOG_DBG2(ndpi_struct, "maybe handshake 2; need next packet\n"); - return; - } - - if (packet->payload_packet_len > 20 && flow->rtsprdt_stage == 2 - packet->packet_direction) { - char buf[32] = { 0 }; - u_int len = packet->payload_packet_len; - - if(len >= (sizeof(buf)-1)) len = sizeof(buf)-1; - strncpy(buf, (const char*)packet->payload, len); - - // RTSP Server Message - if((memcmp(packet->payload, "RTSP/1.0 ", 9) == 0) - || (strstr(buf, "rtsp://") != NULL)) { - NDPI_LOG_DBG2(ndpi_struct, "found RTSP/1.0 \n"); - NDPI_LOG_INFO(ndpi_struct, "found RTSP\n"); - ndpi_int_rtsp_add_connection(ndpi_struct, flow); - return; - } - } - - if (packet->udp != NULL && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN - && ((NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP) == 0) - || (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP) == 0) - )) { - NDPI_LOG_DBG2(ndpi_struct, - "maybe RTSP RTP, RTSP RTCP, RDT; need next packet.\n"); - return; - } - - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_rtsp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_rtsp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RTSP", ndpi_struct, *id, - NDPI_PROTOCOL_RTSP, - ndpi_search_rtsp_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("RTSP", ndpi_struct, + ndpi_search_rtsp_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_RTSP); } diff --git a/src/lib/protocols/rx.c b/src/lib/protocols/rx.c index dcb040534..d84872511 100644 --- a/src/lib/protocols/rx.c +++ b/src/lib/protocols/rx.c @@ -88,7 +88,7 @@ static void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, /* Check that packet is long enough */ if (payload_len < sizeof(struct ndpi_rx_header)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -111,7 +111,7 @@ static void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, /* TYPE field */ if((header->type < RX_DATA) || (header->type > RX_VERS)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -164,11 +164,11 @@ static void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, case RX_VERS: goto security; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // switch } else { // FLAG - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -176,7 +176,7 @@ static void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, /* SECURITY field */ if(header->security > 3) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -194,7 +194,7 @@ static void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, /* https://www.central.org/frameless/numbers/rxservice.html. */ else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } else { @@ -212,16 +212,11 @@ static void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, } } -void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("RX", ndpi_struct, *id, - NDPI_PROTOCOL_RX, - ndpi_search_rx, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("RX", ndpi_struct, + ndpi_search_rx, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_RX); } diff --git a/src/lib/protocols/s7comm.c b/src/lib/protocols/s7comm.c index 9efbb89d5..475be9aef 100644 --- a/src/lib/protocols/s7comm.c +++ b/src/lib/protocols/s7comm.c @@ -65,16 +65,13 @@ static void ndpi_search_s7comm(struct ndpi_detection_module_struct *ndpi_struct, return;
}
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
}
-void init_s7comm_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id)
+void init_s7comm_dissector(struct ndpi_detection_module_struct *ndpi_struct)
{
- ndpi_set_bitmask_protocol_detection("S7Comm", ndpi_struct, *id,
- NDPI_PROTOCOL_S7COMM,
- ndpi_search_s7comm,
- NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
- SAVE_DETECTION_BITMASK_AS_UNKNOWN,
- ADD_TO_DETECTION_BITMASK);
- *id += 1;
+ register_dissector("S7Comm", ndpi_struct,
+ ndpi_search_s7comm,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ 1, NDPI_PROTOCOL_S7COMM);
}
diff --git a/src/lib/protocols/sd_rtn.c b/src/lib/protocols/sd_rtn.c index a40eb6240..3c4313d3f 100644 --- a/src/lib/protocols/sd_rtn.c +++ b/src/lib/protocols/sd_rtn.c @@ -1,7 +1,7 @@ /* * sd_rtn.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -80,19 +80,14 @@ static void ndpi_search_sd_rtn(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_sd_rtn_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_sd_rtn_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SD-RTN", ndpi_struct, *id, - NDPI_PROTOCOL_SD_RTN, - ndpi_search_sd_rtn, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SD-RTN", ndpi_struct, + ndpi_search_sd_rtn, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SD_RTN); } diff --git a/src/lib/protocols/sflow.c b/src/lib/protocols/sflow.c index d731f2146..e273672a4 100644 --- a/src/lib/protocols/sflow.c +++ b/src/lib/protocols/sflow.c @@ -1,7 +1,7 @@ /* * sflow.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -52,18 +52,14 @@ static void ndpi_search_sflow(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_sflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_sflow_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("sFlow", ndpi_struct, *id, - NDPI_PROTOCOL_SFLOW, - ndpi_search_sflow, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("sFlow", ndpi_struct, + ndpi_search_sflow, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SFLOW); } diff --git a/src/lib/protocols/sip.c b/src/lib/protocols/sip.c index 31166a175..42be61b51 100644 --- a/src/lib/protocols/sip.c +++ b/src/lib/protocols/sip.c @@ -2,7 +2,7 @@ * sip.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -236,7 +236,7 @@ static void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, st NDPI_LOG_DBG(ndpi_struct, "Searching for SIP\n"); if(flow->packet_counter >= 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -251,7 +251,7 @@ static void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, st } if(!isprint(packet_payload[0])) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -273,14 +273,10 @@ static void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, st /* ********************************************************** */ -void init_sip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("SIP", ndpi_struct, *id, - NDPI_PROTOCOL_SIP, - ndpi_search_sip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,/* Fix courtesy of Miguel Quesada <mquesadab@gmail.com> */ - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_sip_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("SIP", ndpi_struct, + ndpi_search_sip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SIP); } diff --git a/src/lib/protocols/skinny.c b/src/lib/protocols/skinny.c index b011684c7..8462ae0fb 100644 --- a/src/lib/protocols/skinny.c +++ b/src/lib/protocols/skinny.c @@ -87,18 +87,14 @@ static void ndpi_search_skinny(struct ndpi_detection_module_struct *ndpi_struct, } } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_skinny_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_skinny_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("CiscoSkinny", ndpi_struct, *id, - NDPI_PROTOCOL_SKINNY, - ndpi_search_skinny, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("CiscoSkinny", ndpi_struct, + ndpi_search_skinny, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SKINNY); } diff --git a/src/lib/protocols/slp.c b/src/lib/protocols/slp.c index 81c1cabd9..7a0165d81 100644 --- a/src/lib/protocols/slp.c +++ b/src/lib/protocols/slp.c @@ -101,7 +101,7 @@ static int slp_check_packet_length(struct ndpi_detection_module_struct *ndpi_str struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; if (packet->payload_packet_len != packet_length) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } @@ -113,25 +113,25 @@ static int slp_check_fid(struct ndpi_detection_module_struct *ndpi_struct, enum function_id fid, uint8_t slp_version) { if (fid <= FID_UNKNOWN) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } switch (slp_version) { case 0x01: if (fid >= FID_MAX_v1) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } break; case 0x02: if (fid >= FID_MAX) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } @@ -199,7 +199,7 @@ static void ndpi_search_slp_v1(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search Service Location Protocol v1\n"); if (packet->payload_packet_len < sizeof(*hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -222,7 +222,7 @@ static int ndpi_search_slp_v2(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search Service Location Protocol v2\n"); if (packet->payload_packet_len < sizeof(*hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return 1; } @@ -316,20 +316,15 @@ static void ndpi_search_slp(struct ndpi_detection_module_struct *ndpi_struct, } break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); break; } } -void init_slp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_slp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Service_Location_Protocol", ndpi_struct, *id, - NDPI_PROTOCOL_SERVICE_LOCATION, - ndpi_search_slp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Service_Location_Protocol", ndpi_struct, + ndpi_search_slp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SERVICE_LOCATION); } diff --git a/src/lib/protocols/smb.c b/src/lib/protocols/smb.c index 3997c7aac..c9bf9472a 100644 --- a/src/lib/protocols/smb.c +++ b/src/lib/protocols/smb.c @@ -76,19 +76,14 @@ static void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct } } - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_SMBV1); - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_SMBV23); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_smb_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_smb_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SMB", ndpi_struct, *id, - NDPI_PROTOCOL_SMBV23, - ndpi_search_smb_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SMB", ndpi_struct, + ndpi_search_smb_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SMBV23); } diff --git a/src/lib/protocols/smpp.c b/src/lib/protocols/smpp.c index 6ab09e98e..0435d169a 100644 --- a/src/lib/protocols/smpp.c +++ b/src/lib/protocols/smpp.c @@ -48,7 +48,7 @@ static void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struc if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_SMPP){ // min SMPP packet length = 16 bytes if (packet->payload_packet_len < 16) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // get PDU length @@ -60,7 +60,7 @@ static void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struc // if PDU size was invalid, try the following TCP segments, 3 attempts max if(flow->packet_counter > 3) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // verify PDU length @@ -100,7 +100,7 @@ static void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struc u_int32_t pdu_type = ntohl(get_u_int32_t(packet->payload, 4)); // first byte of PDU type is either 0x00 of 0x80 if(!(packet->payload[4] == 0x00 || packet->payload[4] == 0x80)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } // remove 0x80, get request type pdu @@ -305,20 +305,15 @@ static void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_smpp_dissector(struct ndpi_detection_module_struct* ndpi_struct, - u_int32_t* id) +void init_smpp_dissector(struct ndpi_detection_module_struct* ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SMPP", ndpi_struct, *id, - NDPI_PROTOCOL_SMPP, - ndpi_search_smpp_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SMPP", ndpi_struct, + ndpi_search_smpp_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SMPP); } diff --git a/src/lib/protocols/snmp_proto.c b/src/lib/protocols/snmp_proto.c index 75e829126..dde4d6aa5 100644 --- a/src/lib/protocols/snmp_proto.c +++ b/src/lib/protocols/snmp_proto.c @@ -1,7 +1,7 @@ /* * snmp.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -64,7 +64,7 @@ static void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, (packet->udp->dest != snmp_port) && (packet->udp->source != trap_port) && (packet->udp->dest != trap_port)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -141,18 +141,13 @@ static void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_snmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("SNMP", ndpi_struct, *id, - NDPI_PROTOCOL_SNMP, - ndpi_search_snmp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_snmp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("SNMP", ndpi_struct, + ndpi_search_snmp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SNMP); } diff --git a/src/lib/protocols/soap.c b/src/lib/protocols/soap.c index 96b1ead71..849e0dc90 100644 --- a/src/lib/protocols/soap.c +++ b/src/lib/protocols/soap.c @@ -66,7 +66,7 @@ static void ndpi_search_soap(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_soap_add_connection(ndpi_struct, flow); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } @@ -80,12 +80,11 @@ static void ndpi_search_soap(struct ndpi_detection_module_struct *ndpi_struct, } } -void init_soap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_soap_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection( - "SOAP", ndpi_struct, *id, - NDPI_PROTOCOL_SOAP, ndpi_search_soap, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("SOAP", ndpi_struct, + ndpi_search_soap, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SOAP); } diff --git a/src/lib/protocols/socks45.c b/src/lib/protocols/socks45.c index 78a744087..b17851f97 100644 --- a/src/lib/protocols/socks45.c +++ b/src/lib/protocols/socks45.c @@ -41,7 +41,7 @@ static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t payload_len = packet->payload_packet_len; /* Check if we so far detected the protocol in the request or not. */ - if(flow->socks4_stage == 0) { + if(flow->l4.tcp.socks4_stage == 0) { NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage 0: \n"); if(payload_len >= 9 && packet->payload[0] == 0x04 && @@ -50,13 +50,13 @@ static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS4 request detected, we will look further for the response\n"); /* TODO: check port and ip address is valid */ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->socks4_stage = packet->packet_direction + 1; + flow->l4.tcp.socks4_stage = packet->packet_direction + 1; } } else { - NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage %u: \n", flow->socks4_stage); + NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage %u: \n", flow->l4.tcp.socks4_stage); /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ - if((flow->socks4_stage - packet->packet_direction) == 1) { + if((flow->l4.tcp.socks4_stage - packet->packet_direction) == 1) { return; } /* This is a packet in another direction. Check if we find the proper response. */ @@ -65,7 +65,7 @@ static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_socks_add_connection(ndpi_struct, flow); } else { NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS4, resetting the stage to 0\n"); - flow->socks4_stage = 0; + flow->l4.tcp.socks4_stage = 0; } } } @@ -76,7 +76,7 @@ static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t payload_len = packet->payload_packet_len; /* Check if we so far detected the protocol in the request or not. */ - if(flow->socks5_stage == 0) { + if(flow->l4.tcp.socks5_stage == 0) { NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage 0: \n"); if(((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) || @@ -84,14 +84,14 @@ static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS5 request detected, we will look further for the response\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->socks5_stage = packet->packet_direction + 1; + flow->l4.tcp.socks5_stage = packet->packet_direction + 1; } } else { - NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage %u: \n", flow->socks5_stage); + NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage %u: \n", flow->l4.tcp.socks5_stage); /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ - if((flow->socks5_stage - packet->packet_direction) == 1) { + if((flow->l4.tcp.socks5_stage - packet->packet_direction) == 1) { return; } @@ -101,7 +101,7 @@ static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_socks_add_connection(ndpi_struct, flow); } else { NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS5, resetting the stage to 0\n"); - flow->socks5_stage = 0; + flow->l4.tcp.socks5_stage = 0; } } @@ -112,7 +112,7 @@ static void ndpi_search_socks(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search SOCKS\n"); if(flow->packet_counter >= 10) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -122,15 +122,11 @@ static void ndpi_search_socks(struct ndpi_detection_module_struct *ndpi_struct, ndpi_check_socks5(ndpi_struct, flow); } -void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SOCKS", ndpi_struct, *id, - NDPI_PROTOCOL_SOCKS, - ndpi_search_socks, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SOCKS", ndpi_struct, + ndpi_search_socks, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SOCKS); } diff --git a/src/lib/protocols/softether.c b/src/lib/protocols/softether.c index d0ad8b492..379e743f7 100644 --- a/src/lib/protocols/softether.c +++ b/src/lib/protocols/softether.c @@ -304,7 +304,7 @@ static void ndpi_search_softether(struct ndpi_detection_module_struct *ndpi_stru if(packet->payload_packet_len == 1) { if((packet->payload[0] != 0x41) || (flow->packet_counter > 2)) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -323,7 +323,7 @@ static void ndpi_search_softether(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************** */ @@ -347,15 +347,9 @@ static int ndpi_search_softether_again(struct ndpi_detection_module_struct *ndpi /* ***************************************************** */ -void init_softether_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Softether", ndpi_struct, *id, - NDPI_PROTOCOL_SOFTETHER, - ndpi_search_softether, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; +void init_softether_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Softether", ndpi_struct, + ndpi_search_softether, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SOFTETHER); } diff --git a/src/lib/protocols/someip.c b/src/lib/protocols/someip.c index c2e4ee330..0d17524d1 100644 --- a/src/lib/protocols/someip.c +++ b/src/lib/protocols/someip.c @@ -101,7 +101,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 16) { NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP .. mandatory header not found (not enough data for all fields)\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -122,7 +122,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t someip_len = ntohl(someip_data_cover_32(&packet->payload[4])); if (packet->payload_packet_len != (someip_len + 8)) { NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP .. Length field invalid!\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -130,7 +130,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct,"====>>>> SOME/IP protocol version: [%d]\n",protocol_version); if (protocol_version != LEGAL_PROTOCOL_VERSION){ NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP .. invalid protocol version!\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -144,7 +144,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, (message_type != SOMEIP_REQUEST_NO_RETURN_ACK) && (message_type != SOMEIP_NOTIFICATION_ACK) && (message_type != SOMEIP_RESPONSE) && (message_type != SOMEIP_ERROR) && (message_type != SOMEIP_RESPONSE_ACK) && (message_type != SOMEIP_ERROR_ACK)) { NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP .. invalid message type!\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -152,7 +152,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct,"====>>>> SOME/IP return code: [%d]\n", return_code); if ((return_code >= E_RETURN_CODE_LEGAL_THRESHOLD)) { NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP .. invalid return code!\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -165,7 +165,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, } else{ NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP, invalid header for Magic Cookie\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -179,7 +179,7 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, } else{ NDPI_LOG_DBG(ndpi_struct, "Excluding SOME/IP, invalid header for Magic Cookie ACK\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOMEIP); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -193,15 +193,12 @@ static void ndpi_search_someip(struct ndpi_detection_module_struct *ndpi_struct, /** * Entry point for the ndpi library */ -void init_someip_dissector (struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_someip_dissector (struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection ("SOME/IP", ndpi_struct, *id, - NDPI_PROTOCOL_SOMEIP, - ndpi_search_someip, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - *id +=1; + register_dissector("SOME/IP", ndpi_struct, + ndpi_search_someip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SOMEIP); } diff --git a/src/lib/protocols/sonos.c b/src/lib/protocols/sonos.c index c203f2be9..dca0ac874 100644 --- a/src/lib/protocols/sonos.c +++ b/src/lib/protocols/sonos.c @@ -57,17 +57,14 @@ void ndpi_search_sonos(struct ndpi_detection_module_struct *ndpi_struct, struct } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_sonos_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_sonos_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Sonos", ndpi_struct, *id, - NDPI_PROTOCOL_SONOS, - ndpi_search_sonos, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Only IPv4 UDP traffic is expected. */ - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Sonos", ndpi_struct, + ndpi_search_sonos, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Only IPv4 UDP traffic is expected. */ + 1, NDPI_PROTOCOL_SONOS); } diff --git a/src/lib/protocols/source_engine.c b/src/lib/protocols/source_engine.c index 8d92f537e..96d285a07 100644 --- a/src/lib/protocols/source_engine.c +++ b/src/lib/protocols/source_engine.c @@ -1,7 +1,7 @@ /* * source_engine.c * - * Source Engine Protocol + * Source Engine Protocol (Valve’s A2S protocol) * * Copyright (C) 2023 - ntop.org * @@ -45,45 +45,59 @@ static void ndpi_search_source_engine(struct ndpi_detection_module_struct *ndpi_ struct ndpi_flow_struct *flow) { struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; - char const source_engine_query[] = "Source Engine Query"; - size_t const source_engine_query_len = strlen(source_engine_query); NDPI_LOG_DBG(ndpi_struct, "search Source Engine\n"); - if (packet->payload_packet_len < source_engine_query_len + 1 /* '\0' */) - { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } + /* https://developer.valvesoftware.com/wiki/Server_queries */ - if (packet->payload[packet->payload_packet_len - 1] != '\0') + /* A2S request */ + if (current_pkt_from_client_to_server(ndpi_struct, flow) && + (packet->payload_packet_len > 8 && packet->payload_packet_len < 30) && + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + if (packet->payload[4] == 'T' || /* A2S_INFO */ + packet->payload[4] == 'U' || /* A2S_PLAYER */ + packet->payload[4] == 'V') /* A2S_RULES */ + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } } - if (strncmp((char const *)&packet->payload[packet->payload_packet_len - source_engine_query_len - 1], - source_engine_query, source_engine_query_len) != 0) + /* A2S response */ + if (current_pkt_from_server_to_client(ndpi_struct, flow)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + /* Challenge response */ + if (packet->payload_packet_len == 9 && + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF && + packet->payload[4] == 'A') + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload_packet_len > 30 && /* A reasonable length for euristics */ + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF) + { + if (packet->payload[4] == 'I' || /* A2S_INFO */ + packet->payload[4] == 'D' || /* A2S_PLAYER */ + packet->payload[4] == 'E') /* A2S_RULES */ + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } + } } - ndpi_int_source_engine_add_connection(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************** */ -void init_source_engine_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_source_engine_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Source_Engine", ndpi_struct, *id, - NDPI_PROTOCOL_SOURCE_ENGINE, - ndpi_search_source_engine, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Source_Engine", ndpi_struct, + ndpi_search_source_engine, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SOURCE_ENGINE); } diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c index 7f40ca6dc..4dc6f09b2 100644 --- a/src/lib/protocols/spotify.c +++ b/src/lib/protocols/spotify.c @@ -65,7 +65,7 @@ static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) @@ -76,15 +76,11 @@ static void ndpi_search_spotify(struct ndpi_detection_module_struct *ndpi_struct } -void init_spotify_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_spotify_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SPOTIFY", ndpi_struct, *id, - NDPI_PROTOCOL_SPOTIFY, - ndpi_search_spotify, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SPOTIFY", ndpi_struct, + ndpi_search_spotify, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SPOTIFY); } diff --git a/src/lib/protocols/ssdp.c b/src/lib/protocols/ssdp.c index 90ce4c04c..e45e84911 100644 --- a/src/lib/protocols/ssdp.c +++ b/src/lib/protocols/ssdp.c @@ -2,7 +2,7 @@ * ssdp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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,9 +29,16 @@ #include "ndpi_api.h" #include "ndpi_private.h" +static struct SSDP { + const char *detection_line; + const char *method; +} SSDP_METHODS[] = { + { "M-SEARCH * HTTP/1.1", "M-SEARCH" }, + { "NOTIFY * HTTP/1.1", "NOTIFY" } +}; static void ssdp_parse_lines(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) + *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; @@ -40,21 +47,174 @@ static void ssdp_parse_lines(struct ndpi_detection_module_struct /* Save user-agent for device discovery if available */ if(packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 0) { if (ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len) == NULL) - { - NDPI_LOG_DBG2(ndpi_struct, "Could not set SSDP user agent\n"); - } + { + NDPI_LOG_DBG2(ndpi_struct, "Could not set SSDP user agent\n"); + } } /* Save host which provides a service if available */ if (packet->host_line.ptr != NULL && packet->host_line.len > 0) { ndpi_hostname_sni_set(flow, packet->host_line.ptr, packet->host_line.len, NDPI_HOSTNAME_NORM_ALL); } + + if (packet->bootid.ptr != NULL && packet->bootid.len > 0) { + flow->protos.ssdp.bootid = ndpi_malloc(packet->bootid.len + 1); + if (flow->protos.ssdp.bootid) { + memcpy(flow->protos.ssdp.bootid, packet->bootid.ptr, packet->bootid.len); + flow->protos.ssdp.bootid[packet->bootid.len] = '\0'; + } + } + + if (packet->usn.ptr != NULL && packet->usn.len > 0) { + flow->protos.ssdp.usn = ndpi_malloc(packet->usn.len + 1); + if (flow->protos.ssdp.usn) { + memcpy(flow->protos.ssdp.usn, packet->usn.ptr, packet->usn.len); + flow->protos.ssdp.usn[packet->usn.len] = '\0'; + } + } + + if (packet->cache_controle.ptr != NULL && packet->cache_controle.len > 0) { + flow->protos.ssdp.cache_controle = ndpi_malloc(packet->cache_controle.len + 1); + if (flow->protos.ssdp.cache_controle) { + memcpy(flow->protos.ssdp.cache_controle, packet->cache_controle.ptr, packet->cache_controle.len); + flow->protos.ssdp.cache_controle[packet->cache_controle.len] = '\0'; + } + } + + if (packet->location.ptr != NULL && packet->location.len > 0) { + flow->protos.ssdp.location = ndpi_malloc(packet->location.len + 1); + if (flow->protos.ssdp.location) { + memcpy(flow->protos.ssdp.location, packet->location.ptr, packet->location.len); + flow->protos.ssdp.location[packet->location.len] = '\0'; + } + } + + if (packet->household_smart_speaker_audio.ptr != NULL && packet->household_smart_speaker_audio.len > 0) { + flow->protos.ssdp.household_smart_speaker_audio = ndpi_malloc(packet->household_smart_speaker_audio.len + 1); + if (flow->protos.ssdp.household_smart_speaker_audio) { + memcpy(flow->protos.ssdp.household_smart_speaker_audio, packet->household_smart_speaker_audio.ptr, packet->household_smart_speaker_audio.len); + flow->protos.ssdp.household_smart_speaker_audio[packet->household_smart_speaker_audio.len] = '\0'; + } + } + + if (packet->rincon_household.ptr != NULL && packet->rincon_household.len > 0) { + flow->protos.ssdp.rincon_household = ndpi_malloc(packet->rincon_household.len + 1); + if (flow->protos.ssdp.rincon_household) { + memcpy(flow->protos.ssdp.rincon_household, packet->rincon_household.ptr, packet->rincon_household.len); + flow->protos.ssdp.rincon_household[packet->rincon_household.len] = '\0'; + } + } + + if (packet->rincon_bootseq.ptr != NULL && packet->rincon_bootseq.len > 0) { + flow->protos.ssdp.rincon_bootseq = ndpi_malloc(packet->rincon_bootseq.len + 1); + if (flow->protos.ssdp.rincon_bootseq) { + memcpy(flow->protos.ssdp.rincon_bootseq, packet->rincon_bootseq.ptr, packet->rincon_bootseq.len); + flow->protos.ssdp.rincon_bootseq[packet->rincon_bootseq.len] = '\0'; + } + } + + if (packet->rincon_wifimode.ptr != NULL && packet->rincon_wifimode.len > 0) { + flow->protos.ssdp.rincon_wifimode = ndpi_malloc(packet->rincon_wifimode.len + 1); + if (flow->protos.ssdp.rincon_wifimode) { + memcpy(flow->protos.ssdp.rincon_wifimode, packet->rincon_wifimode.ptr, packet->rincon_wifimode.len); + flow->protos.ssdp.rincon_wifimode[packet->rincon_wifimode.len] = '\0'; + } + } + + if (packet->rincon_variant.ptr != NULL && packet->rincon_variant.len > 0) { + flow->protos.ssdp.rincon_variant = ndpi_malloc(packet->rincon_variant.len + 1); + if (flow->protos.ssdp.rincon_variant) { + memcpy(flow->protos.ssdp.rincon_variant, packet->rincon_variant.ptr, packet->rincon_variant.len); + flow->protos.ssdp.rincon_variant[packet->rincon_variant.len] = '\0'; + } + } + + if (packet->sonos_securelocation.ptr != NULL && packet->sonos_securelocation.len > 0) { + flow->protos.ssdp.sonos_securelocation = ndpi_malloc(packet->sonos_securelocation.len + 1); + if (flow->protos.ssdp.sonos_securelocation) { + memcpy(flow->protos.ssdp.sonos_securelocation, packet->sonos_securelocation.ptr, packet->sonos_securelocation.len); + flow->protos.ssdp.sonos_securelocation[packet->sonos_securelocation.len] = '\0'; + } + } + + if (packet->securelocation_upnp.ptr != NULL && packet->securelocation_upnp.len > 0) { + flow->protos.ssdp.securelocation_upnp = ndpi_malloc(packet->securelocation_upnp.len + 1); + if (flow->protos.ssdp.securelocation_upnp) { + memcpy(flow->protos.ssdp.securelocation_upnp, packet->securelocation_upnp.ptr, packet->securelocation_upnp.len); + flow->protos.ssdp.securelocation_upnp[packet->securelocation_upnp.len] = '\0'; + } + } + + if (packet->location_smart_speaker_audio.ptr != NULL && packet->location_smart_speaker_audio.len > 0) { + flow->protos.ssdp.location_smart_speaker_audio = ndpi_malloc(packet->location_smart_speaker_audio.len + 1); + if (flow->protos.ssdp.location_smart_speaker_audio) { + memcpy(flow->protos.ssdp.location_smart_speaker_audio, packet->location_smart_speaker_audio.ptr, packet->location_smart_speaker_audio.len); + flow->protos.ssdp.location_smart_speaker_audio[packet->location_smart_speaker_audio.len] = '\0'; + } + } + + if (packet->nt.ptr != NULL && packet->nt.len > 0) { + flow->protos.ssdp.nt = ndpi_malloc(packet->nt.len + 1); + if (flow->protos.ssdp.nt) { + memcpy(flow->protos.ssdp.nt, packet->nt.ptr, packet->nt.len); + flow->protos.ssdp.nt[packet->nt.len] = '\0'; + } + } + + if (packet->nts.ptr != NULL && packet->nts.len > 0) { + flow->protos.ssdp.nts = ndpi_malloc(packet->nts.len + 1); + if (flow->protos.ssdp.nts) { + memcpy(flow->protos.ssdp.nts, packet->nts.ptr, packet->nts.len); + flow->protos.ssdp.nts[packet->nts.len] = '\0'; + } + } + + if (packet->server_line.ptr != NULL && packet->server_line.len > 0) { + flow->protos.ssdp.server = ndpi_malloc(packet->server_line.len + 1); + if (flow->protos.ssdp.server) { + memcpy(flow->protos.ssdp.server, packet->server_line.ptr, packet->server_line.len); + flow->protos.ssdp.server[packet->server_line.len] = '\0'; + } + } + + if (packet->man.ptr != NULL && packet->man.len > 0) { + flow->protos.ssdp.man = ndpi_malloc(packet->man.len + 1); + if (flow->protos.ssdp.man) { + memcpy(flow->protos.ssdp.man, packet->man.ptr, packet->man.len); + flow->protos.ssdp.man[packet->man.len] = '\0'; + } + } + + if (packet->mx.ptr != NULL && packet->mx.len > 0) { + flow->protos.ssdp.mx = ndpi_malloc(packet->mx.len + 1); + if (flow->protos.ssdp.mx) { + memcpy(flow->protos.ssdp.mx, packet->mx.ptr, packet->mx.len); + flow->protos.ssdp.mx[packet->mx.len] = '\0'; + } + } + + if (packet->st.ptr != NULL && packet->st.len > 0) { + flow->protos.ssdp.st = ndpi_malloc(packet->st.len + 1); + if (flow->protos.ssdp.st) { + memcpy(flow->protos.ssdp.st, packet->st.ptr, packet->st.len); + flow->protos.ssdp.st[packet->st.len] = '\0'; + } + } + + if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 0) { + flow->protos.ssdp.user_agent = ndpi_malloc(packet->user_agent_line.len + 1); + if (flow->protos.ssdp.user_agent) { + memcpy(flow->protos.ssdp.user_agent, packet->user_agent_line.ptr, packet->user_agent_line.len); + flow->protos.ssdp.user_agent[packet->user_agent_line.len] = '\0'; + } + } } static void ndpi_int_ssdp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - ssdp_parse_lines(ndpi_struct, flow); + if(ndpi_struct->cfg.ssdp_metadata_enabled) + ssdp_parse_lines(ndpi_struct, flow); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSDP, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } @@ -62,18 +222,28 @@ static void ndpi_int_ssdp_add_connection(struct ndpi_detection_module_struct static void ndpi_search_ssdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; - + NDPI_LOG_DBG(ndpi_struct, "search ssdp\n"); - if (packet->udp != NULL) { + if (packet->udp != NULL) { if (packet->payload_packet_len >= 19) { - if ((memcmp(packet->payload, "M-SEARCH * HTTP/1.1", 19) == 0) - || memcmp(packet->payload, "NOTIFY * HTTP/1.1", 17) == 0) { + unsigned int i; + for (i=0; i < sizeof(SSDP_METHODS)/sizeof(SSDP_METHODS[0]); i++) { + if(memcmp(packet->payload, SSDP_METHODS[i].detection_line, strlen(SSDP_METHODS[i].detection_line)) == 0) { + if(ndpi_struct->cfg.ssdp_metadata_enabled) { + flow->protos.ssdp.method = ndpi_malloc(strlen(SSDP_METHODS[i].detection_line) + 1); - NDPI_LOG_INFO(ndpi_struct, "found ssdp\n"); - ndpi_int_ssdp_add_connection(ndpi_struct, flow); - return; + if (flow->protos.ssdp.method) { + memcpy(flow->protos.ssdp.method, SSDP_METHODS[i].method, strlen(SSDP_METHODS[i].method)); + flow->protos.ssdp.method[strlen(SSDP_METHODS[i].method)] = '\0'; + } + } + + NDPI_LOG_INFO(ndpi_struct, "found ssdp\n"); + ndpi_int_ssdp_add_connection(ndpi_struct, flow); + return; + } } #define SSDP_HTTP "HTTP/1.1 200 OK\r\n" @@ -85,19 +255,14 @@ static void ndpi_search_ssdp(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ssdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ssdp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SSDP", ndpi_struct, *id, - NDPI_PROTOCOL_SSDP, - ndpi_search_ssdp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SSDP", ndpi_struct, + ndpi_search_ssdp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SSDP); } - diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index bdca8c059..b283493a3 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -1,7 +1,7 @@ /* * ssh.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -362,7 +362,6 @@ static u_int16_t concat_hash_string(struct ndpi_detection_module_struct *ndpi_st if(len > len_max) goto invalid_payload; - offset += len; /* ssh.languages_client_to_server [None] */ @@ -405,50 +404,45 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct printf("[SSH] %s()\n", __FUNCTION__); #endif - if(flow->l4.tcp.ssh_stage == 0) { - if(packet->payload_packet_len > 7 - && memcmp(packet->payload, "SSH-", 4) == 0) { - int len = ndpi_min(sizeof(flow->protos.ssh.client_signature)-1, packet->payload_packet_len); + if(flow->l4.tcp.ssh_stage <= 1) { + if(packet->payload_packet_len > 7 && memcmp(packet->payload, "SSH-", 4) == 0) { + if(current_pkt_from_client_to_server(ndpi_struct, flow)) { + int len = ndpi_min(sizeof(flow->protos.ssh.client_signature)-1, packet->payload_packet_len); - strncpy(flow->protos.ssh.client_signature, (const char *)packet->payload, len); - flow->protos.ssh.client_signature[len] = '\0'; - ndpi_ssh_zap_cr(flow->protos.ssh.client_signature, len); + strncpy(flow->protos.ssh.client_signature, (const char *)packet->payload, len); + flow->protos.ssh.client_signature[len] = '\0'; + ndpi_ssh_zap_cr(flow->protos.ssh.client_signature, len); - ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.client_signature, 1); + ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.client_signature, 1); #ifdef SSH_DEBUG - printf("[SSH] [client_signature: %s]\n", flow->protos.ssh.client_signature); + printf("[SSH] [client_signature: %s]\n", flow->protos.ssh.client_signature); #endif - NDPI_LOG_DBG2(ndpi_struct, "ssh stage 0 passed\n"); - flow->l4.tcp.ssh_stage = 1 + packet->packet_direction; - ndpi_int_ssh_add_connection(ndpi_struct, flow); - return; - } - } else if(flow->l4.tcp.ssh_stage == (2 - packet->packet_direction)) { - if(packet->payload_packet_len > 7 && packet->payload_packet_len < 500 - && memcmp(packet->payload, "SSH-", 4) == 0) { - int len = ndpi_min(sizeof(flow->protos.ssh.server_signature)-1, packet->payload_packet_len); + ndpi_int_ssh_add_connection(ndpi_struct, flow); + } else { + int len = ndpi_min(sizeof(flow->protos.ssh.server_signature)-1, packet->payload_packet_len); - strncpy(flow->protos.ssh.server_signature, (const char *)packet->payload, len); - flow->protos.ssh.server_signature[len] = '\0'; - ndpi_ssh_zap_cr(flow->protos.ssh.server_signature, len); + strncpy(flow->protos.ssh.server_signature, (const char *)packet->payload, len); + flow->protos.ssh.server_signature[len] = '\0'; + ndpi_ssh_zap_cr(flow->protos.ssh.server_signature, len); - ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.server_signature, 0); + ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.server_signature, 0); #ifdef SSH_DEBUG - printf("[SSH] [server_signature: %s]\n", flow->protos.ssh.server_signature); + printf("[SSH] [server_signature: %s]\n", flow->protos.ssh.server_signature); #endif - NDPI_LOG_DBG2(ndpi_struct, "ssh stage 1 passed\n"); - flow->fast_callback_protocol_id = NDPI_PROTOCOL_SSH; + NDPI_LOG_DBG2(ndpi_struct, "ssh stage 1 passed\n"); + flow->fast_callback_protocol_id = NDPI_PROTOCOL_SSH; #ifdef SSH_DEBUG - printf("[SSH] [completed stage: %u]\n", flow->l4.tcp.ssh_stage); + printf("[SSH] [completed stage: %u]\n", flow->l4.tcp.ssh_stage); #endif + } - flow->l4.tcp.ssh_stage = 3; - return; + flow->l4.tcp.ssh_stage++; + return; } } else if(packet->payload_packet_len > 5) { u_int8_t msgcode = *(packet->payload + 5); @@ -530,19 +524,15 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct #endif NDPI_LOG_DBG(ndpi_struct, "excluding ssh at stage %d\n", flow->l4.tcp.ssh_stage); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSH); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ************************************************************************ */ -void init_ssh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ssh_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SSH", ndpi_struct, *id, - NDPI_PROTOCOL_SSH, - ndpi_search_ssh_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SSH", ndpi_struct, + ndpi_search_ssh_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SSH); } diff --git a/src/lib/protocols/starcraft.c b/src/lib/protocols/starcraft.c deleted file mode 100644 index 9e87ea2c8..000000000 --- a/src/lib/protocols/starcraft.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -* starcraft.c -* -* Copyright (C) 2015 - Matteo Bracci <matteobracci1@gmail.com> -* Copyright (C) 2015-22 - 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 -* 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_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_STARCRAFT - -#include "ndpi_api.h" -#include "ndpi_private.h" - - -/* Sender or receiver are one of the known login portals? */ -static u_int8_t sc2_match_logon_ip(struct ndpi_packet_struct* packet) -{ - if (packet->iph == NULL) - return 0; - - u_int32_t source_ip = ntohl(packet->iph->saddr); - u_int32_t dest_ip = ntohl(packet->iph->daddr); - return (ndpi_ips_match(source_ip, dest_ip, 0xD5F87F82, 32) // EU 213.248.127.130 - || ndpi_ips_match(source_ip, dest_ip, 0x0C81CE82, 32) // US 12.129.206.130 - || ndpi_ips_match(source_ip, dest_ip, 0x79FEC882, 32) // KR 121.254.200.130 - || ndpi_ips_match(source_ip, dest_ip, 0xCA09424C, 32) // SG 202.9.66.76 - || ndpi_ips_match(source_ip, dest_ip, 0x0C81ECFE, 32)); // BETA 12.129.236.254 -} - -/* - The main TCP flow starts with the user login and stays alive until the logout. - Although hard to read, judging from what happens elsewhere this flow probably contains all the data - transfer generated by the user interaction with the client, e.g. chatting or looking at someone's - match history. The current way to detect this is plain dumb packet matching. -*/ -static u_int8_t ndpi_check_starcraft_tcp(struct ndpi_detection_module_struct* ndpi_struct) -{ - struct ndpi_packet_struct* packet = &ndpi_struct->packet; - - if (sc2_match_logon_ip(packet) - && packet->tcp->dest == htons(1119) //bnetgame port - && (ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") - || ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) - return 1; - else - return -1; -} - -/* - UPD traffic is the actual game data and it uses a port owned by Blizzard itself, 1119. Therefore the - real key point here is to make sure that it's actually Starcraft 2 that is using the port and not - some other Blizzard software. - The flow is taken if a pattern in the size of some subsequent packets is found. -*/ -static u_int8_t ndpi_check_starcraft_udp(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) -{ - struct ndpi_packet_struct* packet = &ndpi_struct->packet; - - /* First off, filter out any traffic not using port 1119, removing the chance of any false positive if we assume that non allowed protocols don't use the port */ - if (packet->udp->source != htons(1119) && packet->udp->dest != htons(1119)) - return -1; - - /* Then try to detect the size pattern */ - switch (flow->starcraft_udp_stage) - { - case 0: - if (packet->payload_packet_len == 20) - flow->starcraft_udp_stage = 1; - break; - case 1: - if (packet->payload_packet_len == 20) - flow->starcraft_udp_stage = 2; - break; - case 2: - if (packet->payload_packet_len == 75 || packet->payload_packet_len == 85) - flow->starcraft_udp_stage = 3; - break; - case 3: - if (packet->payload_packet_len == 20) - flow->starcraft_udp_stage = 4; - break; - case 4: - if (packet->payload_packet_len == 548) - flow->starcraft_udp_stage = 5; - break; - case 5: - if (packet->payload_packet_len == 548) - flow->starcraft_udp_stage = 6; - break; - case 6: - if (packet->payload_packet_len == 548) - flow->starcraft_udp_stage = 7; - break; - case 7: - if (packet->payload_packet_len == 484) - return 1; - break; - } - - return(0); -} - -static void ndpi_search_starcraft(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) -{ - struct ndpi_packet_struct* packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search Starcraft\n"); - if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_STARCRAFT) { - int8_t result = 0; - - if (packet->udp != NULL) { - result = ndpi_check_starcraft_udp(ndpi_struct, flow); - if (result == 1) { - NDPI_LOG_INFO(ndpi_struct, "Found Starcraft 2 [Game, UDP]\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STARCRAFT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - return; - } - } - else if (packet->tcp != NULL) { - result = ndpi_check_starcraft_tcp(ndpi_struct); - if (result == 1) { - NDPI_LOG_INFO(ndpi_struct, "Found Starcraft 2 [Client, TCP]\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STARCRAFT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - return; - } - } - - if (result == -1) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - } - } -} - -void init_starcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("Starcraft", ndpi_struct, *id, - NDPI_PROTOCOL_STARCRAFT, ndpi_search_starcraft, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c index 351279f59..1fd461d2a 100644 --- a/src/lib/protocols/steam.c +++ b/src/lib/protocols/steam.c @@ -1,7 +1,7 @@ /* * steam.c * - * Copyright (C) 2011-24 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> * * This file is part of nDPI, an open source deep packet inspection @@ -50,17 +50,13 @@ static void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, /* TODO: implement Steam Remote Play detection */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Steam", ndpi_struct, *id, - NDPI_PROTOCOL_STEAM, - ndpi_search_steam, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Steam", ndpi_struct, + ndpi_search_steam, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_STEAM); } diff --git a/src/lib/protocols/steam_datagram_relay.c b/src/lib/protocols/steam_datagram_relay.c index 6dafd6e97..5f1099f38 100644 --- a/src/lib/protocols/steam_datagram_relay.c +++ b/src/lib/protocols/steam_datagram_relay.c @@ -54,18 +54,13 @@ static void ndpi_search_valve_sdr(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_valve_sdr_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_valve_sdr_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("SteamDatagramRelay", ndpi_struct, *id, - NDPI_PROTOCOL_VALVE_SDR, - ndpi_search_valve_sdr, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("SteamDatagramRelay", ndpi_struct, + ndpi_search_valve_sdr, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_VALVE_SDR); } diff --git a/src/lib/protocols/stomp.c b/src/lib/protocols/stomp.c index 839d6f16f..3e8bdf9d8 100644 --- a/src/lib/protocols/stomp.c +++ b/src/lib/protocols/stomp.c @@ -62,16 +62,13 @@ static void ndpi_search_stomp(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_stomp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_stomp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("STOMP", ndpi_struct, *id, - NDPI_PROTOCOL_STOMP, - ndpi_search_stomp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("STOMP", ndpi_struct, + ndpi_search_stomp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_STOMP); } diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index d5015cc60..d9045fb20 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -1,7 +1,7 @@ /* * stun.c * - * Copyright (C) 2011-24 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -55,7 +55,8 @@ static u_int64_t get_stun_lru_key_raw6(u_int8_t *ip, u_int16_t port); static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t app_proto, - u_int16_t master_proto); + u_int16_t master_proto, + ndpi_protocol_category_t category); static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -354,8 +355,8 @@ static void parse_xor_ip_port_attribute(struct ndpi_detection_module_struct *ndp int is_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int16_t *app_proto) -{ + u_int16_t *app_proto, + ndpi_protocol_category_t *category) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int16_t msg_type, msg_len, method; int off; @@ -366,6 +367,8 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t magic_cookie; u_int32_t transaction_id[3]; + *category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED; + if(payload_length < STUN_HDR_LEN) return(-1); @@ -559,8 +562,8 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct, bool valid = true; ndpi_hostname_sni_set(flow, payload + off + 4, ndpi_min(len, payload_length - off - 4), NDPI_HOSTNAME_NORM_ALL); - NDPI_LOG_DBG(ndpi_struct, "Realm [%s]\n", flow->host_server_name); - + NDPI_LOG_DBG(ndpi_struct, "Realm [%s]\n", flow->host_server_name); + /* Some Realm contain junk, so let's validate it */ for(i=0; flow->host_server_name[i] != '\0'; i++) { if(flow->host_server_name[i] == '?') { @@ -578,11 +581,16 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct, } else if(strstr(flow->host_server_name, "facebook") != NULL) { *app_proto = NDPI_PROTOCOL_FACEBOOK_VOIP; } else if(strstr(flow->host_server_name, "stripcdn.com") != NULL) { - *app_proto = NDPI_PROTOCOL_ADULT_CONTENT; + *category = NDPI_PROTOCOL_CATEGORY_ADULT_CONTENT; } else if(strstr(flow->host_server_name, "telegram") != NULL) { *app_proto = NDPI_PROTOCOL_TELEGRAM_VOIP; } else if(strstr(flow->host_server_name, "viber") != NULL) { *app_proto = NDPI_PROTOCOL_VIBER_VOIP; + } else if(strstr(flow->host_server_name, "turn.cloudflare.com") != NULL) { + /* The latest signal implementations hide behind cloudflare */ + if(signal_search_into_cache(ndpi_struct, flow)) { + *app_proto = NDPI_PROTOCOL_SIGNAL_VOIP; + } } } else flow->host_server_name[0] = '\0'; @@ -828,10 +836,14 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_WHATSAPP_CALL && (msg_type == 0x0800 || msg_type == 0x0801 || msg_type == 0x0802 || msg_type == 0x0804 || msg_type == 0x0805))) { + ndpi_protocol_category_t category; + NDPI_LOG_DBG(ndpi_struct, "Still STUN\n"); - if(is_stun(ndpi_struct, flow, &app_proto) == 1) { /* To extract other metadata */ + + if(is_stun(ndpi_struct, flow, &app_proto, &category) == 1) { /* To extract other metadata */ if(is_new_subclassification_better(ndpi_struct, flow, app_proto)) { - ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto, __get_master(flow)); + ndpi_int_stun_add_connection(ndpi_struct, flow, + app_proto, __get_master(flow), category); } } } else if(first_byte <= 15) { @@ -881,8 +893,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, /* TODO: right way? It is a bit scary... do we need to reset something else too? */ reset_detected_protocol(flow); /* We keep the category related to STUN traffic */ - /* STUN often triggers this risk; clear it. TODO: clear other risks? */ - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + /* TODO: clear some risks? */ /* Give room for DTLS handshake, where we might have retransmissions and fragments */ @@ -900,7 +911,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "Keeping old subclassification %d\n", old_proto_stack[0]); ndpi_int_stun_add_connection(ndpi_struct, flow, old_proto_stack[0] == NDPI_PROTOCOL_RTP ? NDPI_PROTOCOL_SRTP : old_proto_stack[0], - __get_master(flow)); + __get_master(flow), NDPI_PROTOCOL_CATEGORY_UNSPECIFIED); } /* If this is not a real DTLS packet, we need to restore the old state */ @@ -961,14 +972,20 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, rtp_rtcp = is_rtp_or_rtcp(ndpi_struct, packet->payload, packet->payload_packet_len, NULL); if(rtp_rtcp == IS_RTP) { - NDPI_LOG_DBG(ndpi_struct, "RTP (dir %d) [%d/%d]\n", packet->packet_direction, flow->stun.rtp_counters[0], flow->stun.rtp_counters[1]); flow->stun.rtp_counters[packet->packet_direction]++; - + /* TODO: store RTP information in 'struct rtp_info' */ NDPI_LOG_INFO(ndpi_struct, "Found RTP over STUN\n"); + if(flow->stun.t_start != 0) { + flow->stun.t_end = ndpi_get_current_time(flow); + } else if(flow->stun.rtp_counters[0] != 0 && flow->stun.rtp_counters[1] != 0) { + flow->stun.t_start = ndpi_get_current_time(flow); + flow->stun.t_end = ndpi_get_current_time(flow); + } + rtp_get_stream_type(packet->payload[1] & 0x7F, &flow->flow_multimedia_types, flow->detected_protocol_stack[0]); if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_RTP && @@ -981,14 +998,15 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, } else { /* STUN/SUBPROTO -> SRTP/SUBPROTO */ ndpi_int_stun_add_connection(ndpi_struct, flow, - flow->detected_protocol_stack[0], NDPI_PROTOCOL_SRTP); + flow->detected_protocol_stack[0], NDPI_PROTOCOL_SRTP, + NDPI_PROTOCOL_CATEGORY_UNSPECIFIED); } } else { /* STUN -> STUN/RTP, or DTLS -> DTLS/SRTP */ ndpi_int_stun_add_connection(ndpi_struct, flow, __get_master(flow) == NDPI_PROTOCOL_STUN ? NDPI_PROTOCOL_RTP: NDPI_PROTOCOL_SRTP, - __get_master(flow)); + __get_master(flow), NDPI_PROTOCOL_CATEGORY_UNSPECIFIED); } } else if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_RTCP && flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { @@ -1132,7 +1150,8 @@ static u_int64_t get_stun_lru_key_raw6(u_int8_t *ip, u_int16_t port_host_order) static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t app_proto, - u_int16_t master_proto) { + u_int16_t master_proto, + ndpi_protocol_category_t category) { ndpi_confidence_t confidence = NDPI_CONFIDENCE_DPI; u_int16_t new_app_proto; @@ -1189,7 +1208,7 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd if(master_proto == NDPI_PROTOCOL_RTP || master_proto == NDPI_PROTOCOL_RTCP) { if(app_proto == NDPI_PROTOCOL_UNKNOWN) { app_proto = NDPI_PROTOCOL_RTP; - master_proto = NDPI_PROTOCOL_STUN; /* RTP|RTCP ->STUN/RTP */ + master_proto = NDPI_PROTOCOL_STUN; /* RTP|RTCP -> STUN/RTP */ } else { master_proto = NDPI_PROTOCOL_SRTP; } @@ -1199,6 +1218,9 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd if(is_subclassification_real_by_proto(app_proto)) add_to_cache(ndpi_struct, flow, app_proto); + if(category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) + flow->category = category; + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN || app_proto != NDPI_PROTOCOL_UNKNOWN) { NDPI_LOG_DBG(ndpi_struct, "Setting %d/%d\n", master_proto, app_proto); @@ -1208,10 +1230,11 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd takes care of setting the category */ if(flow->extra_packets_func) { ndpi_protocol ret = { { master_proto, app_proto }, NDPI_PROTOCOL_UNKNOWN /* unused */, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NULL}; + flow->category = ndpi_get_proto_category(ndpi_struct, ret); } } - + switch_extra_dissection_to_stun(ndpi_struct, flow, 1); } @@ -1239,6 +1262,7 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int16_t app_proto; + ndpi_protocol_category_t category; int rc; NDPI_LOG_DBG(ndpi_struct, "search stun\n"); @@ -1248,31 +1272,83 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s if(packet->iph && ((packet->iph->daddr == 0xFFFFFFFF /* 255.255.255.255 */) || ((ntohl(packet->iph->daddr) & 0xF0000000) == 0xE0000000 /* A multicast address */))) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } - rc = is_stun(ndpi_struct, flow, &app_proto); + rc = is_stun(ndpi_struct, flow, &app_proto, &category); if(rc == 1) { - ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto, __get_master(flow)); + ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto, + __get_master(flow), category); return; } /* TODO: can we stop earlier? */ if(flow->packet_counter > 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -/* ************************************************************ */ +/* ************************************************************* */ + +static u_int64_t get_signal_key(struct ndpi_flow_struct *flow) +{ + if(flow->is_ipv6) + return ndpi_quick_hash64((const char *)flow->c_address.v6, 16); + else + return flow->c_address.v4; +} + +/* ************************************************************* */ + +int signal_search_into_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + u_int64_t key; + u_int16_t dummy; + + if(ndpi_struct->signal_cache) { + key = get_signal_key(flow); -void init_stun_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("STUN", ndpi_struct, *id, - NDPI_PROTOCOL_STUN, - ndpi_search_stun, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); + if(ndpi_lru_find_cache(ndpi_struct->signal_cache, key, + &dummy, 0 /* Don't remove it as it can be used for other connections */, + ndpi_get_current_time(flow))) { +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] Found %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + return 1; + } else { +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] Not found %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + } + } + + return 0; +} + +/* ************************************************************* */ + +void signal_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + u_int64_t key; + + if(ndpi_struct->signal_cache) { + key = get_signal_key(flow); +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] ADDING %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + ndpi_lru_add_to_cache(ndpi_struct->signal_cache, key, 1 /* dummy */, + ndpi_get_current_time(flow)); + } +} + +/* ************************************************************ */ - *id += 1; +void init_stun_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("STUN", ndpi_struct, + ndpi_search_stun, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_STUN); } diff --git a/src/lib/protocols/syncthing.c b/src/lib/protocols/syncthing.c index 93039d9be..5701bb38d 100644 --- a/src/lib/protocols/syncthing.c +++ b/src/lib/protocols/syncthing.c @@ -45,7 +45,7 @@ static void ndpi_search_syncthing(struct ndpi_detection_module_struct *ndpi_stru if (packet->payload_packet_len <= 4) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -56,20 +56,14 @@ static void ndpi_search_syncthing(struct ndpi_detection_module_struct *ndpi_stru return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } -void init_syncthing_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_syncthing_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Syncthing", ndpi_struct, *id, - NDPI_PROTOCOL_SYNCTHING, - ndpi_search_syncthing, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Syncthing", ndpi_struct, + ndpi_search_syncthing, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SYNCTHING); } diff --git a/src/lib/protocols/syslog.c b/src/lib/protocols/syslog.c index ec349c519..c0cedcd77 100644 --- a/src/lib/protocols/syslog.c +++ b/src/lib/protocols/syslog.c @@ -2,7 +2,7 @@ * syslog.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -56,7 +56,7 @@ static void ndpi_search_syslog(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload[i++] != '>') { NDPI_LOG_DBG(ndpi_struct, "excluded, there is no > following the number\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else { NDPI_LOG_DBG2(ndpi_struct, "a > following the number\n"); @@ -79,7 +79,7 @@ static void ndpi_search_syslog(struct ndpi_detection_module_struct *ndpi_struct, { break; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -91,7 +91,7 @@ static void ndpi_search_syslog(struct ndpi_detection_module_struct *ndpi_struct, if (++i >= packet->payload_packet_len || packet->payload[i] != ' ') { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -100,18 +100,14 @@ static void ndpi_search_syslog(struct ndpi_detection_module_struct *ndpi_struct, ndpi_int_syslog_add_connection(ndpi_struct, flow); return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_syslog_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_syslog_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Syslog", ndpi_struct, *id, - NDPI_PROTOCOL_SYSLOG, - ndpi_search_syslog, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Syslog", ndpi_struct, + ndpi_search_syslog, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_SYSLOG); } diff --git a/src/lib/protocols/tailscale.c b/src/lib/protocols/tailscale.c index 811e8b2ea..4ee7bad65 100644 --- a/src/lib/protocols/tailscale.c +++ b/src/lib/protocols/tailscale.c @@ -45,16 +45,12 @@ static void ndpi_search_tailscale(struct ndpi_detection_module_struct *ndpi_stru return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_tailscale_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Tailscale", ndpi_struct, *id, - NDPI_PROTOCOL_TAILSCALE, - ndpi_search_tailscale, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_tailscale_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Tailscale", ndpi_struct, + ndpi_search_tailscale, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_TAILSCALE); } diff --git a/src/lib/protocols/tcp_udp.c b/src/lib/protocols/tcp_udp.c index a9dd09196..d24f83848 100644 --- a/src/lib/protocols/tcp_udp.c +++ b/src/lib/protocols/tcp_udp.c @@ -1,7 +1,7 @@ /* * tcp_or_udp.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 diff --git a/src/lib/protocols/teamspeak.c b/src/lib/protocols/teamspeak.c index 60fb466e0..fe7f154fc 100644 --- a/src/lib/protocols/teamspeak.c +++ b/src/lib/protocols/teamspeak.c @@ -81,7 +81,7 @@ static void ndpi_search_teamspeak(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; ts3_license_weblist: @@ -93,15 +93,11 @@ ts3_license_weblist: } } -void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TeamSpeak", ndpi_struct, *id, - NDPI_PROTOCOL_TEAMSPEAK, - ndpi_search_teamspeak, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TeamSpeak", ndpi_struct, + ndpi_search_teamspeak, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TEAMSPEAK); } diff --git a/src/lib/protocols/teamviewer.c b/src/lib/protocols/teamviewer.c index 4ed7f1269..b70f8a58c 100644 --- a/src/lib/protocols/teamviewer.c +++ b/src/lib/protocols/teamviewer.c @@ -79,19 +79,15 @@ static void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_teamviewer_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_teamviewer_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TeamViewer", ndpi_struct, *id, - NDPI_PROTOCOL_TEAMVIEWER, - ndpi_search_teamview, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TeamViewer", ndpi_struct, + ndpi_search_teamview, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TEAMVIEWER); } diff --git a/src/lib/protocols/telegram.c b/src/lib/protocols/telegram.c index affeede36..ed3f29cd7 100644 --- a/src/lib/protocols/telegram.c +++ b/src/lib/protocols/telegram.c @@ -107,18 +107,14 @@ static void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struc } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_telegram_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_telegram_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Telegram", ndpi_struct, *id, - NDPI_PROTOCOL_TELEGRAM, - ndpi_search_telegram, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Telegram", ndpi_struct, + ndpi_search_telegram, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TELEGRAM); } diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c index 42b7624b5..dd451b173 100644 --- a/src/lib/protocols/telnet.c +++ b/src/lib/protocols/telnet.c @@ -1,7 +1,7 @@ /* * telnet.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection @@ -209,20 +209,17 @@ static void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct *ndpi_str #ifdef TELNET_DEBUG printf("==> [%s:%d] %s()\n", __FILE__, __LINE__, __FUNCTION__); #endif - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; } -void init_telnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_telnet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Telnet", ndpi_struct, *id, - NDPI_PROTOCOL_TELNET, - ndpi_search_telnet_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Telnet", ndpi_struct, + ndpi_search_telnet_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TELNET); } diff --git a/src/lib/protocols/tencent_games.c b/src/lib/protocols/tencent_games.c index 8c23d6a65..6300129b5 100644 --- a/src/lib/protocols/tencent_games.c +++ b/src/lib/protocols/tencent_games.c @@ -82,16 +82,13 @@ static void ndpi_search_tencent_games(struct ndpi_detection_module_struct *ndpi_ } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_tencent_games_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_tencent_games_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TencentGames", ndpi_struct, *id, - NDPI_PROTOCOL_TENCENTGAMES, - ndpi_search_tencent_games, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("TencentGames", ndpi_struct, + ndpi_search_tencent_games, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TENCENTGAMES); } diff --git a/src/lib/protocols/teredo.c b/src/lib/protocols/teredo.c index 9ecdff7d2..f0cae2759 100644 --- a/src/lib/protocols/teredo.c +++ b/src/lib/protocols/teredo.c @@ -39,21 +39,16 @@ static void ndpi_search_teredo(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_INFO(ndpi_struct,"found teredo\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEREDO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_teredo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_teredo_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TEREDO", ndpi_struct, *id, - NDPI_PROTOCOL_TEREDO, - ndpi_search_teredo, - /* Teredo is inherently IPV4 only */ - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TEREDO", ndpi_struct, + ndpi_search_teredo, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Teredo is inherently IPV4 only */ + 1, NDPI_PROTOCOL_TEREDO); } diff --git a/src/lib/protocols/teso.c b/src/lib/protocols/teso.c index b2888bf4f..708c882e4 100644 --- a/src/lib/protocols/teso.c +++ b/src/lib/protocols/teso.c @@ -49,7 +49,7 @@ static void ndpi_search_teso(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 600 || ntohl(get_u_int32_t(packet->payload, 0)) != (u_int32_t)(packet->payload_packet_len-4)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -75,17 +75,13 @@ static void ndpi_search_teso(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_teso_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_teso_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TES_Online", ndpi_struct, *id, - NDPI_PROTOCOL_TESO, - ndpi_search_teso, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TES_Online", ndpi_struct, + ndpi_search_teso, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TESO); } diff --git a/src/lib/protocols/tftp.c b/src/lib/protocols/tftp.c index f32a7851c..b0686b8d4 100644 --- a/src/lib/protocols/tftp.c +++ b/src/lib/protocols/tftp.c @@ -2,7 +2,7 @@ * tftp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -142,7 +142,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 4 /* min. header size */ || get_u_int8_t(packet->payload, 0) != 0x00) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -156,7 +156,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload[packet->payload_packet_len - 1] != 0x00 /* last pdu element is a nul terminated string */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -170,19 +170,19 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, /* Exclude the flow as TFPT if there was no filename and mode in the first two strings. */ if (filename_len == 0 || ndpi_is_printable_buffer((uint8_t *)filename_start, filename_len) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (tftp_dissect_mode(packet, &offset) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (tftp_dissect_options(packet, &offset) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -201,7 +201,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, /* Data (DATA) */ if (packet->payload_packet_len <= 4 /* min DATA header size */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* First 2 bytes were opcode so next 16 bits are the block number. @@ -220,7 +220,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len != 4 /* ACK has a fixed packet size */) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* First 2 bytes were opcode so next 16 bits are the block number. @@ -241,7 +241,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, packet->payload[packet->payload_packet_len - 1] != 0x00 || packet->payload[2] != 0x00 || packet->payload[3] > 0x07) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } break; @@ -254,7 +254,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, if (tftp_dissect_options(packet, &offset) != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -265,7 +265,7 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, break; default: - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -281,15 +281,11 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, } -void init_tftp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_tftp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TFTP", ndpi_struct, *id, - NDPI_PROTOCOL_TFTP, - ndpi_search_tftp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TFTP", ndpi_struct, + ndpi_search_tftp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_TFTP); } diff --git a/src/lib/protocols/threema.c b/src/lib/protocols/threema.c index 58449b163..b9e992405 100644 --- a/src/lib/protocols/threema.c +++ b/src/lib/protocols/threema.c @@ -43,7 +43,7 @@ static void ndpi_search_threema(struct ndpi_detection_module_struct *ndpi_struct NDPI_LOG_DBG(ndpi_struct, "search Threema\n"); if (ntohs(packet->tcp->source) != 5222 && ntohs(packet->tcp->dest) != 5222) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -52,19 +52,19 @@ static void ndpi_search_threema(struct ndpi_detection_module_struct *ndpi_struct case 1: if (packet->payload_packet_len != 48) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; case 2: if (packet->payload_packet_len != 80) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; case 3: if (packet->payload_packet_len != 191) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } return; case 4: @@ -75,29 +75,24 @@ static void ndpi_search_threema(struct ndpi_detection_module_struct *ndpi_struct if (packet->payload_packet_len < 2) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } uint16_t len = le16toh(get_u_int16_t(packet->payload, 0)); if (len + 2 != packet->payload_packet_len) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } ndpi_int_threema_add_connection(ndpi_struct, flow); } -void init_threema_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_threema_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Threema", ndpi_struct, *id, - NDPI_PROTOCOL_THREEMA, - ndpi_search_threema, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - *id += 1; + register_dissector("Threema", ndpi_struct, + ndpi_search_threema, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_THREEMA); } diff --git a/src/lib/protocols/thrift.c b/src/lib/protocols/thrift.c index c6afe0570..3c94f073c 100644 --- a/src/lib/protocols/thrift.c +++ b/src/lib/protocols/thrift.c @@ -144,22 +144,22 @@ static void ndpi_dissect_strict_hdr(struct ndpi_detection_module_struct *ndpi_st const size_t method_length = ntohl(strict_hdr->method_length); if (packet->tcp == NULL) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (packet->payload_packet_len < sizeof(*strict_hdr) + method_length) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (thrift_validate_version(strict_hdr->version) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (thrift_validate_type(strict_hdr->message_type) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -176,22 +176,22 @@ static void ndpi_dissect_compact_hdr(struct ndpi_detection_module_struct *ndpi_s struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; if (packet->udp == NULL) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (packet->payload_packet_len < sizeof(*compact_hdr) + compact_hdr->method_length) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (thrift_validate_version(compact_hdr->version) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (thrift_validate_type(compact_hdr->message_type) == 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -235,7 +235,7 @@ static void ndpi_search_thrift_tcp_udp(struct ndpi_detection_module_struct *ndpi /* Strict Binary Protocol */ if (packet->payload_packet_len < sizeof(*thrift_data.strict_hdr)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -247,21 +247,18 @@ static void ndpi_search_thrift_tcp_udp(struct ndpi_detection_module_struct *ndpi return; } else { /* Probably not Apache Thrift. */ - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_apache_thrift_dissector(struct ndpi_detection_module_struct *ndpi_struct, uint32_t *id) +void init_apache_thrift_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Thrift", ndpi_struct, *id, - NDPI_PROTOCOL_APACHE_THRIFT, - ndpi_search_thrift_tcp_udp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("Thrift", ndpi_struct, + ndpi_search_thrift_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_APACHE_THRIFT); } diff --git a/src/lib/protocols/tinc.c b/src/lib/protocols/tinc.c index 0e12d6270..309aa2203 100644 --- a/src/lib/protocols/tinc.c +++ b/src/lib/protocols/tinc.c @@ -65,7 +65,7 @@ static void ndpi_check_tinc(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } else if(packet->tcp != NULL) { @@ -130,7 +130,7 @@ static void ndpi_check_tinc(struct ndpi_detection_module_struct *ndpi_struct, st } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } static void ndpi_search_tinc(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { @@ -141,15 +141,11 @@ static void ndpi_search_tinc(struct ndpi_detection_module_struct* ndpi_struct, s } } -void init_tinc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_tinc_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TINC", ndpi_struct, *id, - NDPI_PROTOCOL_TINC, - ndpi_search_tinc, - NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, /* TODO: IPv6? */ - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TINC", ndpi_struct, + ndpi_search_tinc, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, /* TODO: IPv6? */ + 1, NDPI_PROTOCOL_TINC); } diff --git a/src/lib/protocols/tivoconnect.c b/src/lib/protocols/tivoconnect.c index 4bfd041e9..e9b26e7cc 100644 --- a/src/lib/protocols/tivoconnect.c +++ b/src/lib/protocols/tivoconnect.c @@ -126,23 +126,17 @@ static void ndpi_search_tivoconnect(struct ndpi_detection_module_struct *ndpi_st { ndpi_int_tivoconnect_add_connection(ndpi_struct, flow); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } dissect_tivoconnect_data(ndpi_struct, flow); } -void init_tivoconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_tivoconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TiVoConnect", ndpi_struct, *id, - NDPI_PROTOCOL_TIVOCONNECT, - ndpi_search_tivoconnect, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("TiVoConnect", ndpi_struct, + ndpi_search_tivoconnect, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TIVOCONNECT); } diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 88c6fddde..e8444a731 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -29,7 +29,7 @@ #include "ndpi_encryption.h" #include "ndpi_private.h" -//#define JA4R_DECIMAL 1 +//#define JA4R_DECIMAL 1 static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -107,6 +107,19 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp /* **************************************** */ +static bool str_contains_digit(char *str) { + u_int i = 0; + + for(i=0; (str[i] != '.') && (str[i] != '\0'); i++) { + if(isdigit(str[i])) + return(true); + } + + return(false); +} + +/* **************************************** */ + static u_int32_t ndpi_tls_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; @@ -152,6 +165,50 @@ static u_int32_t __get_master(struct ndpi_detection_module_struct *ndpi_struct, /* **************************************** */ +/* TODO: rename */ +static int keep_extra_dissection_tcp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + /* Common path: found handshake on both directions */ + if(flow->tls_quic.certificate_processed == 1 && flow->protos.tls_quic.client_hello_processed) + return 0; + /* Application Data on both directions: handshake already ended (did we miss it?) */ + if(flow->l4.tcp.tls.app_data_seen[0] == 1 && flow->l4.tcp.tls.app_data_seen[1] == 1) + return 0; + /* Handshake on one direction and Application Data on the other */ + if((flow->protos.tls_quic.client_hello_processed && flow->l4.tcp.tls.app_data_seen[!flow->protos.tls_quic.ch_direction] == 1) || + (flow->protos.tls_quic.server_hello_processed && flow->l4.tcp.tls.app_data_seen[flow->protos.tls_quic.ch_direction] == 1)) + return 0; + + /* Are we interested only in the (sub)-classification? */ + + if(/* Subclassification */ + flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN && + /* No metadata from SH or certificate */ + !ndpi_struct->cfg.tls_alpn_negotiated_enabled && + !ndpi_struct->cfg.tls_cipher_enabled && + !ndpi_struct->cfg.tls_sha1_fingerprint_enabled && + !ndpi_struct->cfg.tls_cert_server_names_enabled && + !ndpi_struct->cfg.tls_cert_validity_enabled && + !ndpi_struct->cfg.tls_cert_issuer_enabled && + !ndpi_struct->cfg.tls_cert_subject_enabled && + !ndpi_struct->cfg.tls_broswer_enabled && + !ndpi_struct->cfg.tls_ja3s_fingerprint_enabled && + /* No flow risks from SH or certificate: we should have disabled all + metadata needed for flow risks, so we should not need to explicitly + check them */ + /* Ookla aggressiveness has no impact here because it is evaluated only + without sub-classification */ + /* TLS heuristics */ + (ndpi_struct->cfg.tls_heuristics == 0 || is_flow_addr_informative(flow))) + return 0; + + return 1; +} + + +/* **************************************** */ + /* Heuristic to detect proxied/obfuscated TLS flows, based on https://www.usenix.org/conference/usenixsecurity24/presentation/xue-fingerprinting. Main differences between the paper and our implementation: @@ -381,19 +438,6 @@ static int tls_obfuscated_heur_search(struct ndpi_detection_module_struct* ndpi_ if(check_set(ndpi_struct, set)) { /* Heuristic match */ - /* Export the matching set as metadata */ - flow->tls_quic.obfuscated_heur_matching_set = ndpi_calloc(1, sizeof(struct ndpi_tls_obfuscated_heuristic_matching_set)); - if(flow->tls_quic.obfuscated_heur_matching_set) { - flow->tls_quic.obfuscated_heur_matching_set->bytes[0] = set->bytes[0]; - flow->tls_quic.obfuscated_heur_matching_set->bytes[1] = set->bytes[1]; - flow->tls_quic.obfuscated_heur_matching_set->bytes[2] = set->bytes[2]; - flow->tls_quic.obfuscated_heur_matching_set->bytes[3] = set->bytes[3]; - flow->tls_quic.obfuscated_heur_matching_set->pkts[0] = set->pkts[0]; - flow->tls_quic.obfuscated_heur_matching_set->pkts[1] = set->pkts[1]; - flow->tls_quic.obfuscated_heur_matching_set->pkts[2] = set->pkts[2]; - flow->tls_quic.obfuscated_heur_matching_set->pkts[3] = set->pkts[3]; - } - return 2; /* Found */ } else { /* Close this set and open a new one... */ @@ -448,8 +492,8 @@ static int tls_obfuscated_heur_search_again(struct ndpi_detection_module_struct* ndpi_protocol ret = { { __get_master(ndpi_struct, flow), NDPI_PROTOCOL_UNKNOWN }, NDPI_PROTOCOL_UNKNOWN /* unused */, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NULL}; flow->category = ndpi_get_proto_category(ndpi_struct, ret); } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); /* Not necessary in extra-dissection data path, - but we need it with the plain heuristic */ + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); /* Not necessary in extra-dissection data path, + but we need it with the plain heuristic */ return 0; /* Stop */ } @@ -677,7 +721,7 @@ static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct ndpi_set_detected_protocol(ndpi_struct, flow, cached_proto, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI_CACHE); flow->category = ndpi_get_proto_category(ndpi_struct, ret); ndpi_check_subprotocol_risk(ndpi_struct, flow, cached_proto); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); } } } @@ -767,13 +811,17 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct printf("[TLS] %s() IssuerDN [%s]\n", __FUNCTION__, rdnSeqBuf); #endif - if(rdn_len && (flow->protos.tls_quic.issuerDN == NULL)) { + if(rdn_len && (flow->protos.tls_quic.issuerDN == NULL) && + ndpi_struct->cfg.tls_cert_issuer_enabled) { flow->protos.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf); if(ndpi_normalize_printable_string(rdnSeqBuf, rdn_len) == 0) { - char str[64]; - - snprintf(str, sizeof(str), "Invalid issuerDN %s", flow->protos.tls_quic.issuerDN); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_INVALID_CHARACTERS)) { + char str[64]; + snprintf(str, sizeof(str), "Invalid issuerDN %s", flow->protos.tls_quic.issuerDN); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } } } @@ -781,7 +829,8 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct } if(i + 3 < certificate_len && - (offset+packet->payload[i+3]) < packet->payload_packet_len) { + (offset+packet->payload[i+3]) < packet->payload_packet_len && + ndpi_struct->cfg.tls_cert_validity_enabled) { char utcDate[32]; u_int8_t len = packet->payload[i+3]; @@ -846,41 +895,53 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct if(flow->protos.tls_quic.notBefore > TLS_LIMIT_DATE) if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) { - char str[64]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERT_VALIDITY_TOO_LONG)) { + char str[64]; - snprintf(str, sizeof(str), "TLS Cert lasts %u days", - (flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) / 86400); + snprintf(str, sizeof(str), "TLS Cert lasts %u days", + (flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) / 86400); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, str); /* Certificate validity longer than 13 months */ + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, str); /* Certificate validity longer than 13 months */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, NULL); + } } if((time_sec < flow->protos.tls_quic.notBefore) || (time_sec > flow->protos.tls_quic.notAfter)) { - char str[96], b[32], e[32]; - struct tm result; - time_t theTime; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_EXPIRED)) { + char str[96], b[32], e[32]; + struct tm result; + time_t theTime; - theTime = flow->protos.tls_quic.notBefore; - strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notBefore; + strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - theTime = flow->protos.tls_quic.notAfter; - strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - snprintf(str, sizeof(str), "%s - %s", b, e); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */ + snprintf(str, sizeof(str), "%s - %s", b, e); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, NULL); + } } else if((time_sec > flow->protos.tls_quic.notBefore) && (time_sec > (flow->protos.tls_quic.notAfter - (ndpi_struct->cfg.tls_certificate_expire_in_x_days * 86400)))) { - char str[96], b[32], e[32]; - struct tm result; - time_t theTime; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE)) { + char str[96], b[32], e[32]; + struct tm result; + time_t theTime; - theTime = flow->protos.tls_quic.notBefore; - strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notBefore; + strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - theTime = flow->protos.tls_quic.notAfter; - strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - snprintf(str, sizeof(str), "%s - %s", b, e); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, str); /* Certificate almost expired */ + snprintf(str, sizeof(str), "%s - %s", b, e); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, str); /* Certificate almost expired */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, NULL); + } } } } @@ -992,29 +1053,32 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct } } - if(flow->protos.tls_quic.server_names == NULL) - flow->protos.tls_quic.server_names = ndpi_strdup(dNSName), - flow->protos.tls_quic.server_names_len = strlen(dNSName); - else if((u_int16_t)(flow->protos.tls_quic.server_names_len + dNSName_len + 1) > flow->protos.tls_quic.server_names_len) { - u_int16_t newstr_len = flow->protos.tls_quic.server_names_len + dNSName_len + 1; - char *newstr = (char*)ndpi_realloc(flow->protos.tls_quic.server_names, - flow->protos.tls_quic.server_names_len+1, newstr_len+1); - - if(newstr) { - flow->protos.tls_quic.server_names = newstr; - flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len] = ','; - strncpy(&flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len+1], - dNSName, dNSName_len+1); - flow->protos.tls_quic.server_names[newstr_len] = '\0'; - flow->protos.tls_quic.server_names_len = newstr_len; - } + if(ndpi_struct->cfg.tls_cert_server_names_enabled) { + if(flow->protos.tls_quic.server_names == NULL) { + flow->protos.tls_quic.server_names = ndpi_strdup(dNSName); + flow->protos.tls_quic.server_names_len = strlen(dNSName); + } else if((u_int16_t)(flow->protos.tls_quic.server_names_len + dNSName_len + 1) > flow->protos.tls_quic.server_names_len) { + u_int16_t newstr_len = flow->protos.tls_quic.server_names_len + dNSName_len + 1; + char *newstr = (char*)ndpi_realloc(flow->protos.tls_quic.server_names, + flow->protos.tls_quic.server_names_len+1, newstr_len+1); + + if(newstr) { + flow->protos.tls_quic.server_names = newstr; + flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len] = ','; + strncpy(&flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len+1], + dNSName, dNSName_len+1); + flow->protos.tls_quic.server_names[newstr_len] = '\0'; + flow->protos.tls_quic.server_names_len = newstr_len; + } + } } if(ndpi_struct->cfg.tls_subclassification_enabled && - !flow->protos.tls_quic.subprotocol_detected) { + !flow->protos.tls_quic.subprotocol_detected && + !flow->tls_quic.from_rdp) { /* No (other) sub-classification; we will have TLS.RDP anyway */ if(ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), dNSName, dNSName_len)) { flow->protos.tls_quic.subprotocol_detected = 1; - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); } } @@ -1035,10 +1099,14 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct } /* while */ if(!matched_name) { - char str[128]; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_MISMATCH)) { + char str[128]; - snprintf(str, sizeof(str), "%s vs %s", flow->host_server_name, flow->protos.tls_quic.server_names); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, str); /* Certificate mismatch */ + snprintf(str, sizeof(str), "%s vs %s", flow->host_server_name, flow->protos.tls_quic.server_names); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, str); /* Certificate mismatch */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, NULL); /* Certificate mismatch */ + } } } } @@ -1047,7 +1115,8 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct } /* for */ if(rdn_len && (flow->protos.tls_quic.subjectDN == NULL)) { - flow->protos.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf); + if(ndpi_struct->cfg.tls_cert_subject_enabled) + flow->protos.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf); if(ndpi_struct->cfg.tls_subclassification_enabled && flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { @@ -1064,7 +1133,7 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct ndpi_set_detected_protocol(ndpi_struct, flow, proto_id, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI); flow->category = ndpi_get_proto_category(ndpi_struct, ret); ndpi_check_subprotocol_risk(ndpi_struct, flow, proto_id); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); if(ndpi_struct->tls_cert_cache) { u_int64_t key = make_tls_cert_key(packet, 0 /* from the server */); @@ -1307,11 +1376,14 @@ static void ndpi_looks_like_tls(struct ndpi_detection_module_struct *ndpi_struct /* **************************************** */ int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int8_t something_went_wrong = 0; message_t *message; + if(packet->tcp == NULL) + return 0; /* Error -> stop (this doesn't seem to be TCP) */ + #ifdef DEBUG_TLS_MEMORY printf("[TLS Mem] ndpi_search_tls_tcp() Processing new packet [payload_packet_len: %u][Dir: %u]\n", packet->payload_packet_len, packet->packet_direction); @@ -1506,17 +1578,15 @@ int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, #endif } +#ifdef DEBUG_TLS_MEMORY + printf("[TLS] Eval if keep going [%p]\n", flow->extra_packets_func); +#endif + if(something_went_wrong || ((ndpi_struct->num_tls_blocks_to_follow > 0) && (flow->l4.tcp.tls.num_tls_blocks == ndpi_struct->num_tls_blocks_to_follow)) || ((ndpi_struct->num_tls_blocks_to_follow == 0) - && (/* Common path: found handshake on both directions */ - (flow->tls_quic.certificate_processed == 1 && flow->protos.tls_quic.client_hello_processed) || - /* No handshake at all but Application Data on both directions */ - (flow->l4.tcp.tls.app_data_seen[0] == 1 && flow->l4.tcp.tls.app_data_seen[1] == 1) || - /* Handshake on one direction and Application Data on the other */ - (flow->protos.tls_quic.client_hello_processed && flow->l4.tcp.tls.app_data_seen[!flow->protos.tls_quic.ch_direction] == 1) || - (flow->protos.tls_quic.server_hello_processed && flow->l4.tcp.tls.app_data_seen[flow->protos.tls_quic.ch_direction] == 1))) + && (!keep_extra_dissection_tcp(ndpi_struct, flow))) ) { #ifdef DEBUG_TLS_BLOCKS printf("*** [TLS Block] No more blocks\n"); @@ -1536,7 +1606,7 @@ int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, suited than NDPI_CONFIDENCE_DPI_CACHE */ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI_AGGRESSIVE); /* TLS over port 8080 usually triggers that risk; clear it */ - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); flow->extra_packets_func = NULL; return(0); /* That's all */ /* Loook for TLS-in-TLS */ @@ -1590,7 +1660,8 @@ int is_dtls(const u_int8_t *buf, u_int32_t buf_len, u_int32_t *block_len) { /* **************************************** */ -static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct, +/* NOTE: this function supports both TCP and UDP */ +static int ndpi_search_dtls(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int32_t handshake_len, handshake_frag_off, handshake_frag_len; @@ -1759,7 +1830,7 @@ static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *nd /* At most 12 packets should almost always be enough to find the server certificate if it's there. Exception: DTLS traffic with fragments, retransmissions and STUN packets */ flow->max_extra_packets_to_check = ((packet->udp != NULL) ? 20 : 12) + (ndpi_struct->num_tls_blocks_to_follow*4); - flow->extra_packets_func = (packet->udp != NULL) ? ndpi_search_tls_udp : ndpi_search_tls_tcp; + flow->extra_packets_func = (packet->udp != NULL) ? ndpi_search_dtls : ndpi_search_tls_tcp; } /* **************************************** */ @@ -1849,21 +1920,25 @@ static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struc alpn_len = comma_or_nul - alpn_start; if(!is_a_common_alpn(ndpi_struct, alpn_start, alpn_len)) { - char str[64]; - size_t str_len; + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_UNCOMMON_ALPN)) { + char str[64]; + size_t str_len; #ifdef DEBUG_TLS - printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start); + printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start); #endif - str[0] = '\0'; - str_len = ndpi_min(alpn_len, sizeof(str)); - if(str_len > 0) { - strncpy(str, alpn_start, str_len); - str[str_len - 1] = '\0'; - } + str[0] = '\0'; + str_len = ndpi_min(alpn_len, sizeof(str)); + if(str_len > 0) { + strncpy(str, alpn_start, str_len); + str[str_len - 1] = '\0'; + } - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, NULL); + } break; } @@ -1887,12 +1962,12 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp NDPI_PROTOCOL_RDP, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI); return; } - + if((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) || (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)) { if(!flow->extra_packets_func) tlsInitExtraPacketProcessing(ndpi_struct, flow); - + return; } @@ -1923,7 +1998,7 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, /* see: https://www.wireshark.org/docs/wsar_html/packet-tls-utils_8h_source.html */ static u_int16_t const allowed_non_iana_extensions[] = { - 65486 /* ESNI */, 13172 /* NPN - Next Proto Neg */, 17513 /* ALPS */, + /* 65486 ESNI is suspicious nowadays */ 13172 /* NPN - Next Proto Neg */, 30032 /* Channel ID */, 65445 /* QUIC transport params */, /* GREASE extensions */ 2570, 6682, 10794, 14906, 19018, 23130, 27242, @@ -1933,14 +2008,15 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, 1035, 10794, 16696, 23130, 31354, 35466, 51914, /* Ciphers */ 102, 129, 52243, 52244, 57363, 65279, 65413, - /* ECH */ - 65037 + /* ALPS */ + 17513, 17613 }; size_t const allowed_non_iana_extensions_size = sizeof(allowed_non_iana_extensions) / sizeof(allowed_non_iana_extensions[0]); /* see: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml */ - if(extension_id > 59 && extension_id != 65281) + /* 65281 renegotiation_info, 65037 ECH */ + if(extension_id > 59 && extension_id != 65281 && extension_id != 65037) { u_int8_t extension_found = 0; size_t i; @@ -1953,15 +2029,20 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, } if(extension_found == 0) { - char str[64]; - - snprintf(str, sizeof(str), "Extn id %u", extension_id); #ifdef DEBUG_TLS - printf("[TLS] suspicious extension id: %u\n", extension_id); + printf("[TLS] suspicious extension id: %u\n", extension_id); #endif + + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_SUSPICIOUS_EXTENSION)) { + char str[64]; + + snprintf(str, sizeof(str), "Extn id %u", extension_id); ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); - return; - } + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); + } + return; + } } /* Check for DTLS-only extensions. */ @@ -1969,14 +2050,18 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, { if(extension_id == 53 || extension_id == 54) { - char str[64]; - - snprintf(str, sizeof(str), "Extn id %u", extension_id); - #ifdef DEBUG_TLS - printf("[TLS] suspicious DTLS-only extension id: %u\n", extension_id); + printf("[TLS] suspicious DTLS-only extension id: %u\n", extension_id); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); + + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_SUSPICIOUS_EXTENSION)) { + char str[64]; + + snprintf(str, sizeof(str), "Extn id %u", extension_id); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); + } return; } } @@ -2297,15 +2382,22 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, return(0); /* Not found */ ja.server.num_ciphers = 1, ja.server.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset])); - if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja.server.cipher[0])) != NDPI_CIPHER_SAFE) { - char str[64]; - char unknown_cipher[8]; - snprintf(str, sizeof(str), "Cipher %s", ndpi_cipher2str(ja.server.cipher[0], unknown_cipher)); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str); - } + if(ndpi_struct->cfg.tls_cipher_enabled) { + if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja.server.cipher[0])) != NDPI_CIPHER_SAFE) { + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_WEAK_CIPHER)) { + char str[64]; + char unknown_cipher[8]; + + snprintf(str, sizeof(str), "Cipher %s", ndpi_cipher2str(ja.server.cipher[0], unknown_cipher)); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, NULL); + } + } - flow->protos.tls_quic.server_cipher = ja.server.cipher[0]; + flow->protos.tls_quic.server_cipher = ja.server.cipher[0]; + } #ifdef DEBUG_TLS printf("TLS [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja.server.cipher[0]); @@ -2409,7 +2501,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(ndpi_normalize_printable_string(alpn_str, alpn_str_len) == 0) ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, alpn_str); - if(flow->protos.tls_quic.negotiated_alpn == NULL) + if(flow->protos.tls_quic.negotiated_alpn == NULL && + ndpi_struct->cfg.tls_alpn_negotiated_enabled) flow->protos.tls_quic.negotiated_alpn = ndpi_strdup(alpn_str); /* Check ALPN only if not already checked (client-side) */ @@ -2524,13 +2617,17 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.tls_quic.ssl_version = ja.client.tls_handshake_version = tls_version; if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ { - char str[32], buf[32]; - u_int8_t unknown_tls_version; - - snprintf(str, sizeof(str), "%s", ndpi_ssl_version2str(buf, sizeof(buf), - flow->protos.tls_quic.ssl_version, - &unknown_tls_version)); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str); + if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_OBSOLETE_VERSION)) { + char str[32], buf[32]; + u_int8_t unknown_tls_version; + + snprintf(str, sizeof(str), "%s", ndpi_ssl_version2str(buf, sizeof(buf), + flow->protos.tls_quic.ssl_version, + &unknown_tls_version)); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, NULL); + } } if((session_id_len+base_offset+3) > packet->payload_packet_len) @@ -2626,27 +2723,29 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, i += 2; } /* for */ - /* NOTE: - we do not check for duplicates as with signatures because - this is time consuming and we want to avoid overhead whem possible - */ - if(this_is_not_safari) - flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; - else if((safari_ciphers == 12) || (this_is_not_safari && looks_like_safari_on_big_sur)) - flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; + if(ndpi_struct->cfg.tls_broswer_enabled) { + /* NOTE: + we do not check for duplicates as with signatures because + this is time consuming and we want to avoid overhead whem possible + */ + if(this_is_not_safari) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; + else if((safari_ciphers == 12) || (this_is_not_safari && looks_like_safari_on_big_sur)) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; - if(chrome_ciphers == 13) - flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 1; + if(chrome_ciphers == 13) + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 1; - /* Note that both Safari and Chrome can overlap */ + /* Note that both Safari and Chrome can overlap */ #ifdef DEBUG_HEURISTIC - printf("[CIPHERS] [is_chrome_tls: %u (%u)][is_safari_tls: %u (%u)][this_is_not_safari: %u]\n", - flow->protos.tls_quic.browser_heuristics.is_chrome_tls, - chrome_ciphers, - flow->protos.tls_quic.browser_heuristics.is_safari_tls, - safari_ciphers, - this_is_not_safari); + printf("[CIPHERS] [is_chrome_tls: %u (%u)][is_safari_tls: %u (%u)][this_is_not_safari: %u]\n", + flow->protos.tls_quic.browser_heuristics.is_chrome_tls, + chrome_ciphers, + flow->protos.tls_quic.browser_heuristics.is_safari_tls, + safari_ciphers, + this_is_not_safari); #endif + } } else { invalid_ja = 1; #ifdef DEBUG_TLS @@ -2747,10 +2846,14 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(!is_quic) { if(ndpi_struct->cfg.tls_subclassification_enabled && + flow->protos.tls_quic.subprotocol_detected == 0 && + !flow->tls_quic.from_rdp && /* No (other) sub-classification; we will have TLS.RDP anyway */ ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), sni, sni_len)) flow->protos.tls_quic.subprotocol_detected = 1; } else { if(ndpi_struct->cfg.quic_subclassification_enabled && + flow->protos.tls_quic.subprotocol_detected == 0 && + !flow->tls_quic.from_rdp && /* No (other) sub-classification; we will have TLS.RDP anyway */ ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, sni, sni_len)) flow->protos.tls_quic.subprotocol_detected = 1; } @@ -2760,7 +2863,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, sni); } - if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0)) { + if(ndpi_str_endswith(sni, "signal.org")) { + /* printf("[SIGNAL] SNI: [%s]\n", sni); */ + signal_add_to_cache(ndpi_struct, flow); + } + + if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0, 0)) { #ifdef DEBUG_TLS printf("[TLS] SNI: (DGA) [%s]\n", sni); #endif @@ -2768,7 +2876,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if((sni_len >= 4) /* Check if it ends in .com or .net */ && ((strcmp(&sni[sni_len-4], ".com") == 0) || (strcmp(&sni[sni_len-4], ".net") == 0)) - && (strncmp(sni, "www.", 4) == 0)) /* Not starting with www.... */ + && (strncmp(sni, "www.", 4) == 0)) /* Starting with www.... */ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI); } else { #ifdef DEBUG_TLS @@ -2847,8 +2955,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, } } else if(extension_id == 13 /* signature algorithms */ && offset+extension_offset+1 < total_len) { - int s_offset = offset+extension_offset, safari_signature_algorithms = 0, - chrome_signature_algorithms = 0, duplicate_found = 0, last_signature = 0, id; + int s_offset = offset+extension_offset, safari_signature_algorithms = 0, id; u_int16_t tot_signature_algorithms_len = ntohs(*((u_int16_t*)&packet->payload[s_offset])); #ifdef DEBUG_TLS @@ -2880,95 +2987,99 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(rc < 0) break; } - for(i=0; i<tot_signature_algorithms_len && s_offset + (int)i + 2 < packet->payload_packet_len; i+=2) { - u_int16_t signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i])); + if(ndpi_struct->cfg.tls_broswer_enabled) { + int chrome_signature_algorithms = 0, duplicate_found = 0, last_signature = 0; - if(last_signature == signature_algo) { - /* Consecutive duplication */ - duplicate_found = 1; - continue; - } else { - /* Check for other duplications */ - u_int all_ok = 1; + for(i=0; i<tot_signature_algorithms_len && s_offset + (int)i + 2 < packet->payload_packet_len; i+=2) { + u_int16_t signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i])); - for(j=0; j<tot_signature_algorithms_len; j+=2) { - if(j != i && s_offset + (int)j + 2 < packet->payload_packet_len) { - u_int16_t j_signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+j])); + if(last_signature == signature_algo) { + /* Consecutive duplication */ + duplicate_found = 1; + continue; + } else { + /* Check for other duplications */ + u_int all_ok = 1; - if((signature_algo == j_signature_algo) - && (i < j) /* Don't skip both of them */) { + for(j=0; j<tot_signature_algorithms_len; j+=2) { + if(j != i && s_offset + (int)j + 2 < packet->payload_packet_len) { + u_int16_t j_signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+j])); + + if((signature_algo == j_signature_algo) + && (i < j) /* Don't skip both of them */) { #ifdef DEBUG_HEURISTIC - printf("[SIGNATURE] [TLS Signature Algorithm] Skipping duplicate 0x%04X\n", signature_algo); + printf("[SIGNATURE] [TLS Signature Algorithm] Skipping duplicate 0x%04X\n", signature_algo); #endif - duplicate_found = 1, all_ok = 0; - break; - } - } - } + duplicate_found = 1, all_ok = 0; + break; + } + } + } - if(!all_ok) - continue; - } + if(!all_ok) + continue; + } - last_signature = signature_algo; + last_signature = signature_algo; #ifdef DEBUG_HEURISTIC - printf("[SIGNATURE] [TLS Signature Algorithm] 0x%04X\n", signature_algo); -#endif - switch(signature_algo) { - case ECDSA_SECP521R1_SHA512: - flow->protos.tls_quic.browser_heuristics.is_firefox_tls = 1; - break; - - case ECDSA_SECP256R1_SHA256: - case ECDSA_SECP384R1_SHA384: - case RSA_PKCS1_SHA256: - case RSA_PKCS1_SHA384: - case RSA_PKCS1_SHA512: - case RSA_PSS_RSAE_SHA256: - case RSA_PSS_RSAE_SHA384: - case RSA_PSS_RSAE_SHA512: - chrome_signature_algorithms++, safari_signature_algorithms++; + printf("[SIGNATURE] [TLS Signature Algorithm] 0x%04X\n", signature_algo); +#endif + switch(signature_algo) { + case ECDSA_SECP521R1_SHA512: + flow->protos.tls_quic.browser_heuristics.is_firefox_tls = 1; + break; + + case ECDSA_SECP256R1_SHA256: + case ECDSA_SECP384R1_SHA384: + case RSA_PKCS1_SHA256: + case RSA_PKCS1_SHA384: + case RSA_PKCS1_SHA512: + case RSA_PSS_RSAE_SHA256: + case RSA_PSS_RSAE_SHA384: + case RSA_PSS_RSAE_SHA512: + chrome_signature_algorithms++, safari_signature_algorithms++; #ifdef DEBUG_HEURISTIC - printf("[SIGNATURE] [Chrome/Safari] Found 0x%04X [chrome: %u][safari: %u]\n", - signature_algo, chrome_signature_algorithms, safari_signature_algorithms); + printf("[SIGNATURE] [Chrome/Safari] Found 0x%04X [chrome: %u][safari: %u]\n", + signature_algo, chrome_signature_algorithms, safari_signature_algorithms); #endif - break; - } - } + break; + } + } #ifdef DEBUG_HEURISTIC - printf("[SIGNATURE] [safari_signature_algorithms: %u][chrome_signature_algorithms: %u]\n", - safari_signature_algorithms, chrome_signature_algorithms); + printf("[SIGNATURE] [safari_signature_algorithms: %u][chrome_signature_algorithms: %u]\n", + safari_signature_algorithms, chrome_signature_algorithms); #endif - if(flow->protos.tls_quic.browser_heuristics.is_firefox_tls) - flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0, - flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; + if(flow->protos.tls_quic.browser_heuristics.is_firefox_tls) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0, + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; - if(safari_signature_algorithms != 8) - flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; + if(safari_signature_algorithms != 8) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; - if((chrome_signature_algorithms != 8) || duplicate_found) - flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; + if((chrome_signature_algorithms != 8) || duplicate_found) + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; - /* Avoid Chrome and Safari overlaps, thing that cannot happen with Firefox */ - if(flow->protos.tls_quic.browser_heuristics.is_safari_tls) - flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; + /* Avoid Chrome and Safari overlaps, thing that cannot happen with Firefox */ + if(flow->protos.tls_quic.browser_heuristics.is_safari_tls) + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; - if((flow->protos.tls_quic.browser_heuristics.is_chrome_tls == 0) - && duplicate_found) - flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; /* Safari */ + if((flow->protos.tls_quic.browser_heuristics.is_chrome_tls == 0) + && duplicate_found) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; /* Safari */ #ifdef DEBUG_HEURISTIC - printf("[SIGNATURE] [is_firefox_tls: %u][is_chrome_tls: %u][is_safari_tls: %u][duplicate_found: %u]\n", - flow->protos.tls_quic.browser_heuristics.is_firefox_tls, - flow->protos.tls_quic.browser_heuristics.is_chrome_tls, - flow->protos.tls_quic.browser_heuristics.is_safari_tls, - duplicate_found); + printf("[SIGNATURE] [is_firefox_tls: %u][is_chrome_tls: %u][is_safari_tls: %u][duplicate_found: %u]\n", + flow->protos.tls_quic.browser_heuristics.is_firefox_tls, + flow->protos.tls_quic.browser_heuristics.is_chrome_tls, + flow->protos.tls_quic.browser_heuristics.is_safari_tls, + duplicate_found); #endif + } if(i > 0 && i >= tot_signature_algorithms_len) { ja.client.signature_algorithms_str[i*2 - 1] = '\0'; @@ -3100,12 +3211,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("Client TLS [SUPPORTED_VERSIONS: %s]\n", version_str); #endif - if(flow->protos.tls_quic.tls_supported_versions == NULL) + if(flow->protos.tls_quic.tls_supported_versions == NULL && + ndpi_struct->cfg.tls_versions_supported_enabled) flow->protos.tls_quic.tls_supported_versions = ndpi_strdup(version_str); } - } else if(extension_id == 65486 /* encrypted server name */) { - /* ESNI has been superseded by ECH */ - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_ESNI_USAGE, NULL); } else if(extension_id == 65037 /* ECH: latest drafts */) { #ifdef DEBUG_TLS printf("Client TLS: ECH version 0x%x\n", extension_id); @@ -3169,6 +3278,22 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #endif ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Abnormal Client Hello/Padding length"); } + } else if(extension_id == 22) { /* Encrypt-then-MAC */ + if(extension_len == 0) { + char *sni = flow->host_server_name; + + if(sni != NULL) { + u_int sni_len = strlen(sni); + + if((flow->protos.tls_quic.advertised_alpns == NULL) /* No ALPN */ + && (sni_len > 8) + && ((strcmp(&sni[sni_len-4], ".com") == 0) || (strcmp(&sni[sni_len-4], ".net") == 0)) + && (strncmp(sni, "www.", 4) == 0) /* Starting with www.... */ + && str_contains_digit(&sni[4])) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI); + } + } + } } extension_offset += extension_len; /* Move to the next extension */ @@ -3277,7 +3402,7 @@ static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_st if(flow->tls_quic.obfuscated_heur_state == NULL) { if(packet->udp != NULL || flow->stun.maybe_dtls) - rc = ndpi_search_tls_udp(ndpi_struct, flow); + rc = ndpi_search_dtls(ndpi_struct, flow); else rc = ndpi_search_tls_tcp(ndpi_struct, flow); @@ -3301,34 +3426,17 @@ static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_st if(flow->tls_quic.obfuscated_heur_state) { tls_obfuscated_heur_search_again(ndpi_struct, flow); } else if(rc == 0) { - if(packet->udp != NULL || flow->stun.maybe_dtls) - NDPI_EXCLUDE_PROTO_EXT(ndpi_struct, flow, NDPI_PROTOCOL_DTLS); - else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* **************************************** */ -void init_tls_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("TLS", ndpi_struct, *id, - NDPI_PROTOCOL_TLS, - ndpi_search_tls_wrapper, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; - - /* *************************************************** */ - - ndpi_set_bitmask_protocol_detection("DTLS", ndpi_struct, *id, - NDPI_PROTOCOL_DTLS, - ndpi_search_tls_wrapper, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_tls_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("(D)TLS", ndpi_struct, + ndpi_search_tls_wrapper, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 2, + NDPI_PROTOCOL_TLS, + NDPI_PROTOCOL_DTLS); } diff --git a/src/lib/protocols/tocaboca.c b/src/lib/protocols/tocaboca.c index cf5c39af5..b69117104 100644 --- a/src/lib/protocols/tocaboca.c +++ b/src/lib/protocols/tocaboca.c @@ -1,7 +1,7 @@ /* * tocaboca.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -73,19 +73,14 @@ static void ndpi_search_toca_boca(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_toca_boca_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_toca_boca_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TocaBoca", ndpi_struct, *id, - NDPI_PROTOCOL_TOCA_BOCA, - ndpi_search_toca_boca, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TocaBoca", ndpi_struct, + ndpi_search_toca_boca, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_TOCA_BOCA); } diff --git a/src/lib/protocols/tplink_shp.c b/src/lib/protocols/tplink_shp.c index c4b68f71b..4961f5955 100644 --- a/src/lib/protocols/tplink_shp.c +++ b/src/lib/protocols/tplink_shp.c @@ -57,7 +57,7 @@ static void ndpi_search_tplink_shp(struct ndpi_detection_module_struct *ndpi_str if (packet->payload_packet_len - offset < _TPLSHP_MIN_LEN) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -72,7 +72,7 @@ static void ndpi_search_tplink_shp(struct ndpi_detection_module_struct *ndpi_str if (b[0] != '{' || (b[1] != '}' && b[1] != '"')) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -81,16 +81,10 @@ static void ndpi_search_tplink_shp(struct ndpi_detection_module_struct *ndpi_str /* ***************************************************** */ -void init_tplink_shp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_tplink_shp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TPLINK SHP", ndpi_struct, *id, - NDPI_PROTOCOL_TPLINK_SHP, - ndpi_search_tplink_shp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("TPLINK SHP", ndpi_struct, + ndpi_search_tplink_shp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TPLINK_SHP); } diff --git a/src/lib/protocols/trdp.c b/src/lib/protocols/trdp.c index 6cdbc7710..05185f3d5 100644 --- a/src/lib/protocols/trdp.c +++ b/src/lib/protocols/trdp.c @@ -80,17 +80,13 @@ static void ndpi_search_trdp(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_trdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_trdp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TRDP", ndpi_struct, *id, - NDPI_PROTOCOL_TRDP, - ndpi_search_trdp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("TRDP", ndpi_struct, + ndpi_search_trdp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_TRDP); } diff --git a/src/lib/protocols/tuya_lp.c b/src/lib/protocols/tuya_lp.c index d8488aa52..78726f276 100644 --- a/src/lib/protocols/tuya_lp.c +++ b/src/lib/protocols/tuya_lp.c @@ -48,21 +48,21 @@ static void ndpi_search_tuya_lp(struct ndpi_detection_module_struct *ndpi_struct if (packet->payload_packet_len < 16) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* https://github.com/tuya/tuya-iotos-embeded-sdk-wifi-ble-bk7231n/blob/0eff617610cc97e0d134bb8136cebb518a2a403b/sdk/include/lan_protocol.h#L73 */ if (ntohl(get_u_int32_t(packet->payload, 0)) != 0x000055AA) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if (packet->payload_packet_len < ntohl(get_u_int32_t(packet->payload, 4))) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -71,7 +71,7 @@ static void ndpi_search_tuya_lp(struct ndpi_detection_module_struct *ndpi_struct packet->payload[packet->payload_packet_len - 2] != 0xAA || packet->payload[packet->payload_packet_len - 1] != 0x55) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -80,16 +80,10 @@ static void ndpi_search_tuya_lp(struct ndpi_detection_module_struct *ndpi_struct /* ***************************************************** */ -void init_tuya_lp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_tuya_lp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("TUYA LP", ndpi_struct, *id, - NDPI_PROTOCOL_TUYA_LP, - ndpi_search_tuya_lp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("TUYA LP", ndpi_struct, + ndpi_search_tuya_lp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_TUYA_LP); } diff --git a/src/lib/protocols/ubntac2.c b/src/lib/protocols/ubntac2.c index 2b56c5aee..d3ff71a91 100644 --- a/src/lib/protocols/ubntac2.c +++ b/src/lib/protocols/ubntac2.c @@ -35,60 +35,47 @@ static void ndpi_int_ubntac2_add_connection(struct ndpi_detection_module_struct static void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int8_t tlv_type; + u_int16_t tlv_length, version_len; + int off; NDPI_LOG_DBG(ndpi_struct, "search ubntac2\n"); - NDPI_LOG_DBG2(ndpi_struct, "UBNTAC2 detection... plen:%i %i:%i\n", packet->payload_packet_len, ntohs(packet->udp->source), ntohs(packet->udp->dest)); - - if(packet->udp) { - if(packet->payload_packet_len >= 135 && - (packet->udp->source == htons(10001) || packet->udp->dest == htons(10001))) { - int found = 0; - - if(memcmp(&(packet->payload[36]), "UBNT", 4) == 0) { - found = 36+5; - } else if(memcmp(&(packet->payload[49]), "ubnt", 4) == 0) { - found = 49+5; - } - if(found) { - found += packet->payload[found+1] + 4; /* Skip model name */ - found++; /* Skip len */ - - if(found < packet->payload_packet_len) { - char version[256]; - int len; - u_int i, j; - - for(i=found, j=0; (i < packet->payload_packet_len) - && (i < (sizeof(version)-1)) - && (packet->payload[i] != 0); i++) - version[j++] = packet->payload[i]; - - version[j] = '\0'; - - len = ndpi_min(sizeof(flow->protos.ubntac2.version) - 1, j); - memcpy(flow->protos.ubntac2.version, (const char *)version, len); - flow->protos.ubntac2.version[len] = '\0'; - } - - NDPI_LOG_INFO(ndpi_struct, "UBNT AirControl 2 request\n"); - - ndpi_int_ubntac2_add_connection(ndpi_struct, flow); + if(packet->payload_packet_len >= 4 && + (packet->udp->source == htons(10001) || packet->udp->dest == htons(10001)) && + (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0206 || + ntohs(get_u_int16_t(packet->payload, 0)) == 0x0100 /* discovery request/reply */) && + (4 + ntohs(*(u_int16_t *)&packet->payload[2]) == packet->payload_packet_len)) { + NDPI_LOG_INFO(ndpi_struct, "UBNT AirControl 2 request\n"); + ndpi_int_ubntac2_add_connection(ndpi_struct, flow); + + /* Parse TLV list: 1 byte type + 2 byte length + (optional) data */ + off = 4; + while (off + 3 < packet->payload_packet_len) { + tlv_type = packet->payload[off]; + tlv_length = ntohs(*(u_int16_t *)&packet->payload[off + 1]); + + NDPI_LOG_DBG2(ndpi_struct, "0x%x Len %d\n", tlv_type, tlv_length); + + if(tlv_type == 0x03 && off + 3 + tlv_length < packet->payload_packet_len) { + version_len = ndpi_min(sizeof(flow->protos.ubntac2.version) - 1, tlv_length); + memcpy(flow->protos.ubntac2.version, (const char *)&packet->payload[off + 3], version_len); + flow->protos.ubntac2.version[version_len] = '\0'; } + + off += 3 + tlv_length; } + return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("UBNTAC2", ndpi_struct, *id, - NDPI_PROTOCOL_UBNTAC2, - ndpi_search_ubntac2, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; + register_dissector("UBNTAC2", ndpi_struct, + ndpi_search_ubntac2, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_UBNTAC2); } diff --git a/src/lib/protocols/uftp.c b/src/lib/protocols/uftp.c index efcfa64fd..898fd8be9 100644 --- a/src/lib/protocols/uftp.c +++ b/src/lib/protocols/uftp.c @@ -54,17 +54,13 @@ static void ndpi_search_uftp(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_uftp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_uftp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("UFTP", ndpi_struct, *id, - NDPI_PROTOCOL_UFTP, - ndpi_search_uftp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("UFTP", ndpi_struct, + ndpi_search_uftp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_UFTP); } diff --git a/src/lib/protocols/ultrasurf.c b/src/lib/protocols/ultrasurf.c index 05ba72764..620a17c4a 100644 --- a/src/lib/protocols/ultrasurf.c +++ b/src/lib/protocols/ultrasurf.c @@ -45,7 +45,7 @@ static void ndpi_search_ultrasurf(struct ndpi_detection_module_struct *ndpi_stru if (packet->payload_packet_len < 8) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -55,19 +55,13 @@ static void ndpi_search_ultrasurf(struct ndpi_detection_module_struct *ndpi_stru ndpi_int_ultrasurf_add_connection(ndpi_struct, flow); } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_ultrasurf_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_ultrasurf_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("UltraSurf", ndpi_struct, *id, - NDPI_PROTOCOL_ULTRASURF, - ndpi_search_ultrasurf, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("UltraSurf", ndpi_struct, + ndpi_search_ultrasurf, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ULTRASURF); } diff --git a/src/lib/protocols/usenet.c b/src/lib/protocols/usenet.c index 467ed1b4f..34bacb74b 100644 --- a/src/lib/protocols/usenet.c +++ b/src/lib/protocols/usenet.c @@ -2,7 +2,7 @@ * usenet.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -92,18 +92,14 @@ static void ndpi_search_usenet_tcp(struct ndpi_detection_module_struct *ndpi_str } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_usenet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_usenet_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Usenet", ndpi_struct, *id, - NDPI_PROTOCOL_USENET, - ndpi_search_usenet_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Usenet", ndpi_struct, + ndpi_search_usenet_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_USENET); } diff --git a/src/lib/protocols/vhua.c b/src/lib/protocols/vhua.c deleted file mode 100644 index c6af07406..000000000 --- a/src/lib/protocols/vhua.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * vhua.c - * - * Copyright (C) 2011-22 - ntop.org - * - * nDPI is free software: you can vhuatribute 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_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_VHUA - -#include "ndpi_api.h" -#include "ndpi_private.h" - -/* - http://www.vhua.com - - Skype-like Chinese phone protocol - - */ - - -static void ndpi_int_vhua_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VHUA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - NDPI_LOG_INFO(ndpi_struct, "found VHUA\n"); -} - - -static void ndpi_check_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - u_char p0[] = { 0x05, 0x14, 0x3a, 0x05, 0x08, 0xf8, 0xa1, 0xb1, 0x03 }; - - /* Break after 3 packets. */ - if((flow->packet_counter > 3) - || (packet->payload_packet_len < sizeof(p0))) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - } else if(memcmp(packet->payload, p0, sizeof(p0)) == 0) { - ndpi_int_vhua_add_connection(ndpi_struct, flow); - } -} - -static void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - NDPI_LOG_DBG(ndpi_struct, "search VHUA\n"); - - ndpi_check_vhua(ndpi_struct, flow); -} - - -void init_vhua_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("VHUA", ndpi_struct, *id, - NDPI_PROTOCOL_VHUA, - ndpi_search_vhua, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; -} - diff --git a/src/lib/protocols/viber.c b/src/lib/protocols/viber.c index 69741abff..7f56fcdea 100644 --- a/src/lib/protocols/viber.c +++ b/src/lib/protocols/viber.c @@ -45,7 +45,7 @@ static void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, if(packet->udp && packet->iph) { /* ignore broadcast as this isn't viber */ if((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -71,7 +71,7 @@ static void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -89,24 +89,20 @@ static void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } if(flow->packet_counter > 3) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_viber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_viber_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Viber", ndpi_struct, *id, - NDPI_PROTOCOL_VIBER, - ndpi_search_viber, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Viber", ndpi_struct, + ndpi_search_viber, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_VIBER); } diff --git a/src/lib/protocols/vmware.c b/src/lib/protocols/vmware.c index 31433e5e1..47214c197 100644 --- a/src/lib/protocols/vmware.c +++ b/src/lib/protocols/vmware.c @@ -41,17 +41,13 @@ static void ndpi_search_vmware(struct ndpi_detection_module_struct *ndpi_struct, return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_vmware_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_vmware_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("VMWARE", ndpi_struct, *id, - NDPI_PROTOCOL_VMWARE, - ndpi_search_vmware, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("VMWARE", ndpi_struct, + ndpi_search_vmware, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_VMWARE); } diff --git a/src/lib/protocols/vnc.c b/src/lib/protocols/vnc.c index 52c644224..d8d3bb143 100644 --- a/src/lib/protocols/vnc.c +++ b/src/lib/protocols/vnc.c @@ -57,18 +57,14 @@ static void ndpi_search_vnc_tcp(struct ndpi_detection_module_struct *ndpi_struct } } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_vnc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_vnc_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("VNC", ndpi_struct, *id, - NDPI_PROTOCOL_VNC, - ndpi_search_vnc_tcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("VNC", ndpi_struct, + ndpi_search_vnc_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_VNC); } diff --git a/src/lib/protocols/vxlan.c b/src/lib/protocols/vxlan.c index 04b3b3fbc..ab8383b03 100644 --- a/src/lib/protocols/vxlan.c +++ b/src/lib/protocols/vxlan.c @@ -1,7 +1,7 @@ /* * vxlan.c * - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -53,7 +53,7 @@ static void ndpi_check_vxlan(struct ndpi_detection_module_struct *ndpi_struct, s } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -64,14 +64,10 @@ static void ndpi_search_vxlan(struct ndpi_detection_module_struct *ndpi_struct, ndpi_check_vxlan(ndpi_struct, flow); } -void init_vxlan_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_vxlan_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("VXLAN", ndpi_struct, *id, - NDPI_PROTOCOL_VXLAN, - ndpi_search_vxlan, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("VXLAN", ndpi_struct, + ndpi_search_vxlan, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_VXLAN); } diff --git a/src/lib/protocols/warcraft3.c b/src/lib/protocols/warcraft3.c deleted file mode 100644 index 768c3da74..000000000 --- a/src/lib/protocols/warcraft3.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * warcraft3.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_WARCRAFT3 - -#include "ndpi_api.h" -#include "ndpi_private.h" - -static void ndpi_int_warcraft3_add_connection(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WARCRAFT3, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - -static void ndpi_search_warcraft3(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - u_int16_t l; /* - Leave it as u_int32_t because otherwise 'u_int16_t temp' - might overflood it and thus generate an infinite loop - */ - - NDPI_LOG_DBG(ndpi_struct, "search WARCRAFT3\n"); - - - if (flow->packet_counter == 1 && packet->payload_packet_len == 1 && packet->payload[0] == 0x01) { - NDPI_LOG_DBG2(ndpi_struct, "maybe warcraft3: packet_len == 1\n"); - return; - } else if (packet->payload_packet_len >= 4 && (packet->payload[0] == 0xf7 || packet->payload[0] == 0xff)) { - - NDPI_LOG_DBG2(ndpi_struct, "packet_payload begins with 0xf7 or 0xff\n"); - - l = packet->payload[2] + (packet->payload[3] << 8); // similar to ntohs - - NDPI_LOG_DBG2(ndpi_struct, "l = %u \n", l); - - while (l <= (packet->payload_packet_len - 4)) { - if (packet->payload[l] == 0xf7) { - u_int16_t temp = (packet->payload[l + 2 + 1] << 8) + packet->payload[l + 2]; - NDPI_LOG_DBG2(ndpi_struct, "another f7 visited\n"); - - if((temp <= 2) || (temp > 1500)) { - NDPI_LOG_DBG2(ndpi_struct, "break\n"); - break; - } else { - l += temp; - NDPI_LOG_DBG2(ndpi_struct, "l = %u \n", l); - } - } else { - NDPI_LOG_DBG2(ndpi_struct, "break\n"); - break; - } - } - - if (l == packet->payload_packet_len) { - NDPI_LOG_DBG2(ndpi_struct, "maybe WARCRAFT3 flow->packet_counter = %u \n", - flow->packet_counter); - if (flow->packet_counter > 2) { - NDPI_LOG_INFO(ndpi_struct, "found WARCRAFT3\n"); - ndpi_int_warcraft3_add_connection(ndpi_struct, flow); - return; - } - return; - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_warcraft3_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("Warcraft3", ndpi_struct, *id, - NDPI_PROTOCOL_WARCRAFT3, - ndpi_search_warcraft3, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - diff --git a/src/lib/protocols/websocket.c b/src/lib/protocols/websocket.c index 47af111d8..fc8a89231 100644 --- a/src/lib/protocols/websocket.c +++ b/src/lib/protocols/websocket.c @@ -63,7 +63,7 @@ static void ndpi_check_websocket(struct ndpi_detection_module_struct *ndpi_struc if (packet->payload_packet_len < sizeof(u_int16_t)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -74,8 +74,8 @@ static void ndpi_check_websocket(struct ndpi_detection_module_struct *ndpi_struc if (packet->payload_packet_len != hdr_size + websocket_payload_length) { - NDPI_LOG_DBG(ndpi_struct, "Invalid WEBSOCKET payload"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_LOG_DBG(ndpi_struct, "Invalid WEBSOCKET payload\n"); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -88,18 +88,18 @@ static void ndpi_check_websocket(struct ndpi_detection_module_struct *ndpi_struc set_websocket_detected(ndpi_struct, flow); } else { - NDPI_LOG_DBG(ndpi_struct, "Invalid WEBSOCKET payload"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_LOG_DBG(ndpi_struct, "Invalid WEBSOCKET payload\n"); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } static void ndpi_search_websocket(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - // Break after 6 packets. + // Break after 10 packets. if (flow->packet_counter > 10) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -112,28 +112,33 @@ static void ndpi_search_websocket(struct ndpi_detection_module_struct *ndpi_stru { struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; uint16_t i; + int found = 0; NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); for (i = 0; i < packet->parsed_lines; i++) { if (LINE_STARTS(packet->line[i], "upgrade:") != 0 && LINE_ENDS(packet->line[i], "websocket") != 0) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WEBSOCKET, - NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); + if(found == 0) + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WEBSOCKET, + NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); + found = 1; } else if (LINE_STARTS(packet->line[i], "sec-websocket") != 0) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WEBSOCKET, - NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); + if(found == 0) + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WEBSOCKET, + NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); if (ndpi_strncasestr((const char *)packet->line[i].ptr, "chisel", packet->line[i].len) != NULL) { ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Obfuscated SSH-in-HTTP-WebSocket traffic"); } + found = 1; } } if (i == packet->parsed_lines) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } } @@ -143,11 +148,10 @@ static void ndpi_search_websocket(struct ndpi_detection_module_struct *ndpi_stru /* ********************************* */ -void init_websocket_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_websocket_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("WEBSOCKET", ndpi_struct, *id, NDPI_PROTOCOL_WEBSOCKET, - ndpi_search_websocket, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("WEBSOCKET", ndpi_struct, + ndpi_search_websocket, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_WEBSOCKET); } diff --git a/src/lib/protocols/whatsapp.c b/src/lib/protocols/whatsapp.c index 2a9564501..f53dbfce3 100644 --- a/src/lib/protocols/whatsapp.c +++ b/src/lib/protocols/whatsapp.c @@ -93,7 +93,7 @@ static void ndpi_search_whatsapp(struct ndpi_detection_module_struct *ndpi_struc if (flow->packet_counter > 3) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -116,20 +116,14 @@ static void ndpi_search_whatsapp(struct ndpi_detection_module_struct *ndpi_struc return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_whatsapp_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_whatsapp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection( - "WhatsApp", ndpi_struct, *id, - NDPI_PROTOCOL_WHATSAPP, - ndpi_search_whatsapp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - *id += 1; + register_dissector("WhatsApp", ndpi_struct, + ndpi_search_whatsapp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_WHATSAPP); } diff --git a/src/lib/protocols/whoisdas.c b/src/lib/protocols/whoisdas.c index c5450d1a1..00e6e7ff7 100644 --- a/src/lib/protocols/whoisdas.c +++ b/src/lib/protocols/whoisdas.c @@ -49,18 +49,14 @@ static void ndpi_search_whois_das(struct ndpi_detection_module_struct *ndpi_stru } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_whois_das_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_whois_das_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Whois-DAS", ndpi_struct, *id, - NDPI_PROTOCOL_WHOIS_DAS, - ndpi_search_whois_das, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Whois-DA", ndpi_struct, + ndpi_search_whois_das, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_WHOIS_DAS); } diff --git a/src/lib/protocols/wireguard.c b/src/lib/protocols/wireguard.c index 90d814464..57ad347c3 100644 --- a/src/lib/protocols/wireguard.c +++ b/src/lib/protocols/wireguard.c @@ -82,14 +82,14 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru * Note that handshake packets have a slightly different structure, but they are larger. */ if (packet->payload_packet_len < 32) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } /* * The next three bytes after the message type are reserved and set to zero. */ if (payload[1] != 0 || payload[2] != 0 || payload[3] != 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -139,12 +139,13 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru u_int32_t receiver_index = get_u_int32_t(payload, 8); if (receiver_index == flow->l4.udp.wireguard_peer_index[1 - packet->packet_direction]) { - if(packet->payload_packet_len == 100) + if(packet->payload_packet_len == 100 && + ndpi_struct->cfg.wireguard_subclassification_by_ip /* TODO: the right option? */) ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TUNNELBEAR); else ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* need more packets before deciding */ @@ -160,7 +161,7 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru if (receiver_index == flow->l4.udp.wireguard_peer_index[1 - packet->packet_direction]) { ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* need more packets before deciding */ @@ -188,23 +189,19 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru if (receiver_index == flow->l4.udp.wireguard_peer_index[packet->packet_direction]) { ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } /* need more packets before deciding */ } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_wireguard_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_wireguard_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("WireGuard", ndpi_struct, *id, - NDPI_PROTOCOL_WIREGUARD, - ndpi_search_wireguard, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("WireGuard", ndpi_struct, + ndpi_search_wireguard, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_WIREGUARD); } diff --git a/src/lib/protocols/world_of_kung_fu.c b/src/lib/protocols/world_of_kung_fu.c deleted file mode 100644 index dc867ea5e..000000000 --- a/src/lib/protocols/world_of_kung_fu.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * world_of_kung_fu.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_WORLD_OF_KUNG_FU -#include "ndpi_api.h" -#include "ndpi_private.h" - - -static void ndpi_int_world_of_kung_fu_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WORLD_OF_KUNG_FU, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - -static void ndpi_search_world_of_kung_fu(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search world_of_kung_fu\n"); - - if ((packet->payload_packet_len == 16) - && ntohl(get_u_int32_t(packet->payload, 0)) == 0x0c000000 && ntohl(get_u_int32_t(packet->payload, 4)) == 0xd2000c00 - && (packet->payload[9] - == 0x16) && ntohs(get_u_int16_t(packet->payload, 10)) == 0x0000 && ntohs(get_u_int16_t(packet->payload, 14)) == 0x0000) { - NDPI_LOG_INFO(ndpi_struct, "detected world_of_kung_fu\n"); - ndpi_int_world_of_kung_fu_add_connection(ndpi_struct, flow); - return; - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_world_of_kung_fu_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("WorldOfKungFu", ndpi_struct, *id, - NDPI_PROTOCOL_WORLD_OF_KUNG_FU, - ndpi_search_world_of_kung_fu, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} diff --git a/src/lib/protocols/world_of_warcraft.c b/src/lib/protocols/world_of_warcraft.c deleted file mode 100644 index e0e8dba08..000000000 --- a/src/lib/protocols/world_of_warcraft.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * world_of_warcraft.c - * - * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_WORLDOFWARCRAFT - -#include "ndpi_api.h" -#include "ndpi_private.h" - -static void ndpi_int_worldofwarcraft_add_connection(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) -{ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WORLDOFWARCRAFT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); -} - - -#if !defined(WIN32) -static inline -#elif defined(MINGW_GCC) -__mingw_forceinline static -#else -__forceinline static -#endif -u_int8_t ndpi_int_is_wow_port(const u_int16_t port) -{ - if (port == htons(3724) || port == htons(6112) || port == htons(6113) || - port == htons(6114) || port == htons(4000) || port == htons(1119)) { - return 1; - } - return 0; -} - -static void ndpi_search_worldofwarcraft(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - - NDPI_LOG_DBG(ndpi_struct, "search World of Warcraft\n"); - - if (packet->tcp != NULL) { - /* - if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /") && - memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) || - (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") && - memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0)) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - if (packet->user_agent_line.ptr != NULL && - packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Blizzard Web Client") && - memcmp(packet->user_agent_line.ptr, "Blizzard Web Client", - NDPI_STATICSTRING_LEN("Blizzard Web Client")) == 0) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_DBG(ndpi_struct, "World of Warcraft: Web Client found\n"); - return; - } - } - */ - if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") - && memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) { - ndpi_parse_packet_line_info(ndpi_struct, flow); - if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL - && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Blizzard Downloader") - && packet->host_line.len > NDPI_STATICSTRING_LEN("worldofwarcraft.com") - && memcmp(packet->user_agent_line.ptr, "Blizzard Downloader", - NDPI_STATICSTRING_LEN("Blizzard Downloader")) == 0 - && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("worldofwarcraft.com")], - "worldofwarcraft.com", NDPI_STATICSTRING_LEN("worldofwarcraft.com")) == 0) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, - "World of Warcraft: Web Client found\n"); - return; - } - } - if (packet->payload_packet_len == 50 && memcmp(&packet->payload[2], "WORLD OF WARCRAFT CONNECTION", - NDPI_STATICSTRING_LEN("WORLD OF WARCRAFT CONNECTION")) == 0) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: Login found\n"); - return; - } - if (packet->tcp->dest == htons(3724) && packet->payload_packet_len < 70 - && packet->payload_packet_len > 40 && (memcmp(&packet->payload[4], "WoW", 3) == 0 - || memcmp(&packet->payload[5], "WoW", 3) == 0)) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: Login found\n"); - return; - } - - if (packet->tcp->source == htons(3724) - && packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 0) == htonl(0x0006ec01)) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: connection detected\n"); - return; - } - - /* for some well known WoW ports - check another pattern */ - if (flow->l4.tcp.wow_stage == 0) { - if (ndpi_int_is_wow_port(packet->tcp->source) && - packet->payload_packet_len >= 14 && - ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) { - if (get_u_int32_t(packet->payload, 2) == htonl(0xec010100)) { - - NDPI_LOG_DBG2(ndpi_struct, "probably World of Warcraft, waiting for final packet\n"); - flow->l4.tcp.wow_stage = 2; - return; - } else if (packet->payload_packet_len == 41 && - (get_u_int16_t(packet->payload, 2) == htons(0x0085) || - get_u_int16_t(packet->payload, 2) == htons(0x0034) || - get_u_int16_t(packet->payload, 2) == htons(0x1960))) { - NDPI_LOG_DBG2(ndpi_struct, "maybe World of Warcraft, need next\n"); - flow->l4.tcp.wow_stage = 1; - return; - } - } - } - - if (flow->l4.tcp.wow_stage == 1) { - if (packet->payload_packet_len == 325 && - ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2) && - get_u_int16_t(packet->payload, 4) == 0 && - (get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x2331) || - get_u_int16_t(packet->payload, 67) == htons(0x2331)) && - (memcmp - (&packet->payload[packet->payload_packet_len - 18], - "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0 - || memcmp(&packet->payload[packet->payload_packet_len - 30], - "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0)) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: connection detected\n"); - return; - } - if (packet->payload_packet_len > 32 && - ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) { - if (get_u_int16_t(packet->payload, 4) == 0) { - - NDPI_LOG_DBG2(ndpi_struct, "probably World of Warcraft, waiting for final packet\n"); - flow->l4.tcp.wow_stage = 2; - return; - } else if (get_u_int32_t(packet->payload, 2) == htonl(0x12050000)) { - NDPI_LOG_DBG2(ndpi_struct, "probably World of Warcraft, waiting for final packet\n"); - flow->l4.tcp.wow_stage = 2; - return; - } - } - } - - if (flow->l4.tcp.wow_stage == 2) { - if (packet->payload_packet_len == 4) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: connection detected\n"); - return; - } else if (packet->payload_packet_len > 4 && packet->payload_packet_len <= 16 && packet->payload[4] == 0x0c) { - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: connection detected\n"); - return; - } else if (flow->packet_counter < 3) { - NDPI_LOG_DBG2(ndpi_struct, "waiting for final packet\n"); - return; - } - } - if (flow->l4.tcp.wow_stage == 0 && packet->tcp->dest == htons(1119)) { - /* special log in port for battle.net/world of warcraft */ - - if (packet->payload_packet_len >= 77 && - get_u_int32_t(packet->payload, 0) == htonl(0x40000aed) && get_u_int32_t(packet->payload, 4) == htonl(0xea070aed)) { - - ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow); - NDPI_LOG_INFO(ndpi_struct, "World of Warcraft: connection detected\n"); - return; - } - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_world_of_warcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) -{ - ndpi_set_bitmask_protocol_detection("WorldOfWarcraft", ndpi_struct, *id, - NDPI_PROTOCOL_WORLDOFWARCRAFT, - ndpi_search_worldofwarcraft, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - diff --git a/src/lib/protocols/wsd.c b/src/lib/protocols/wsd.c index a15ff10d0..16b6fe2a5 100644 --- a/src/lib/protocols/wsd.c +++ b/src/lib/protocols/wsd.c @@ -48,18 +48,15 @@ static void ndpi_search_wsd(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_INFO(ndpi_struct,"found wsd\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WSD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } } -void init_wsd_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("WSD", ndpi_struct, *id, - NDPI_PROTOCOL_WSD, - ndpi_search_wsd, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_wsd_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("WSD", ndpi_struct, + ndpi_search_wsd, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_WSD); } diff --git a/src/lib/protocols/xbox.c b/src/lib/protocols/xbox.c index f1f334316..29248cf82 100644 --- a/src/lib/protocols/xbox.c +++ b/src/lib/protocols/xbox.c @@ -94,19 +94,15 @@ static void ndpi_search_xbox(struct ndpi_detection_module_struct *ndpi_struct, s } if(flow->packet_counter >= 5) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_xbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_xbox_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Xbox", ndpi_struct, *id, - NDPI_PROTOCOL_XBOX, - ndpi_search_xbox, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Xbox", ndpi_struct, + ndpi_search_xbox, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_XBOX); } diff --git a/src/lib/protocols/xdmcp.c b/src/lib/protocols/xdmcp.c index f90877a38..7aadb0f28 100644 --- a/src/lib/protocols/xdmcp.c +++ b/src/lib/protocols/xdmcp.c @@ -2,7 +2,7 @@ * xdmcp.c * * Copyright (C) 2009-11 - ipoque GmbH - * Copyright (C) 2011-22 - ntop.org + * Copyright (C) 2011-25 - 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 @@ -61,18 +61,14 @@ static void ndpi_search_xdmcp(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_xdmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_xdmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("XDMCP", ndpi_struct, *id, - NDPI_PROTOCOL_XDMCP, - ndpi_search_xdmcp, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("XDMCP", ndpi_struct, + ndpi_search_xdmcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_XDMCP); } diff --git a/src/lib/protocols/xiaomi.c b/src/lib/protocols/xiaomi.c index 04b24c986..baf8e31d5 100644 --- a/src/lib/protocols/xiaomi.c +++ b/src/lib/protocols/xiaomi.c @@ -107,16 +107,12 @@ static void ndpi_search_xiaomi(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_xiaomi_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Xiaomi", ndpi_struct, *id, - NDPI_PROTOCOL_XIAOMI, - ndpi_search_xiaomi, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - *id += 1; +void init_xiaomi_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Xiaomi", ndpi_struct, + ndpi_search_xiaomi, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_XIAOMI); } diff --git a/src/lib/protocols/yojimbo.c b/src/lib/protocols/yojimbo.c index 9434bb5ee..5b2440f11 100644 --- a/src/lib/protocols/yojimbo.c +++ b/src/lib/protocols/yojimbo.c @@ -46,7 +46,7 @@ static void ndpi_search_yojimbo(struct ndpi_detection_module_struct *ndpi_struct if (packet->payload_packet_len < 9) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -57,19 +57,14 @@ static void ndpi_search_yojimbo(struct ndpi_detection_module_struct *ndpi_struct return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_yojimbo_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_yojimbo_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Yojimbo", ndpi_struct, *id, - NDPI_PROTOCOL_YOJIMBO, - ndpi_search_yojimbo, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Yojimbo", ndpi_struct, + ndpi_search_yojimbo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_YOJIMBO); } diff --git a/src/lib/protocols/z3950.c b/src/lib/protocols/z3950.c index 92eed01b0..99292e4fa 100644 --- a/src/lib/protocols/z3950.c +++ b/src/lib/protocols/z3950.c @@ -94,7 +94,7 @@ static void ndpi_search_z3950(struct ndpi_detection_module_struct *ndpi_struct, int ret = z3950_parse_sequences(packet, minimum_expected_sequences); if(ret < 0) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -103,30 +103,25 @@ static void ndpi_search_z3950(struct ndpi_detection_module_struct *ndpi_struct, return; } - if(flow->z3950_stage == 3) { + if(flow->l4.tcp.z3950_stage == 3) { if(flow->packet_direction_counter[0] && flow->packet_direction_counter[1]) ndpi_int_z3950_add_connection(ndpi_struct, flow); else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); /* Skip if unidirectional traffic */ + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); /* Skip if unidirectional traffic */ } else - flow->z3950_stage++; + flow->l4.tcp.z3950_stage++; return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************************** */ -void init_z3950_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Z3950", - ndpi_struct, *id, - NDPI_PROTOCOL_Z3950, - ndpi_search_z3950, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_z3950_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Z3950", ndpi_struct, + ndpi_search_z3950, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_Z3950); } diff --git a/src/lib/protocols/zabbix.c b/src/lib/protocols/zabbix.c index 84e466de5..470bafd39 100644 --- a/src/lib/protocols/zabbix.c +++ b/src/lib/protocols/zabbix.c @@ -45,18 +45,14 @@ static void ndpi_search_zabbix(struct ndpi_detection_module_struct *ndpi_struct, && (memcmp(packet->payload, tomatch, 4) == 0)) ndpi_int_zabbix_add_connection(ndpi_struct, flow); else - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* *************************************************** */ -void init_zabbix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Zabbix", ndpi_struct, *id, - NDPI_PROTOCOL_ZABBIX, - ndpi_search_zabbix, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_zabbix_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Zabbix", ndpi_struct, + ndpi_search_zabbix, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ZABBIX); } diff --git a/src/lib/protocols/zattoo.c b/src/lib/protocols/zattoo.c index aba720243..e285ee47a 100644 --- a/src/lib/protocols/zattoo.c +++ b/src/lib/protocols/zattoo.c @@ -204,18 +204,14 @@ static void ndpi_search_zattoo(struct ndpi_detection_module_struct *ndpi_struct, } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_zattoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_zattoo_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Zattoo", ndpi_struct, *id, - NDPI_PROTOCOL_ZATTOO, - ndpi_search_zattoo, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("Zattoo", ndpi_struct, + ndpi_search_zattoo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ZATTOO); } diff --git a/src/lib/protocols/zeromq.c b/src/lib/protocols/zeromq.c index d90d36a68..b79a004b1 100644 --- a/src/lib/protocols/zeromq.c +++ b/src/lib/protocols/zeromq.c @@ -24,79 +24,31 @@ #include "ndpi_api.h" #include "ndpi_private.h" -static void ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - NDPI_LOG_INFO(ndpi_struct, "found ZMQ\n"); -} - - -static void ndpi_check_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { +static const u_int8_t zmtp_signature[] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7F }; - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - u_int32_t payload_len = packet->payload_packet_len; - u_char p0[] = { 0x00, 0x00, 0x00, 0x05, 0x01, 0x66, 0x6c, 0x6f, 0x77 }; - u_char p1[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f }; - u_char p2[] = { 0x28, 0x66, 0x6c, 0x6f, 0x77, 0x00 }; +static void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; - /* Break after 10 packets. */ - if(flow->packet_counter > 10) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } + NDPI_LOG_DBG(ndpi_struct, "search ZMQ\n"); - if(flow->l4.tcp.prev_zmq_pkt_len == 0) { - flow->l4.tcp.prev_zmq_pkt_len = ndpi_min(packet->payload_packet_len, 10); - memcpy(flow->l4.tcp.prev_zmq_pkt, packet->payload, flow->l4.tcp.prev_zmq_pkt_len); - return; /* Too early */ - } - if(payload_len == 2) { - if(flow->l4.tcp.prev_zmq_pkt_len == 2) { - if((memcmp(packet->payload, "\01\01", 2) == 0) - && (memcmp(flow->l4.tcp.prev_zmq_pkt, "\01\02", 2) == 0)) { - ndpi_int_zmq_add_connection(ndpi_struct, flow); - return; - } - } else if(flow->l4.tcp.prev_zmq_pkt_len == 9) { - if((memcmp(packet->payload, "\00\00", 2) == 0) - && (memcmp(flow->l4.tcp.prev_zmq_pkt, p0, 9) == 0)) { - ndpi_int_zmq_add_connection(ndpi_struct, flow); - return; - } - } else if(flow->l4.tcp.prev_zmq_pkt_len == 10) { - if((memcmp(packet->payload, "\01\02", 2) == 0) - && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) { - ndpi_int_zmq_add_connection(ndpi_struct, flow); - return; - } - } - } else if(payload_len >= 10) { - if(flow->l4.tcp.prev_zmq_pkt_len == 10) { - if(((memcmp(packet->payload, p1, 10) == 0) - && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) - || ((memcmp(&packet->payload[1], p2, sizeof(p2)) == 0) - && (memcmp(&flow->l4.tcp.prev_zmq_pkt[1], p2, sizeof(p2)) == 0))) { - ndpi_int_zmq_add_connection(ndpi_struct, flow); - return; - } + if (packet->payload_packet_len > 9) { + if (memcmp(packet->payload, zmtp_signature, sizeof(zmtp_signature)) == 0) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, + NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + NDPI_LOG_INFO(ndpi_struct, "found ZMQ\n"); + return; } } -} -static void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - NDPI_LOG_DBG(ndpi_struct, "search ZMQ\n"); - - ndpi_check_zmq(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) +void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("ZeroMQ", ndpi_struct, *id, - NDPI_PROTOCOL_ZMQ, - ndpi_search_zmq, /* TODO: add UDP support */ - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("ZeroMQ", ndpi_struct, + ndpi_search_zmq, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + 1, NDPI_PROTOCOL_ZMQ); } diff --git a/src/lib/protocols/zoom.c b/src/lib/protocols/zoom.c index a115fe37b..e573fc8f1 100644 --- a/src/lib/protocols/zoom.c +++ b/src/lib/protocols/zoom.c @@ -242,18 +242,14 @@ static void ndpi_search_zoom(struct ndpi_detection_module_struct *ndpi_struct, } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* *************************************************** */ -void init_zoom_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { - ndpi_set_bitmask_protocol_detection("Zoom", ndpi_struct, *id, - NDPI_PROTOCOL_ZOOM, - ndpi_search_zoom, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; +void init_zoom_dissector(struct ndpi_detection_module_struct *ndpi_struct) { + register_dissector("Zoom", ndpi_struct, + ndpi_search_zoom, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ZOOM); } diff --git a/src/lib/protocols/zug.c b/src/lib/protocols/zug.c index b4f6b2e16..3a135648b 100644 --- a/src/lib/protocols/zug.c +++ b/src/lib/protocols/zug.c @@ -44,7 +44,7 @@ static void ndpi_search_zug(struct ndpi_detection_module_struct *ndpi_struct, if (packet->payload_packet_len < 5) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); return; } @@ -55,19 +55,14 @@ static void ndpi_search_zug(struct ndpi_detection_module_struct *ndpi_struct, return; } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } -void init_zug_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_zug_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("ZUG", ndpi_struct, *id, - NDPI_PROTOCOL_ZUG, - ndpi_search_zug, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; + register_dissector("ZUG", ndpi_struct, + ndpi_search_zug, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_ZUG); } |