aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2023-12-03 09:03:56 +0100
committerToni Uhlig <matzeton@googlemail.com>2023-12-14 00:19:35 +0100
commit709e460c896861f413baa5189d46b15ba06c2673 (patch)
tree71ef4908d4778ba2f22bf83bd3f1506698779e71 /example
parentef62391dba4814ab840539406f276685ba8535f1 (diff)
Add realtime protocol output to `ndpiReader`.add/output-realtime-protocols
* support for using a new flow callback invoked before the flow memory is free'd * minor fixes * Win32 gmtime fix Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'example')
-rw-r--r--example/ndpiReader.c74
-rw-r--r--example/reader_util.c3
-rw-r--r--example/reader_util.h10
3 files changed, 87 insertions, 0 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 919a7963d..cc62d0d49 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -2643,6 +2643,77 @@ static void debug_printf(u_int32_t protocol, void *id_struct,
/* *********************************************** */
+static int is_realtime_protocol(ndpi_protocol proto)
+{
+ static u_int16_t const realtime_protos[] = {
+ NDPI_PROTOCOL_YOUTUBE,
+ NDPI_PROTOCOL_YOUTUBE_UPLOAD,
+ NDPI_PROTOCOL_TIKTOK,
+ NDPI_PROTOCOL_GOOGLE,
+ NDPI_PROTOCOL_GOOGLE_CLASSROOM,
+ NDPI_PROTOCOL_GOOGLE_CLOUD,
+ NDPI_PROTOCOL_GOOGLE_DOCS,
+ NDPI_PROTOCOL_GOOGLE_DRIVE,
+ NDPI_PROTOCOL_GOOGLE_MAPS,
+ NDPI_PROTOCOL_GOOGLE_SERVICES
+ };
+
+ for (u_int16_t i = 0; i < NDPI_ARRAY_LENGTH(realtime_protos); i++) {
+ if (proto.app_protocol == realtime_protos[i]
+ || proto.master_protocol == realtime_protos[i])
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void dump_realtime_protocol(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow)
+{
+ FILE *out = results_file ? results_file : stdout;
+ char srcip[64], dstip[64];
+ char ip_proto[64], app_name[64];
+ char date[64];
+ int ret = is_realtime_protocol(flow->detected_protocol);
+ time_t firsttime = flow->first_seen_ms;
+ struct tm result;
+
+ if (ndpi_gmtime_r(&firsttime, &result) != NULL)
+ {
+ strftime(date, sizeof(date), "%d.%m.%y %H:%M:%S", &result);
+ } else {
+ snprintf(date, sizeof(date), "%s", "Unknown");
+ }
+
+ if (flow->ip_version==4) {
+ inet_ntop(AF_INET, &flow->src_ip, srcip, sizeof(srcip));
+ inet_ntop(AF_INET, &flow->dst_ip, dstip, sizeof(dstip));
+ } else {
+ snprintf(srcip, sizeof(srcip), "[%s]", flow->src_name);
+ snprintf(dstip, sizeof(dstip), "[%s]", flow->dst_name);
+ }
+
+ ndpi_protocol2name(workflow->ndpi_struct, flow->detected_protocol, app_name, sizeof(app_name));
+
+ if (ret == 1) {
+ fprintf(out, "Detected Realtime protocol %s --> [%s] %s:%d <--> %s:%d app=%s <%s>\n",
+ date, ndpi_get_ip_proto_name(flow->protocol, ip_proto, sizeof(ip_proto)),
+ srcip, ntohs(flow->src_port), dstip, ntohs(flow->dst_port),
+ app_name, flow->human_readeable_string_buffer);
+ }
+}
+
+static void on_protocol_discovered(struct ndpi_workflow * workflow,
+ struct ndpi_flow_info * flow,
+ void * userdata)
+{
+ (void)userdata;
+ dump_realtime_protocol(workflow, flow);
+}
+
+/* *********************************************** */
+
/**
* @brief Setup for detection begin
*/
@@ -2701,6 +2772,9 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
}
}
+ ndpi_workflow_set_flow_callback(ndpi_thread_info[thread_id].workflow,
+ on_protocol_discovered, NULL);
+
/* Make sure to load lists before finalizing the initialization */
ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].workflow->ndpi_struct, &enabled_bitmask);
diff --git a/example/reader_util.c b/example/reader_util.c
index 64b00b18f..480c3f180 100644
--- a/example/reader_util.c
+++ b/example/reader_util.c
@@ -1423,6 +1423,9 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
flow->flow_payload = flow->ndpi_flow->flow_payload, flow->flow_payload_len = flow->ndpi_flow->flow_payload_len;
flow->ndpi_flow->flow_payload = NULL; /* We'll free the memory */
+ if(workflow->flow_callback != NULL)
+ workflow->flow_callback(workflow, flow, workflow->flow_callback_userdata);
+
ndpi_free_flow_info_half(flow);
}
}
diff --git a/example/reader_util.h b/example/reader_util.h
index 9c55355e6..b0e6a88c1 100644
--- a/example/reader_util.h
+++ b/example/reader_util.h
@@ -374,6 +374,9 @@ typedef struct ndpi_workflow {
struct ndpi_workflow_prefs prefs;
struct ndpi_stats stats;
+ ndpi_workflow_callback_ptr flow_callback;
+ void * flow_callback_userdata;
+
/* outside referencies */
pcap_t *pcap_handle;
@@ -408,6 +411,13 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow,
const u_char *packet,
ndpi_risk *flow_risk);
+
+/* Flow callback for completed flows, before the flow memory will be freed. */
+static inline void ndpi_workflow_set_flow_callback(struct ndpi_workflow * workflow, ndpi_workflow_callback_ptr callback, void * userdata) {
+ workflow->flow_callback = callback;
+ workflow->flow_callback_userdata = userdata;
+}
+
int ndpi_is_datalink_supported(int datalink_type);
/* compare two nodes in workflow */