1 /*
2 * zmq.c
3 *
4 * Copyright (C) 2016-21 - ntop.org
5 *
6 * nDPI is free software: you can zmqtribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * nDPI is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20 #include "ndpi_protocol_ids.h"
21
22 #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_ZMQ
23
24 #include "ndpi_api.h"
25
ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)26 static void ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
27 ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, NDPI_PROTOCOL_UNKNOWN);
28 NDPI_LOG_INFO(ndpi_struct, "found ZMQ\n");
29 }
30
31
ndpi_check_zmq(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)32 static void ndpi_check_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
33
34 struct ndpi_packet_struct *packet = &flow->packet;
35 u_int32_t payload_len = packet->payload_packet_len;
36 u_char p0[] = { 0x00, 0x00, 0x00, 0x05, 0x01, 0x66, 0x6c, 0x6f, 0x77 };
37 u_char p1[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f };
38 u_char p2[] = { 0x28, 0x66, 0x6c, 0x6f, 0x77, 0x00 };
39
40 if(payload_len == 0) return; /* Shouldn't happen */
41
42 /* Break after 17 packets. */
43 if(flow->packet_counter > 17) {
44 NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
45 return;
46 }
47
48 if(flow->l4.tcp.prev_zmq_pkt_len == 0) {
49 flow->l4.tcp.prev_zmq_pkt_len = ndpi_min(packet->payload_packet_len, 10);
50 memcpy(flow->l4.tcp.prev_zmq_pkt, packet->payload, flow->l4.tcp.prev_zmq_pkt_len);
51 return; /* Too early */
52 }
53 if(payload_len == 2) {
54 if(flow->l4.tcp.prev_zmq_pkt_len == 2) {
55 if((memcmp(packet->payload, "\01\01", 2) == 0)
56 && (memcmp(flow->l4.tcp.prev_zmq_pkt, "\01\02", 2) == 0)) {
57 ndpi_int_zmq_add_connection(ndpi_struct, flow);
58 return;
59 }
60 } else if(flow->l4.tcp.prev_zmq_pkt_len == 9) {
61 if((memcmp(packet->payload, "\00\00", 2) == 0)
62 && (memcmp(flow->l4.tcp.prev_zmq_pkt, p0, 9) == 0)) {
63 ndpi_int_zmq_add_connection(ndpi_struct, flow);
64 return;
65 }
66 } else if(flow->l4.tcp.prev_zmq_pkt_len == 10) {
67 if((memcmp(packet->payload, "\01\02", 2) == 0)
68 && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) {
69 ndpi_int_zmq_add_connection(ndpi_struct, flow);
70 return;
71 }
72 }
73 } else if(payload_len >= 10) {
74 if(flow->l4.tcp.prev_zmq_pkt_len == 10) {
75 if(((memcmp(packet->payload, p1, 10) == 0)
76 && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0))
77 || ((memcmp(&packet->payload[1], p2, sizeof(p2)) == 0)
78 && (memcmp(&flow->l4.tcp.prev_zmq_pkt[1], p2, sizeof(p2)) == 0))) {
79 ndpi_int_zmq_add_connection(ndpi_struct, flow);
80 return;
81 }
82 }
83 }
84 }
85
ndpi_search_zmq(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)86 void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
87 struct ndpi_packet_struct *packet = &flow->packet;
88
89 NDPI_LOG_DBG(ndpi_struct, "search ZMQ\n");
90
91 /* skip marked packets */
92 if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_ZMQ) {
93 if(packet->tcp && packet->tcp_retransmission == 0) {
94 ndpi_check_zmq(ndpi_struct, flow);
95 }
96 }
97 }
98
99
init_zmq_dissector(struct ndpi_detection_module_struct * ndpi_struct,u_int32_t * id,NDPI_PROTOCOL_BITMASK * detection_bitmask)100 void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
101 {
102 ndpi_set_bitmask_protocol_detection("ZeroMQ", ndpi_struct, detection_bitmask, *id,
103 NDPI_PROTOCOL_ZMQ,
104 ndpi_search_zmq, /* TODO: add UDP support */
105 NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
106 SAVE_DETECTION_BITMASK_AS_UNKNOWN,
107 ADD_TO_DETECTION_BITMASK);
108
109 *id += 1;
110 }
111