aboutsummaryrefslogtreecommitdiff
path: root/example/reader_util.c
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2024-10-14 18:05:35 +0200
committerGitHub <noreply@github.com>2024-10-14 18:05:35 +0200
commit521d0ca7a0196889f5452a2e725f8e01ddf79efb (patch)
tree06b76aa973aa8cf380c064750c4b9a052af82e29 /example/reader_util.c
parent44d0d9454c5db4e7863ed0b83c94de08eb19e132 (diff)
Add monitoring capability (#2588)
Allow nDPI to process the entire flows and not only the first N packets. Usefull when the application is interested in some metadata spanning the entire life of the session. As initial step, only STUN flows can be put in monitoring. See `doc/monitoring.md` for further details. This feature is disabled by default. Close #2583
Diffstat (limited to 'example/reader_util.c')
-rw-r--r--example/reader_util.c177
1 files changed, 172 insertions, 5 deletions
diff --git a/example/reader_util.c b/example/reader_util.c
index 702ff4dc7..28596eb4f 100644
--- a/example/reader_util.c
+++ b/example/reader_util.c
@@ -84,6 +84,7 @@ extern char *addr_dump_path;
u_int8_t enable_doh_dot_detection = 0;
extern bool do_load_lists;
extern int malloc_size_stats;
+extern int monitoring_enabled;
/* ****************************************************** */
@@ -554,6 +555,27 @@ static void ndpi_free_flow_tls_data(struct ndpi_flow_info *flow) {
ndpi_free(flow->ssh_tls.ja4_client_raw);
flow->ssh_tls.ja4_client_raw = NULL;
}
+
+ if(flow->stun.mapped_address.aps) {
+ ndpi_free(flow->stun.mapped_address.aps);
+ flow->stun.mapped_address.aps = NULL;
+ }
+ if(flow->stun.other_address.aps) {
+ ndpi_free(flow->stun.other_address.aps);
+ flow->stun.other_address.aps = NULL;
+ }
+ if(flow->stun.peer_address.aps) {
+ ndpi_free(flow->stun.peer_address.aps);
+ flow->stun.peer_address.aps = NULL;
+ }
+ if(flow->stun.relayed_address.aps) {
+ ndpi_free(flow->stun.relayed_address.aps);
+ flow->stun.relayed_address.aps = NULL;
+ }
+ if(flow->stun.response_origin.aps) {
+ ndpi_free(flow->stun.response_origin.aps);
+ flow->stun.response_origin.aps = NULL;
+ }
}
/* ***************************************************** */
@@ -1117,6 +1139,143 @@ static void dump_flow_fingerprint(struct ndpi_workflow * workflow,
ndpi_term_serializer(&serializer);
}
+
+static void add_to_address_port_list(ndpi_address_port_list *list, ndpi_address_port *ap)
+{
+ int new_num;
+ void *new_buf;
+ unsigned int i;
+
+ if(ap->port == 0)
+ return;
+
+ /* Avoid saving duplicates */
+ for(i = 0; i < list->num_aps; i++)
+ if(memcmp(&list->aps[i], ap, sizeof(*ap)) == 0)
+ return;
+
+ if(list->num_aps == list->num_aps_allocated) {
+ new_num = 1 + list->num_aps_allocated * 2;
+ new_buf = ndpi_realloc(list->aps, list->num_aps_allocated * sizeof(ndpi_address_port),
+ new_num * sizeof(ndpi_address_port));
+ if(!new_buf)
+ return;
+ list->aps = new_buf;
+ list->num_aps_allocated = new_num;
+ }
+ memcpy(&list->aps[list->num_aps++], ap, sizeof(ndpi_address_port));
+}
+
+/* ****************************************************** */
+
+static void process_ndpi_monitoring_info(struct ndpi_flow_info *flow) {
+ if(!flow->ndpi_flow || !flow->ndpi_flow->monit)
+ return;
+
+ /* In theory, we should check only for STUN.
+ However since we sometimes might not have STUN in protocol classification
+ (because we have only two protocols in flow->ndpi_flow->detected_protocol_stack[])
+ we need to check also for the other "master" protocols set by STUN dissector
+ See at the beginning of the STUN c file for further details
+ */
+ if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_STUN ||
+ flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_STUN ||
+ flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_DTLS ||
+ flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_DTLS ||
+ flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_SRTP ||
+ flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_SRTP) {
+
+ add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.mapped_address);
+ add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.other_address);
+ add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.peer_address);
+ add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.relayed_address);
+ add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.response_origin);
+ }
+
+}
+
+/* ****************************************************** */
+
+static void serialize_monitoring_metadata(struct ndpi_flow_info *flow)
+{
+ unsigned int i;
+ char buf[64];
+
+ if(!flow->ndpi_flow->monit)
+ return;
+
+ ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "monitoring");
+
+ switch(flow->detected_protocol.proto.master_protocol ? flow->detected_protocol.proto.master_protocol : flow->detected_protocol.proto.app_protocol) {
+ case NDPI_PROTOCOL_STUN:
+ case NDPI_PROTOCOL_DTLS:
+ case NDPI_PROTOCOL_SRTP:
+
+ ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "stun");
+
+ if(flow->stun.mapped_address.num_aps > 0) {
+ ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "mapped_address");
+ for(i = 0; i < flow->stun.mapped_address.num_aps; i++) {
+ if(flow->stun.mapped_address.aps[i].port > 0) {
+ ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "mapped_address",
+ print_ndpi_address_port(&flow->stun.mapped_address.aps[i], buf, sizeof(buf)));
+ }
+ }
+ ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
+ }
+
+ if(flow->stun.other_address.num_aps > 0) {
+ ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "other_address");
+ for(i = 0; i < flow->stun.other_address.num_aps; i++) {
+ if(flow->stun.other_address.aps[i].port > 0) {
+ ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "other_address",
+ print_ndpi_address_port(&flow->stun.other_address.aps[i], buf, sizeof(buf)));
+ }
+ }
+ ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
+ }
+
+ if(flow->stun.peer_address.num_aps > 0) {
+ ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "peer_address");
+ for(i = 0; i < flow->stun.peer_address.num_aps; i++) {
+ if(flow->stun.peer_address.aps[i].port > 0) {
+ ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "peer_address",
+ print_ndpi_address_port(&flow->stun.peer_address.aps[i], buf, sizeof(buf)));
+ }
+ }
+ ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
+ }
+
+ if(flow->stun.relayed_address.num_aps > 0) {
+ ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "relayed_address");
+ for(i = 0; i < flow->stun.relayed_address.num_aps; i++) {
+ if(flow->stun.relayed_address.aps[i].port > 0) {
+ ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "relayed_address",
+ print_ndpi_address_port(&flow->stun.relayed_address.aps[i], buf, sizeof(buf)));
+ }
+ }
+ ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
+ }
+
+ if(flow->stun.response_origin.num_aps > 0) {
+ ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "response_origin");
+ for(i = 0; i < flow->stun.response_origin.num_aps; i++) {
+ if(flow->stun.response_origin.aps[i].port > 0) {
+ ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "response_origin",
+ print_ndpi_address_port(&flow->stun.response_origin.aps[i], buf, sizeof(buf)));
+ }
+ }
+ ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
+ }
+
+ ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer); /* stun */
+
+ break;
+ }
+
+ ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer);
+}
+
/* ****************************************************** */
void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) {
@@ -1416,11 +1575,13 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
}
}
- memcpy(&flow->stun.mapped_address, &flow->ndpi_flow->stun.mapped_address, sizeof(ndpi_address_port));
- memcpy(&flow->stun.peer_address, &flow->ndpi_flow->stun.peer_address, sizeof(ndpi_address_port));
- memcpy(&flow->stun.relayed_address, &flow->ndpi_flow->stun.relayed_address, sizeof(ndpi_address_port));
- memcpy(&flow->stun.response_origin, &flow->ndpi_flow->stun.response_origin, sizeof(ndpi_address_port));
- memcpy(&flow->stun.other_address, &flow->ndpi_flow->stun.other_address, sizeof(ndpi_address_port));
+ if(!monitoring_enabled) {
+ add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->stun.mapped_address);
+ add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->stun.peer_address);
+ add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->stun.relayed_address);
+ add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->stun.response_origin);
+ add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->stun.other_address);
+ }
flow->multimedia_flow_type = flow->ndpi_flow->flow_multimedia_type;
@@ -1478,6 +1639,10 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed);
ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "check_extra_packets", flow->check_extra_packets);
+ if(flow->ndpi_flow->monitoring) {
+ serialize_monitoring_metadata(flow);
+ }
+
if(flow->server_hostname)
ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "server_hostname", flow->server_hostname);
}
@@ -1792,6 +1957,8 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow,
flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow,
iph ? (uint8_t *)iph : (uint8_t *)iph6,
ipsize, time_ms, &input_info);
+ if(monitoring_enabled)
+ process_ndpi_monitoring_info(flow);
enough_packets |= ndpi_flow->fail_with_unknown;
if(enough_packets || (flow->detected_protocol.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)) {
if((!enough_packets)