aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c2
-rw-r--r--src/include/ndpi_protocol_ids.h4
-rw-r--r--src/include/ndpi_protocols.h6
-rw-r--r--src/include/ndpi_typedefs.h19
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/ndpi_main.c16
-rw-r--r--src/lib/protocols/coap.c110
-rw-r--r--src/lib/protocols/mqtt.c215
8 files changed, 370 insertions, 4 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 082871346..e5119692b 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -113,7 +113,7 @@ static u_int8_t undetected_flows_deleted = 0;
/**
* User preferences
*/
-static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 0, json_flag = 0;
+static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 2, json_flag = 0;
static u_int16_t decode_tunnels = 0;
static u_int16_t num_loops = 1;
static u_int8_t shutdown_app = 0, quiet_mode = 0;
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index b7e620076..59707896b 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -270,9 +270,11 @@
#define NDPI_SERVICE_OFFICE_365 219
#define NDPI_SERVICE_CLOUDFLARE 220
#define NDPI_SERVICE_MS_ONE_DRIVE 221
+#define NDPI_PROTOCOL_COAP 222
+#define NDPI_PROTOCOL_MQTT 223
/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */
-#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_SERVICE_MS_ONE_DRIVE
+#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MQTT
#define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1)
#define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL)
diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h
index 7fc165281..b6ceed257 100644
--- a/src/include/ndpi_protocols.h
+++ b/src/include/ndpi_protocols.h
@@ -197,7 +197,8 @@ void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struc
void ndpi_search_mpegts(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_starcraft(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
-
+void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
/* --- INIT FUNCTIONS --- */
void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
@@ -337,5 +338,6 @@ void init_zattoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_i
void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_stracraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
-
+void init_coap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct,u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
#endif /* __NDPI_PROTOCOLS_H__ */
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 620c9685d..4fe8d5712 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -345,6 +345,14 @@ typedef enum {
HTTP_METHOD_CONNECT
} ndpi_http_method;
+typedef enum {
+ COAP_METHOD_UNKNOWN = 0,
+ COAP_METHOD_GET,
+ COAP_METHOD_POST,
+ COAP_METHOD_PUT,
+ COAP_METHOD_DELETE
+} ndpi_coap_method;
+
struct ndpi_id_struct {
/**
detected_protocol_bitmask:
@@ -576,6 +584,9 @@ struct ndpi_flow_tcp_struct {
u_int8_t prev_zmq_pkt_len;
u_char prev_zmq_pkt[10];
#endif
+#ifdef NDPI_PROTOCOL_MQTT
+ u_int8_t mqtt_stage:2;
+#endif
}
#ifndef WIN32
__attribute__ ((__packed__))
@@ -625,6 +636,9 @@ struct ndpi_flow_udp_struct {
u_int8_t eaq_pkt_id;
u_int32_t eaq_sequence;
#endif
+#ifdef NDPI_PROTOCOL_COAP
+ u_int32_t coap_stage:2;
+#endif
}
#ifndef WIN32
__attribute__ ((__packed__))
@@ -907,6 +921,11 @@ struct ndpi_flow_struct {
char *url, *content_type;
} http;
+ struct {
+ ndpi_coap_method method;
+ char *url, *content_type;
+ } coap;
+
union {
/* the only fields useful for nDPI and ntopng */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 66bb0c0e9..2e8b0551a 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -153,6 +153,8 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/yahoo.c \
protocols/zattoo.c \
protocols/zeromq.c \
+ protocols/coap.c \
+ protocols/mqtt.c \
third_party/include/actypes.h \
third_party/include/ahocorasick.h \
third_party/include/node.h \
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index a5fab256e..8d40fe9aa 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1523,6 +1523,16 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master, "Viber",
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
ndpi_build_default_ports(ports_b, 7985, 7987, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_COAP,
+ no_master,
+ no_master, "COAP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 5683, 5684, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_MQTT,
+ no_master,
+ no_master, "MQTT",
+ ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
/* calling function for host and content matched protocols */
init_string_based_protocols(ndpi_mod);
@@ -2487,6 +2497,12 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* UBNTAC2 */
init_ubntac2_dissector(ndpi_struct, &a, detection_bitmask);
+ /* COAP */
+ init_coap_dissector(ndpi_struct, &a, detection_bitmask);
+
+ /* MQTT */
+ init_mqtt_dissector(ndpi_struct, &a, detection_bitmask);
+
/* Put false-positive sensitive protocols at the end */
/* SKYPE */
diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c
new file mode 100644
index 000000000..8089c8159
--- /dev/null
+++ b/src/lib/protocols/coap.c
@@ -0,0 +1,110 @@
+/*
+ * coap.c
+ *
+ * Copyright (C) 2016 Sorin Zamfir <sorin.zamfir@yahoo.com>
+ *
+ * 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_protocols.h"
+#ifdef NDPI_PROTOCOL_COAP
+
+/**
+ * Entry point when protocol is identified.
+ */
+static void ndpi_int_coap_add_connection (struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ // not sure if this is accurate but coap runs on top of udp and should be connectionless
+ ndpi_set_detected_protocol(ndpi_struct,flow,NDPI_PROTOCOL_COAP,NDPI_PROTOCOL_UNKNOWN);
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "CoAP found.\n");
+}
+/**
+ * Dissector function that searches CoAP headers
+ */
+void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "CoAP detection...\n");
+ // searching for request
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "====>>>> COAP header: %04x%04x%04x%04x [len: %u]\n",
+ packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3], packet->payload_packet_len);
+ // check if we have version bits
+ if (packet->payload_packet_len < 4) {
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap .. mandatory header not found!\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP);
+ return;
+ }
+ // since this is always unsigned we could have spared the 0xF0 logical AND
+ // vt = version and type (version is mandatory 1; type is either 0,1,2,3 )
+ u_int8_t vt = (u_int8_t) ((packet->payload[0] & 0xF0) >> 4);
+ if ((vt == 4) || (vt == 5) || (vt == 6) || (vt == 7)) {
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Continuing Coap detection \n");
+ // search for values 9 to 15 in the token length
+ u_int8_t tkl = (u_int8_t) ((packet->payload[0] & 0x0F));
+ if ((tkl >= 9) && (tkl <= 15)) {
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap .. invalid token length found!\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP);
+ return;
+ }
+ u_int8_t class = (u_int8_t) ((packet->payload[1] & 0xE0) >> 5);
+ u_int8_t detail = (u_int8_t) ((packet->payload[1] & 0x1F));
+ if ((class == 0) && (detail == 0) && (tkl == 0) && (packet->payload_packet_len == 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found ... empty message\n");
+ ndpi_int_coap_add_connection(ndpi_struct,flow);
+ return;
+ }
+ if ((class == 0) && ((detail == 1) || (detail == 2 ) || (detail == 3 ) || (detail == 4 ))) {
+ // we should probably search for options as well and payload for deeper inspection
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found ... req message\n");
+ ndpi_int_coap_add_connection(ndpi_struct,flow);
+ return;
+ }
+ if ((class == 2) || (class == 4) || (class == 5)) {
+ // we should probably search for options as well and payload for deeper inspection
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found ... resp message\n");
+ ndpi_int_coap_add_connection(ndpi_struct,flow);
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap ...\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP);
+ return;
+
+}
+/**
+ * Entry point for the ndpi library
+ */
+void init_coap_dissector (struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
+{
+ ndpi_set_bitmask_protocol_detection ("COAP", ndpi_struct, detection_bitmask, *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;
+}
+
+
+#endif // NDPI_PROTOCOL_COAP
diff --git a/src/lib/protocols/mqtt.c b/src/lib/protocols/mqtt.c
new file mode 100644
index 000000000..238f07e64
--- /dev/null
+++ b/src/lib/protocols/mqtt.c
@@ -0,0 +1,215 @@
+/*
+ * mqtt.c
+ *
+ * Copyright (C) 2016 Sorin Zamfir <sorin.zamfir@yahoo.com>
+ *
+ * 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_protocols.h"
+#ifdef NDPI_PROTOCOL_MQTT
+
+/**
+ * The type of control messages in mqtt version 3.1.1
+ * see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1
+ */
+enum MQTT_PACKET_TYPES {
+ CONNECT = 1,
+ CONNACK = 2,
+ PUBLISH = 3,
+ PUBACK = 4,
+ PUBREC = 5,
+ PUBREL = 6,
+ PUBCOMP = 7,
+ SUBSCRIBE = 8,
+ SUBACK = 9,
+ UNSUBSCRIBE = 10,
+ UNSUBACK = 11,
+ PINGREQ = 12,
+ PINGRESP = 13,
+ DISCONNECT = 14
+};
+
+
+/**
+ * Entry point when protocol is identified.
+ */
+static void ndpi_int_mqtt_add_connection (struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ ndpi_set_detected_protocol(ndpi_struct,flow,NDPI_PROTOCOL_MQTT,NDPI_PROTOCOL_UNKNOWN);
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found.\n");
+}
+
+/**
+ * Dissector function that searches Mqtt headers
+ */
+void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt search called...\n");
+ struct ndpi_packet_struct *packet = &flow->packet;
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt detection...\n");
+ if (flow->packet_counter > 10) {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt .. mandatory header not found!\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+
+ // searching for request
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "====>>>> Mqtt header: %4x%4x%4x%4x [len: %u]\n",
+ packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3], packet->payload_packet_len);
+ if (packet->payload_packet_len < 2) {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt .. mandatory header not found!\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ // we first extract the packet type
+ u_int8_t pt = (u_int8_t) ((packet->payload[0] & 0xF0) >> 4);
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Mqtt packet type: [%d]\n",pt);
+ if ((pt == 0) || (pt == 15)) {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt .. invalid packet type!\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ u_int8_t flags = (u_int8_t) (packet->payload[0] & 0x0F);
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Mqtt flags type: [%d]\n",flags);
+ // first stage verification
+ if ((pt == CONNECT) || (pt == CONNACK) || (pt == PUBACK) || (pt == PUBREC) ||
+ (pt == PUBCOMP) || (pt == SUBACK) || (pt == UNSUBACK) || (pt == PINGREQ) ||
+ (pt == PINGRESP) || (pt == DISCONNECT)) {
+ if (flags > 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid Packet-Flag combination flag!=0\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ }
+ if (((pt == PUBREL) || (pt == SUBSCRIBE) || (pt == UNSUBSCRIBE)) && (flags != 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid Packet-Flag combination flag!=2\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed first stage of identification\n");
+ // second stage verification (no payload)
+ if (((pt == CONNACK) || (pt == PUBACK) || (pt == PUBREL) ||
+ (pt == PUBREC) || (pt == PUBCOMP) || (pt == UNSUBACK)) && (packet->payload_packet_len > 4)){
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid Packet-Length < 4 \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found \n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ }
+ if (((pt == PINGREQ) || (pt == PINGRESP) || (pt == DISCONNECT)) && (packet->payload_packet_len > 2))
+ {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid Packet-Length <2 \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found PING/PINGRESP/DISCONNECT\n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed second stage of identification\n");
+ // third stage verification (payload)
+ if ((pt == CONNECT) && (memcmp(&(packet->payload[4]),"MQTT",4) == 0) ){
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found CONNECT\n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid CONNECT\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ if (pt == PUBLISH){
+ u_int8_t qos = (u_int8_t) (flags & 0x06);
+ if (((qos == 1) || (qos == 2)) && (packet->payload_packet_len < 4)){ // at least topic + pkt identifier
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid PUBLISH qos1&2\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ if ((qos == 0) && (packet->payload_packet_len < 3)){ // at least topic
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid PUBLISH qos0\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ if ((qos == 3)){ // this should never happen
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid PUBLISH qos3\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found PUBLISH\n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+
+ }
+ if ((pt == SUBSCRIBE) && (packet->payload_packet_len < 8)){ // at least one topic+filter is required in the payload
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid SUBSCRIBE\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found SUBSCRIBE\n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ }
+
+ if ((pt == SUBACK ) && (packet->payload_packet_len <5 )){ // must have at least a response code
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid SUBACK\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found SUBACK\n");
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ }
+
+ if ((pt == UNSUBSCRIBE) && (packet->payload_packet_len < 7)) { // at least a topic
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Mqtt invalid UNSUBSCRIBE\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found UNSUBSCRIBE\n",pt);
+ ndpi_int_mqtt_add_connection(ndpi_struct,flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed third stage of identification");
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Reached the end excluding Mqtt ...\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
+ return;
+}
+/**
+ * Entry point for the ndpi library
+ */
+void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
+{
+ NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt dissector init...\n");
+ ndpi_set_bitmask_protocol_detection ("MQTT", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_MQTT,
+ ndpi_search_mqtt,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK);
+ *id +=1;
+}
+
+#endif // NDPI_PROTOCOL_MQTT
+