nDPI/fuzz/fuzz_process_packet.c
Ivan Nardi 83d85775a8
Provide an explicit state for the flow classification process (#2942)
Application should keep calling nDPI until flow state became
`NDPI_STATE_CLASSIFIED`.

The main loop in the application is simplified to something like:
```
res = ndpi_detection_process_packet(...);
if(res->state == NDPI_STATE_CLASSIFIED) {
  /* Done: you can get finale classification and all metadata.
     nDPI doesn't need more packets for this flow */
} else {
  /* nDPI needs more packets for this flow. The provided
     classification is not final and more metadata might be
     extracted.
     If `res->state` is `NDPI_STATE_PARTIAL`, partial/initial
     classification is available in `res->proto`
     as usual but it can be updated later.
  */
}

/*
    Example A (QUIC flow):
     pkt 1: proto QUIC state NDPI_STATE_PARTIAL
     pkt 2: proto QUIC/Youtube  state NDPI_STATE_CLASSIFIED
    Example B (GoogleMeet call):
     pkt 1:   proto STUN state NDPI_STATE_PARTIAL
     pkt N:   proto DTLS state NDPI_STATE_PARTIAL
     pkt N+M: proto DTLS/GoogleCall state NDPI_STATE_CLASSIFIED
    Example C (standard TLS flow):
     pkt 1:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 2:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 3:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 4:   proto TLS/Facebook state NDPI_STATE_PARTIAL
     pkt N:   proto TLS/Facebook state NDPI_STATE_CLASSIFIED
 */
}
```
You can take a look at `ndpiReader` for a slightly more complex example.

API changes:
* remove the third parameter from `ndpi_detection_giveup()`. If you need
to know if the classification flow has been guessed, you can access
`flow->protocol_was_guessed`
* remove `ndpi_extra_dissection_possible()`
* change some prototypes from accepting `ndpi_protocol foo` to
`ndpi_master_app_protocol bar`. The update is trivial: from `foo` to
`foo.proto`
2025-11-03 12:08:15 +01:00

32 lines
1.1 KiB
C

#include "ndpi_api.h"
#include "fuzz_common_code.h"
#include <stdint.h>
#include <stdio.h>
struct ndpi_detection_module_struct *ndpi_info_mod = NULL;
struct ndpi_flow_struct ndpi_flow;
static ndpi_serializer json_serializer = {};
static ndpi_serializer csv_serializer = {};
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (ndpi_info_mod == NULL) {
fuzz_init_detection_module(&ndpi_info_mod, NULL);
ndpi_init_serializer(&json_serializer, ndpi_serialization_format_json);
ndpi_init_serializer(&csv_serializer, ndpi_serialization_format_csv);
}
memset(&ndpi_flow, 0, SIZEOF_FLOW_STRUCT);
ndpi_protocol detected_protocol =
ndpi_detection_process_packet(ndpi_info_mod, &ndpi_flow, Data, Size, 0, NULL);
detected_protocol = ndpi_detection_giveup(ndpi_info_mod, &ndpi_flow);
ndpi_reset_serializer(&json_serializer);
ndpi_reset_serializer(&csv_serializer);
ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &json_serializer);
ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &csv_serializer);
ndpi_free_flow_data(&ndpi_flow);
return 0;
}