/src/ndpi/example/reader_util.h
Line | Count | Source |
1 | | /* |
2 | | * ndpi_util.h |
3 | | * |
4 | | * Copyright (C) 2011-25 - 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 | | /** |
22 | | * This module contains routines to help setup a simple nDPI program. |
23 | | * |
24 | | * If you concern about performance or have to integrate nDPI in your |
25 | | * application, you could need to reimplement them yourself. |
26 | | * |
27 | | * WARNING: this API is just a demo od nDPI usage: Use it at your own risk! |
28 | | */ |
29 | | #ifndef __NDPI_UTIL_H__ |
30 | | #define __NDPI_UTIL_H__ |
31 | | |
32 | | #include "../src/lib/third_party/include/uthash.h" |
33 | | #include <pcap.h> |
34 | | #include "ndpi_includes.h" |
35 | | #include "ndpi_classify.h" |
36 | | #include "ndpi_typedefs.h" |
37 | | |
38 | | #ifdef USE_DPDK |
39 | | #include <rte_eal.h> |
40 | | #include <rte_ether.h> |
41 | | #include <rte_ethdev.h> |
42 | | #include <rte_cycles.h> |
43 | | #include <rte_lcore.h> |
44 | | #include <rte_mbuf.h> |
45 | | |
46 | | #define RX_RING_SIZE 128 |
47 | | #define TX_RING_SIZE 512 |
48 | | #define NUM_MBUFS 8191 |
49 | | #define MBUF_CACHE_SIZE 250 |
50 | | #define BURST_SIZE 32 |
51 | | #define PREFETCH_OFFSET 3 |
52 | | |
53 | | extern int dpdk_port_init(int port, struct rte_mempool *mbuf_pool); |
54 | | extern int dpdk_port_deinit(int port); |
55 | | #endif |
56 | | |
57 | 560k | #define PLEN_MAX 1504 |
58 | 556k | #define PLEN_BIN_LEN 32 |
59 | 190k | #define PLEN_NUM_BINS 48 /* 47*32 = 1504 */ |
60 | 574k | #define MAX_NUM_BIN_PKTS 256 |
61 | | |
62 | | /* ETTA Spec defiintions for feature readiness */ |
63 | | #define ETTA_MIN_PACKETS 10 |
64 | 125M | #define ETTA_MIN_OCTETS 4000 |
65 | | /** maximum line length */ |
66 | | #define LINEMAX 512 |
67 | | #define MAX_BYTE_COUNT_ARRAY_LENGTH 256 |
68 | | #define MAX_NUM_PKTS 10 |
69 | | |
70 | | #define MAX_NUM_READER_THREADS 16 |
71 | | #define IDLE_SCAN_PERIOD 10 /* msec (use TICK_RESOLUTION = 1000) */ |
72 | | #define MAX_IDLE_TIME 30000 |
73 | | #define IDLE_SCAN_BUDGET 1024 |
74 | | #define NUM_ROOTS 512 |
75 | | #define MAX_EXTRA_PACKETS_TO_CHECK 7 |
76 | | #define MAX_NDPI_FLOWS 200000000 |
77 | 1.81M | #define TICK_RESOLUTION 1000 |
78 | | #define MAX_NUM_IP_ADDRESS 5 /* len of ip address array */ |
79 | | #define UPDATED_TREE 1 |
80 | | #define AGGRESSIVE_PERCENT 95.00 |
81 | | #define DIR_SRC 10 |
82 | | #define DIR_DST 20 |
83 | | #define PORT_ARRAY_SIZE 20 |
84 | | #define HOST_ARRAY_SIZE 20 |
85 | | #define FLOWS_PACKETS_THRESHOLD 0.9 |
86 | | #define FLOWS_PERCENT_THRESHOLD 1.0 |
87 | | #define FLOWS_PERCENT_THRESHOLD_2 0.2 |
88 | | #define FLOWS_THRESHOLD 1000 |
89 | | #define PKTS_PERCENT_THRESHOLD 0.1 |
90 | | #define MAX_TABLE_SIZE_1 4096 |
91 | | #define MAX_TABLE_SIZE_2 8192 |
92 | | #define INIT_VAL -1 |
93 | | #define SERIALIZATION_BUFSIZ (8192 * 2) |
94 | | |
95 | | |
96 | | #ifdef __cplusplus |
97 | | extern "C" { |
98 | | #endif |
99 | | |
100 | | // inner hash table (ja -> security state) |
101 | | typedef struct ndpi_ja_info { |
102 | | char * ja; |
103 | | ndpi_cipher_weakness unsafe_cipher; |
104 | | UT_hash_handle hh; |
105 | | } ndpi_ja_info; |
106 | | |
107 | | // external hash table (host ip -> <ip string, hash table ja4c, hash table ja3s>) |
108 | | // used to aggregate ja3 fingerprints by hosts |
109 | | typedef struct ndpi_host_ja_fingerprints { |
110 | | u_int32_t ip; |
111 | | char *ip_string; |
112 | | char *dns_name; |
113 | | ndpi_ja_info *host_client_info_hasht; |
114 | | ndpi_ja_info *host_server_info_hasht; |
115 | | |
116 | | UT_hash_handle hh; |
117 | | } ndpi_host_ja_fingerprints; |
118 | | |
119 | | |
120 | | //inner hash table |
121 | | typedef struct ndpi_ip_dns{ |
122 | | u_int32_t ip; |
123 | | char *ip_string; |
124 | | char *dns_name; //server name if any; |
125 | | UT_hash_handle hh; |
126 | | } ndpi_ip_dns; |
127 | | |
128 | | //hash table ja -> <host, ip, security>, used to aggregate host by ja fingerprints |
129 | | typedef struct ndpi_ja_fingerprints_host{ |
130 | | char *ja; //key |
131 | | ndpi_cipher_weakness unsafe_cipher; |
132 | | ndpi_ip_dns *ipToDNS_ht; |
133 | | UT_hash_handle hh; |
134 | | } ndpi_ja_fingerprints_host; |
135 | | |
136 | | struct flow_metrics { |
137 | | float entropy, average, stddev; |
138 | | }; |
139 | | |
140 | | struct ndpi_entropy { |
141 | | // Entropy fields |
142 | | u_int16_t src2dst_pkt_len[MAX_NUM_PKTS]; /*!< array of packet appdata lengths */ |
143 | | pkt_timeval src2dst_pkt_time[MAX_NUM_PKTS]; /*!< array of arrival times */ |
144 | | u_int16_t dst2src_pkt_len[MAX_NUM_PKTS]; /*!< array of packet appdata lengths */ |
145 | | pkt_timeval dst2src_pkt_time[MAX_NUM_PKTS]; /*!< array of arrival times */ |
146 | | pkt_timeval src2dst_start; /*!< first packet arrival time */ |
147 | | pkt_timeval dst2src_start; /*!< first packet arrival time */ |
148 | | u_int32_t src2dst_opackets; /*!< non-zero packet counts */ |
149 | | u_int32_t dst2src_opackets; /*!< non-zero packet counts */ |
150 | | u_int16_t src2dst_pkt_count; /*!< packet counts */ |
151 | | u_int16_t dst2src_pkt_count; /*!< packet counts */ |
152 | | u_int32_t src2dst_l4_bytes; /*!< packet counts */ |
153 | | u_int32_t dst2src_l4_bytes; /*!< packet counts */ |
154 | | u_int32_t src2dst_byte_count[MAX_BYTE_COUNT_ARRAY_LENGTH]; /*!< number of occurences of each byte */ |
155 | | u_int32_t dst2src_byte_count[MAX_BYTE_COUNT_ARRAY_LENGTH]; /*!< number of occurences of each byte */ |
156 | | u_int32_t src2dst_num_bytes; |
157 | | u_int32_t dst2src_num_bytes; |
158 | | double src2dst_bd_mean; |
159 | | double src2dst_bd_variance; |
160 | | double dst2src_bd_mean; |
161 | | double dst2src_bd_variance; |
162 | | float score; |
163 | | }; |
164 | | |
165 | | enum info_type { |
166 | | INFO_INVALID = 0, |
167 | | INFO_GENERIC, |
168 | | INFO_KERBEROS, |
169 | | INFO_SOFTETHER, |
170 | | INFO_TIVOCONNECT, |
171 | | INFO_FTP_IMAP_POP_SMTP, |
172 | | INFO_NATPMP, |
173 | | INFO_SIP, |
174 | | INFO_FASTCGI, |
175 | | INFO_BFCP, |
176 | | }; |
177 | | |
178 | | typedef struct { |
179 | | ndpi_address_port *aps; |
180 | | unsigned int num_aps; |
181 | | unsigned int num_aps_allocated; |
182 | | } ndpi_address_port_list; |
183 | | |
184 | | // flow tracking |
185 | | typedef struct ndpi_flow_info { |
186 | | u_int32_t flow_id; |
187 | | u_int32_t hashval; |
188 | | u_int32_t src_ip; /* network order */ |
189 | | u_int32_t dst_ip; /* network order */ |
190 | | struct ndpi_in6_addr src_ip6; /* network order */ |
191 | | struct ndpi_in6_addr dst_ip6; /* network order */ |
192 | | u_int16_t src_port; /* network order */ |
193 | | u_int16_t dst_port; /* network order */ |
194 | | u_int8_t detection_completed, protocol, bidirectional, check_extra_packets, current_pkt_from_client_to_server; |
195 | | u_int16_t vlan_id; |
196 | | ndpi_packet_tunnel tunnel_type; |
197 | | struct ndpi_flow_struct *ndpi_flow; |
198 | | char *src_name, *dst_name; |
199 | | u_int8_t ip_version; |
200 | | u_int32_t cwr_count, src2dst_cwr_count, dst2src_cwr_count; |
201 | | u_int32_t ece_count, src2dst_ece_count, dst2src_ece_count; |
202 | | u_int32_t urg_count, src2dst_urg_count, dst2src_urg_count; |
203 | | u_int32_t ack_count, src2dst_ack_count, dst2src_ack_count; |
204 | | u_int32_t psh_count, src2dst_psh_count, dst2src_psh_count; |
205 | | u_int32_t syn_count, src2dst_syn_count, dst2src_syn_count; |
206 | | u_int32_t fin_count, src2dst_fin_count, dst2src_fin_count; |
207 | | u_int32_t rst_count, src2dst_rst_count, dst2src_rst_count; |
208 | | u_int32_t c_to_s_init_win, s_to_c_init_win; |
209 | | u_int64_t first_seen_ms, last_seen_ms; |
210 | | u_int64_t src2dst_bytes, dst2src_bytes; |
211 | | u_int64_t src2dst_goodput_bytes, dst2src_goodput_bytes; |
212 | | u_int32_t src2dst_packets, dst2src_packets; |
213 | | u_int32_t has_human_readeable_strings; |
214 | | char human_readeable_string_buffer[32]; |
215 | | char *risk_str; |
216 | | |
217 | | // result only, not used for flow identification |
218 | | ndpi_protocol detected_protocol; |
219 | | ndpi_confidence_t confidence; |
220 | | struct ndpi_fpc_info fpc; |
221 | | u_int16_t num_dissector_calls; |
222 | | u_int16_t dpi_packets; |
223 | | u_int8_t monitoring_state; |
224 | | u_int16_t num_packets_before_monitoring; |
225 | | |
226 | | // Flow data analysis |
227 | | pkt_timeval src2dst_last_pkt_time, dst2src_last_pkt_time, flow_last_pkt_time; |
228 | | struct ndpi_analyze_struct *iat_c_to_s, *iat_s_to_c, *iat_flow, |
229 | | *pktlen_c_to_s, *pktlen_s_to_c; |
230 | | |
231 | | enum info_type info_type; |
232 | | |
233 | | union { |
234 | | char info[256]; |
235 | | |
236 | | struct { |
237 | | unsigned char auth_failed; |
238 | | char username[127]; |
239 | | char password[128]; |
240 | | } ftp_imap_pop_smtp; |
241 | | |
242 | | struct { |
243 | | char domain[85]; |
244 | | char hostname[85]; |
245 | | char username[86]; |
246 | | } kerberos; |
247 | | |
248 | | struct { |
249 | | char ip[16]; |
250 | | char port[6]; |
251 | | char hostname[48]; |
252 | | char fqdn[48]; |
253 | | } softether; |
254 | | |
255 | | struct { |
256 | | char identity_uuid[36]; |
257 | | char machine[48]; |
258 | | char platform[32]; |
259 | | char services[48]; |
260 | | } tivoconnect; |
261 | | |
262 | | struct { |
263 | | uint16_t result_code; |
264 | | uint16_t internal_port; |
265 | | uint16_t external_port; |
266 | | char ip[16]; |
267 | | } natpmp; |
268 | | |
269 | | struct { |
270 | | char from[256]; |
271 | | char from_imsi[16]; |
272 | | char to[256]; |
273 | | char to_imsi[16]; |
274 | | } sip; |
275 | | |
276 | | struct { |
277 | | ndpi_http_method method; |
278 | | char user_agent[32]; |
279 | | char url[64]; |
280 | | } fast_cgi; |
281 | | |
282 | | struct { |
283 | | u_int32_t conference_id; |
284 | | u_int16_t user_id; |
285 | | } bfcp; |
286 | | }; |
287 | | |
288 | | ndpi_serializer ndpi_flow_serializer; |
289 | | |
290 | | char host_server_name[80]; /* Hostname/SNI */ |
291 | | char *server_hostname; |
292 | | char *bittorent_hash; |
293 | | char *dhcp_fingerprint; |
294 | | char *dhcp_class_ident; |
295 | | uint32_t idle_timeout_sec; |
296 | | ndpi_risk risk; |
297 | | |
298 | | struct { |
299 | | char currency[16]; |
300 | | } mining; |
301 | | |
302 | | struct { |
303 | | u_int16_t ssl_version; |
304 | | char server_info[64], |
305 | | client_hassh[33], server_hassh[33], *server_names, |
306 | | *advertised_alpns, *negotiated_alpn, *tls_supported_versions, |
307 | | *tls_issuerDN, *tls_subjectDN, |
308 | | ja3_server[33], ja4_client[37], *ja4_client_raw, |
309 | | sha1_cert_fingerprint[20]; |
310 | | u_int8_t sha1_cert_fingerprint_set; |
311 | | struct tls_heuristics browser_heuristics; |
312 | | |
313 | | struct { |
314 | | u_int16_t version; |
315 | | } encrypted_ch; |
316 | | |
317 | | time_t notBefore, notAfter; |
318 | | u_int16_t server_cipher; |
319 | | ndpi_cipher_weakness client_unsafe_cipher, server_unsafe_cipher; |
320 | | |
321 | | u_int32_t quic_version; |
322 | | } ssh_tls; |
323 | | |
324 | | struct { |
325 | | char url[256], request_content_type[64], content_type[64], |
326 | | user_agent[256], server[128], nat_ip[32], username[64], password[64], filename[256]; |
327 | | u_int response_status_code; |
328 | | } http; |
329 | | |
330 | | struct rtp_info rtp[2 /* directions */]; |
331 | | |
332 | | struct { |
333 | | ndpi_address_port_list mapped_address, peer_address, |
334 | | relayed_address, response_origin, other_address; |
335 | | u_int16_t rtp_counters[2]; |
336 | | } stun; |
337 | | |
338 | | struct { |
339 | | char *username, *password; |
340 | | } telnet; |
341 | | |
342 | | struct { |
343 | | char geolocation_iata_code[4]; |
344 | | char ptr_domain_name[64]; |
345 | | u_int16_t transaction_id; |
346 | | } dns; |
347 | | |
348 | | u_int8_t multimedia_flow_types; |
349 | | |
350 | | void *src_id, *dst_id; |
351 | | char *tcp_fingerprint, *ndpi_fingerprint; |
352 | | struct ndpi_entropy *entropy; |
353 | | struct ndpi_entropy *last_entropy; |
354 | | |
355 | | /* Payload lenght bins */ |
356 | | #ifdef DIRECTION_BINS |
357 | | struct ndpi_bin payload_len_bin_src2dst, payload_len_bin_dst2src; |
358 | | #else |
359 | | struct ndpi_bin payload_len_bin; |
360 | | #endif |
361 | | |
362 | | /* Flow payload */ |
363 | | u_int16_t flow_payload_len; |
364 | | char *flow_payload; |
365 | | } ndpi_flow_info_t; |
366 | | |
367 | | |
368 | | // flow statistics info |
369 | | typedef struct ndpi_stats { |
370 | | u_int32_t guessed_flow_protocols; |
371 | | u_int64_t raw_packet_count; |
372 | | u_int64_t ip_packet_count; |
373 | | u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; |
374 | | u_int32_t num_protocols; |
375 | | u_int64_t *protocol_counter; |
376 | | u_int64_t *protocol_counter_bytes; |
377 | | u_int32_t *protocol_flows; |
378 | | u_int64_t *fpc_protocol_counter; |
379 | | u_int64_t *fpc_protocol_counter_bytes; |
380 | | u_int32_t *fpc_protocol_flows; |
381 | | u_int64_t category_counter[NDPI_PROTOCOL_NUM_CATEGORIES]; |
382 | | u_int64_t category_counter_bytes[NDPI_PROTOCOL_NUM_CATEGORIES]; |
383 | | u_int32_t category_flows[NDPI_PROTOCOL_NUM_CATEGORIES]; |
384 | | u_int32_t ndpi_flow_count; |
385 | | u_int32_t flow_count[3]; |
386 | | u_int64_t tcp_count, udp_count; |
387 | | u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; |
388 | | u_int64_t packet_len[6]; |
389 | | u_int16_t max_packet_len; |
390 | | u_int64_t dpi_packet_count[3]; |
391 | | u_int64_t flow_confidence[NDPI_CONFIDENCE_MAX]; |
392 | | u_int64_t fpc_flow_confidence[NDPI_FPC_CONFIDENCE_MAX]; |
393 | | u_int64_t num_dissector_calls; |
394 | | |
395 | | struct ndpi_lru_cache_stats lru_stats[NDPI_LRUCACHE_MAX]; |
396 | | struct ndpi_automa_stats automa_stats[NDPI_AUTOMA_MAX]; |
397 | | struct ndpi_patricia_tree_stats patricia_stats[NDPI_PTREE_MAX]; |
398 | | } ndpi_stats_t; |
399 | | |
400 | | |
401 | | // flow preferences |
402 | | typedef struct ndpi_workflow_prefs { |
403 | | u_int8_t decode_tunnels; |
404 | | u_int8_t quiet_mode; |
405 | | u_int8_t ignore_vlanid; |
406 | | u_int32_t num_roots; |
407 | | u_int32_t max_ndpi_flows; |
408 | | } ndpi_workflow_prefs_t; |
409 | | |
410 | | struct ndpi_workflow; |
411 | | |
412 | | /** workflow, flow, user data */ |
413 | | typedef void (*ndpi_workflow_callback_ptr) (struct ndpi_workflow *, struct ndpi_flow_info *, void *); |
414 | | |
415 | | |
416 | | // workflow main structure |
417 | | typedef struct ndpi_workflow { |
418 | | u_int64_t last_time; |
419 | | |
420 | | struct ndpi_workflow_prefs prefs; |
421 | | struct ndpi_stats stats; |
422 | | |
423 | | ndpi_workflow_callback_ptr flow_callback; |
424 | | void * flow_callback_userdata; |
425 | | |
426 | | /* outside referencies */ |
427 | | pcap_t *pcap_handle; |
428 | | |
429 | | /* allocated by prefs */ |
430 | | void **ndpi_flows_root; |
431 | | struct ndpi_detection_module_struct *ndpi_struct; |
432 | | struct ndpi_global_context *g_ctx; |
433 | | u_int32_t num_allocated_flows; |
434 | | |
435 | | /* CSV,TLV,JSON serialization interface */ |
436 | | ndpi_serialization_format ndpi_serialization_format; |
437 | | } ndpi_workflow_t; |
438 | | |
439 | | void ndpi_stats_free(ndpi_stats_t *s); |
440 | | int ndpi_stats_init(ndpi_stats_t *s, uint32_t num_protocols); |
441 | | void ndpi_stats_reset(ndpi_stats_t *s); |
442 | | |
443 | | /* TODO: remove wrappers parameters and use ndpi global, when their initialization will be fixed... */ |
444 | | struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle, int do_init_flows_root, ndpi_serialization_format serialization_format, struct ndpi_global_context *g_ctx); |
445 | | |
446 | | |
447 | | /* workflow main free function */ |
448 | | void ndpi_workflow_free(struct ndpi_workflow * workflow); |
449 | | |
450 | | |
451 | | /** Free flow_info ndpi support structures but not the flow_info itself |
452 | | * |
453 | | * TODO remove! Half freeing things is bad! |
454 | | */ |
455 | | void ndpi_free_flow_info_half(struct ndpi_flow_info *flow); |
456 | | |
457 | | |
458 | | /* Process a packet and update the workflow */ |
459 | | struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, |
460 | | const struct pcap_pkthdr *header, |
461 | | const u_char *packet, |
462 | | ndpi_risk *flow_risk, |
463 | | struct ndpi_flow_info **flow); |
464 | | |
465 | | |
466 | | /* Flow callback for completed flows, before the flow memory will be freed. */ |
467 | 1 | static inline void ndpi_workflow_set_flow_callback(struct ndpi_workflow * workflow, ndpi_workflow_callback_ptr callback, void * userdata) { |
468 | 1 | workflow->flow_callback = callback; |
469 | 1 | workflow->flow_callback_userdata = userdata; |
470 | 1 | } fuzz_ndpi_reader.c:ndpi_workflow_set_flow_callback Line | Count | Source | 467 | 1 | static inline void ndpi_workflow_set_flow_callback(struct ndpi_workflow * workflow, ndpi_workflow_callback_ptr callback, void * userdata) { | 468 | 1 | workflow->flow_callback = callback; | 469 | 1 | workflow->flow_callback_userdata = userdata; | 470 | 1 | } |
Unexecuted instantiation: reader_util.c:ndpi_workflow_set_flow_callback |
471 | | |
472 | | int ndpi_is_datalink_supported(int datalink_type); |
473 | | |
474 | | /* compare two nodes in workflow */ |
475 | | int ndpi_workflow_node_cmp(const void *a, const void *b); |
476 | | void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow); |
477 | | void ndpi_flow_info_free_data(struct ndpi_flow_info *flow); |
478 | | void ndpi_flow_info_freer(void *node); |
479 | | const char* print_cipher_id(u_int32_t cipher); |
480 | | |
481 | | extern int reader_log_level; |
482 | | |
483 | | #if defined(NDPI_ENABLE_DEBUG_MESSAGES) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
484 | | #define LOG(log_level, args...) \ |
485 | | { \ |
486 | | if(log_level <= reader_log_level) \ |
487 | | printf(args); \ |
488 | | } |
489 | | #else |
490 | 3 | #define LOG(...) {} |
491 | | #endif |
492 | | |
493 | | #ifndef LINKTYPE_LINUX_SLL2 |
494 | 21.3k | #define LINKTYPE_LINUX_SLL2 276 |
495 | | #endif |
496 | | |
497 | | #ifdef __cplusplus |
498 | | } |
499 | | #endif |
500 | | |
501 | | #endif |