1 /*
2 * amqp.c
3 *
4 * Copyright (C) 2011-21 - ntop.org
5 *
6 * nDPI is free software: you can redistribute 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
21 #include "ndpi_protocol_ids.h"
22
23 #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_AMQP
24
25 #include "ndpi_api.h"
26
27
28 PACK_ON
29 struct amqp_header {
30 u_int8_t ptype;
31 u_int16_t channel;
32 u_int32_t length;
33 u_int16_t class_id, method;
34 } PACK_OFF;
35
ndpi_int_amqp_add_connection(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)36 static void ndpi_int_amqp_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
37 struct ndpi_flow_struct *flow/* , */
38 /* ndpi_protocol_type_t protocol_type */) {
39 ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AMQP, NDPI_PROTOCOL_UNKNOWN);
40 }
41
ndpi_search_amqp(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)42 void ndpi_search_amqp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
43 struct ndpi_packet_struct *packet = &flow->packet;
44
45 NDPI_LOG_DBG(ndpi_struct, "search amqp\n");
46
47 if (packet->tcp != NULL) {
48 if(packet->payload_packet_len > sizeof(struct amqp_header)) {
49 struct amqp_header *h = (struct amqp_header*)packet->payload;
50
51 if(h->ptype <= 3) {
52 u_int32_t length = htonl(h->length);
53
54 if(((length+8) >= packet->payload_packet_len)
55 && (length < 32768) /* Upper bound */) {
56 u_int16_t class_id = htons(h->class_id);
57
58 if((class_id >= 10) /* Connection */
59 && (class_id <= 110) /* Tunnel */) {
60 u_int16_t method = htons(h->method);
61
62 if(method <= 120 /* Method basic NACK */) {
63 NDPI_LOG_INFO(ndpi_struct, "found amqp over tcp\n");
64 ndpi_int_amqp_add_connection(ndpi_struct, flow);
65 return;
66 }
67 }
68 }
69 }
70 }
71 } else {
72 NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
73 }
74 }
75
76
init_amqp_dissector(struct ndpi_detection_module_struct * ndpi_struct,u_int32_t * id,NDPI_PROTOCOL_BITMASK * detection_bitmask)77 void init_amqp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
78 ndpi_set_bitmask_protocol_detection("AMQP", ndpi_struct, detection_bitmask, *id,
79 NDPI_PROTOCOL_AMQP,
80 ndpi_search_amqp,
81 NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
82 SAVE_DETECTION_BITMASK_AS_UNKNOWN,
83 ADD_TO_DETECTION_BITMASK);
84
85 *id += 1;
86 }
87
88