utoni / nDPId

Tiny nDPI based deep packet inspection daemons / toolkit.
GNU General Public License v3.0
67 stars 15 forks source link

Is it possible to carry the DPI information to the flow_event_end event? #21

Closed jiamo closed 1 year ago

jiamo commented 1 year ago

In my case, I want to one event of one flow. I try to do such thing

 static void free_workflow(struct nDPId_workflow ** const workflow);
 static void serialize_and_send(struct nDPId_reader_thread * const reader_thread);
 static void jsonize_flow_event(struct nDPId_reader_thread * const reader_thread,
-                               struct nDPId_flow_extended * const flow_ext,
+                               struct nDPId_flow * const flow,
                                enum flow_event event);
 static void jsonize_flow_detection_event(struct nDPId_reader_thread * const reader_thread,
                                          struct nDPId_flow * const flow,
@@ -1788,11 +1788,11 @@ static void process_idle_flow(struct nDPId_reader_thread * const reader_thread,

                 if (flow->flow_extended.flow_basic.tcp_fin_rst_seen != 0)
                 {
-                    jsonize_flow_event(reader_thread, &flow->flow_extended, FLOW_EVENT_END);
+                    jsonize_flow_event(reader_thread, flow, FLOW_EVENT_END);
                 }
                 else
                 {
-                    jsonize_flow_event(reader_thread, &flow->flow_extended, FLOW_EVENT_IDLE);
+                    jsonize_flow_event(reader_thread, flow, FLOW_EVENT_IDLE);
                 }
                 break;
             }
@@ -1843,11 +1843,11 @@ static void process_idle_flow(struct nDPId_reader_thread * const reader_thread,
                 }
                 if (flow->flow_extended.flow_basic.tcp_fin_rst_seen != 0)
                 {
-                    jsonize_flow_event(reader_thread, &flow->flow_extended, FLOW_EVENT_END);
+                    jsonize_flow_event(reader_thread, flow, FLOW_EVENT_END);
                 }
                 else
                 {
-                    jsonize_flow_event(reader_thread, &flow->flow_extended, FLOW_EVENT_IDLE);
+                    jsonize_flow_event(reader_thread, flow, FLOW_EVENT_IDLE);
                 }
                 break;
             }
@@ -1897,11 +1897,11 @@ static void ndpi_flow_update_scan_walker(void const * const A, ndpi_VISIT which,
             case FS_INFO:
             {
                 struct nDPId_flow_extended * const flow_ext = (struct nDPId_flow_extended *)flow_basic;
-
+                struct nDPId_flow * const flow = (struct nDPId_flow *)flow_basic;
                 if (is_flow_update_required(workflow, flow_ext) != 0)
                 {
                     workflow->total_flow_updates++;
-                    jsonize_flow_event(reader_thread, flow_ext, FLOW_EVENT_UPDATE);
+                    jsonize_flow_event(reader_thread, flow, FLOW_EVENT_UPDATE);
                     flow_ext->last_flow_update = workflow->last_thread_time;
                 }
                 break;
@@ -2644,11 +2644,12 @@ static void jsonize_packet_event(struct nDPId_reader_thread * const reader_threa

 /* I decided against ndpi_flow2json as it does not fulfill my needs. */
 static void jsonize_flow_event(struct nDPId_reader_thread * const reader_thread,
-                               struct nDPId_flow_extended * const flow_ext,
+                               struct nDPId_flow * const flow,
                                enum flow_event event)
 {
     struct nDPId_workflow * const workflow = reader_thread->workflow;
     char const ev[] = "flow_event_name";
+    struct nDPId_flow_extended * const flow_ext = &flow->flow_extended;

     ndpi_serialize_string_int32(&workflow->ndpi_serializer, "flow_event_id", event);
     if (event > FLOW_EVENT_INVALID && event < FLOW_EVENT_COUNT)
@@ -4086,7 +4087,7 @@ static void ndpi_process_packet(uint8_t * const args,
                     flow_to_process->flow_extended.last_flow_update = workflow->last_thread_time;
         flow_to_process->flow_extended.max_l4_payload_len[direction] = l4_payload_len;
         flow_to_process->flow_extended.min_l4_payload_len[direction] = l4_payload_len;
-        jsonize_flow_event(reader_thread, &flow_to_process->flow_extended, FLOW_EVENT_NEW);
+        jsonize_flow_event(reader_thread, flow_to_process, FLOW_EVENT_NEW);
     }

     if (nDPId_options.enable_data_analysis != 0 && flow_to_process->flow_extended.flow_analysis != NULL &&
@@ -4114,7 +4115,7 @@ static void ndpi_process_packet(uint8_t * const args,

         if (total_flow_packets == nDPId_options.max_packets_per_flow_to_analyse)
         {
-            jsonize_flow_event(reader_thread, &flow_to_process->flow_extended, FLOW_EVENT_ANALYSE);
+            jsonize_flow_event(reader_thread, flow_to_process, FLOW_EVENT_ANALYSE);
             free_analysis_data(&flow_to_process->flow_extended);
         }
     }

first try to using nDPId_flow instead nDPId_flow_extended

Then add the ndpi_dpi2json in jsonize_flow_event

+            if (event == FLOW_EVENT_END){
+                if (ndpi_dpi2json(workflow->ndpi_struct,
+                                  &flow->info.detection_data->flow,
+                                  flow->flow_extended.detected_l7_protocol,
+                                  &workflow->ndpi_serializer) != 0)
+                {
+                    logger(1,
+                           "[%8llu, %4llu] ndpi_dpi2json failed for detected/detection-update flow",
+                           workflow->packets_captured,
+                           flow->flow_extended.flow_id);
+                }
+            }
+

It will got segment fault. Even I comment free_detection_data. It still got segment. I don't want to add such if (event == FLOW_EVENT_END && flow->info.detection_completed == 1) line. Because I want the end event can contains the DPI info.

I am wondering the data struct need by ndpi_dpi2json was freed by which function? freed by nDPId or freed by nDPI ? What I want to achieve is: When the segment solved, I will do not serialize other event. Do you have some suggestion?

jiamo commented 1 year ago

I may found the issue . The union info and finished in nDPId_flow caused the problem. May be it is a good idea to make jsonize_flow_event and jsonize_flow_detect_eventto one function, and info and finished to one? Never mind.

utoni commented 1 year ago

Documentation needed here! Thanks for pointing that out!