Coverage Report

Created: 2025-08-28 06:46

/src/ndpi/example/reader_util.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * reader_util.c
3
 *
4
 * Copyright (C) 2011-25 - ntop.org
5
 *
6
 * This file is part of nDPI, an open source deep packet inspection
7
 * library based on the OpenDPI and PACE technology by ipoque GmbH
8
 *
9
 * nDPI is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * nDPI is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
#include "ndpi_config.h"
25
#include "ndpi_api.h"
26
27
#include <stdlib.h>
28
#include <math.h>
29
#include <float.h>
30
31
#ifdef WIN32
32
#include <winsock2.h> /* winsock.h is included automatically */
33
#include <windows.h>
34
#include <ws2tcpip.h>
35
#include <process.h>
36
#include <io.h>
37
#ifndef DISABLE_NPCAP
38
#include <ip6_misc.h>
39
#endif
40
#else
41
#include <unistd.h>
42
#include <netinet/in.h>
43
#include <netinet/ip.h>
44
#endif
45
#include <assert.h>
46
#include <sys/stat.h>
47
48
#include "reader_util.h"
49
50
248k
#define SNAP                   0XAA
51
238k
#define BSTP                   0x42     /* Bridge Spanning Tree Protocol */
52
53
/* Keep last 32 packets */
54
20.5M
#define DATA_ANALUYSIS_SLIDING_WINDOW    32
55
56
/* mask for FCF */
57
9.39k
#define WIFI_DATA                        0x2    /* 0000 0010 */
58
9.39k
#define FCF_TYPE(fc)     (((fc) >> 2) & 0x3)    /* 0000 0011 = 0x3 */
59
#define FCF_SUBTYPE(fc)  (((fc) >> 4) & 0xF)    /* 0000 1111 = 0xF */
60
15.5k
#define FCF_TO_DS(fc)        ((fc) & 0x0100)
61
5.84k
#define FCF_FROM_DS(fc)      ((fc) & 0x0200)
62
63
/* mask for Bad FCF presence */
64
28.5k
#define BAD_FCS                         0x50    /* 0101 0000 */
65
66
5.70M
#define GTP_U_V1_PORT                  2152
67
5.57M
#define NDPI_CAPWAP_DATA_PORT          5247
68
5.59M
#define TZSP_PORT                      37008
69
70
#ifndef DLT_LINUX_SLL
71
#define DLT_LINUX_SLL  113
72
#endif
73
74
#include "ndpi_main.h"
75
#include "reader_util.h"
76
#include "ndpi_classify.h"
77
78
extern u_int8_t enable_flow_stats, enable_payload_analyzer;
79
extern u_int8_t verbose, human_readeable_string_len;
80
extern u_int8_t max_num_udp_dissected_pkts /* 24 */, max_num_tcp_dissected_pkts /* 80 */;
81
static u_int32_t flow_id = 0;
82
extern FILE *fingerprint_fp;
83
extern char *addr_dump_path;
84
u_int8_t enable_doh_dot_detection = 0;
85
extern bool do_load_lists;
86
extern int malloc_size_stats;
87
extern int monitoring_enabled;
88
extern char *protocolsDirPath;
89
90
/* ****************************************************** */
91
92
struct flow_id_stats {
93
  u_int32_t flow_id;
94
  UT_hash_handle hh;   /* makes this structure hashable */
95
};
96
97
struct packet_id_stats {
98
  u_int32_t packet_id;
99
  UT_hash_handle hh;   /* makes this structure hashable */
100
};
101
102
struct payload_stats {
103
  u_int8_t *pattern;
104
  u_int8_t pattern_len;
105
  u_int16_t num_occurrencies;
106
  struct flow_id_stats *flows;
107
  struct packet_id_stats *packets;
108
  UT_hash_handle hh;   /* makes this structure hashable */
109
};
110
111
112
struct payload_stats *pstats = NULL;
113
u_int32_t max_num_packets_per_flow      = 10; /* ETTA requires min 10 pkts for record. */
114
u_int32_t max_packet_payload_dissection = 128;
115
u_int32_t max_num_reported_top_payloads = 25;
116
u_int16_t min_pattern_len               = 4;
117
u_int16_t max_pattern_len               = 8;
118
119
/* *********************************************************** */
120
121
int ndpi_analyze_payload(struct ndpi_flow_info *flow,
122
       u_int8_t *payload,
123
       u_int16_t payload_len,
124
0
       u_int32_t packet_id) {
125
0
  struct payload_stats *ret, *ret_found;
126
0
  struct flow_id_stats *f, *f_found;
127
0
  struct packet_id_stats *p, *p_found;
128
129
#ifdef DEBUG_PAYLOAD
130
  u_int16_t i;
131
  for(i=0; i<payload_len; i++)
132
    printf("%c", ndpi_isprint(payload[i]) ? payload[i] : '.');
133
  printf("\n");
134
#endif
135
136
0
  HASH_FIND(hh, pstats, payload, payload_len, ret);
137
0
  if(ret == NULL) {
138
0
    if((ret = (struct payload_stats*)ndpi_calloc(1, sizeof(struct payload_stats))) == NULL)
139
0
      return -1; /* OOM */
140
141
0
    if((ret->pattern = (u_int8_t*)ndpi_malloc(payload_len)) == NULL) {
142
0
      ndpi_free(ret);
143
0
      return -1;
144
0
    }
145
146
0
    memcpy(ret->pattern, payload, payload_len);
147
0
    ret->pattern_len = payload_len;
148
0
    ret->num_occurrencies = 1;
149
150
0
    HASH_ADD(hh, pstats, pattern[0], payload_len, ret);
151
152
0
    HASH_FIND(hh, pstats, payload, payload_len, ret_found);
153
0
    if(ret_found == NULL) { /* The insertion failed (because of a memory allocation error) */
154
0
      ndpi_free(ret->pattern);
155
0
      ndpi_free(ret);
156
0
      return -1;
157
0
    }
158
159
#ifdef DEBUG_PAYLOAD
160
    printf("Added element [total: %u]\n", HASH_COUNT(pstats));
161
#endif
162
0
  } else {
163
0
    ret->num_occurrencies++;
164
    // printf("==> %u\n", ret->num_occurrencies);
165
0
  }
166
167
0
  HASH_FIND_INT(ret->flows, &flow->flow_id, f);
168
0
  if(f == NULL) {
169
0
    if((f = (struct flow_id_stats*)ndpi_calloc(1, sizeof(struct flow_id_stats))) == NULL)
170
0
      return -1; /* OOM */
171
172
0
    f->flow_id = flow->flow_id;
173
0
    HASH_ADD_INT(ret->flows, flow_id, f);
174
175
0
    HASH_FIND_INT(ret->flows, &flow->flow_id, f_found);
176
0
    if(f_found == NULL) { /* The insertion failed (because of a memory allocation error) */
177
0
      ndpi_free(f);
178
0
      return -1;
179
0
    }
180
0
  }
181
182
0
  HASH_FIND_INT(ret->packets, &packet_id, p);
183
0
  if(p == NULL) {
184
0
    if((p = (struct packet_id_stats*)ndpi_calloc(1, sizeof(struct packet_id_stats))) == NULL)
185
0
      return -1; /* OOM */
186
0
    p->packet_id = packet_id;
187
188
0
    HASH_ADD_INT(ret->packets, packet_id, p);
189
190
0
    HASH_FIND_INT(ret->packets, &packet_id, p_found);
191
0
    if(p_found == NULL) { /* The insertion failed (because of a memory allocation error) */
192
0
      ndpi_free(p);
193
0
    }
194
0
  }
195
0
  return 0;
196
0
}
197
198
/* *********************************************************** */
199
200
void ndpi_payload_analyzer(struct ndpi_flow_info *flow,
201
         u_int8_t *payload, u_int16_t payload_len,
202
0
         u_int32_t packet_id) {
203
0
  u_int16_t i, j;
204
0
  u_int16_t scan_len = ndpi_min(max_packet_payload_dissection, payload_len);
205
206
0
  if((flow->src2dst_packets+flow->dst2src_packets) <= max_num_packets_per_flow) {
207
#ifdef DEBUG_PAYLOAD
208
    printf("[hashval: %u][proto: %u][vlan: %u][%s:%u <-> %s:%u][direction: %s][payload_len: %u]\n",
209
     flow->hashval, flow->protocol, flow->vlan_id,
210
     flow->src_name ? flow->src_name : "",
211
     flow->src_port,
212
     flow->dst_name ? flow->dst_name : "",
213
     flow->dst_port,
214
     src_to_dst_direction ? "s2d" : "d2s",
215
     payload_len);
216
#endif
217
0
  } else
218
0
    return;
219
220
0
  for(i=0; i<scan_len; i++) {
221
0
    for(j=min_pattern_len; j <= max_pattern_len; j++) {
222
0
      if((i+j) < payload_len) {
223
0
  if(ndpi_analyze_payload(flow, &payload[i], j, packet_id) == -1) {
224
0
          LOG(NDPI_LOG_ERROR, "Error ndpi_analyze_payload (allocation failure)\n");
225
0
  }
226
0
      }
227
0
    }
228
0
  }
229
0
}
230
231
/* ***************************************************** */
232
233
0
static int payload_stats_sort_asc(void *_a, void *_b) {
234
0
  struct payload_stats *a = (struct payload_stats *)_a;
235
0
  struct payload_stats *b = (struct payload_stats *)_b;
236
237
  //return(a->num_occurrencies - b->num_occurrencies);
238
0
  return(b->num_occurrencies - a->num_occurrencies);
239
0
}
240
241
/* ***************************************************** */
242
243
0
static void print_payload_stat(struct payload_stats *p, FILE *out) {
244
0
  u_int i;
245
0
  struct flow_id_stats *s, *tmp;
246
0
  struct packet_id_stats *s1, *tmp1;
247
248
0
  fprintf(out, "\t[");
249
250
0
  for(i=0; i<p->pattern_len; i++) {
251
0
    fprintf(out, "%c", ndpi_isprint(p->pattern[i]) ? p->pattern[i] : '.');
252
0
  }
253
254
0
  fprintf(out, "]");
255
0
  for(; i<16; i++) fprintf(out, " ");
256
0
  fprintf(out, "[");
257
258
0
  for(i=0; i<p->pattern_len; i++) {
259
0
    fprintf(out, "%s%02X", (i > 0) ? " " : "", ndpi_isprint(p->pattern[i]) ? p->pattern[i] : '.');
260
0
  }
261
262
0
  fprintf(out, "]");
263
264
0
  for(; i<16; i++) fprintf(out, "  ");
265
0
  for(i=p->pattern_len; i<max_pattern_len; i++) fprintf(out, " ");
266
267
0
  fprintf(out, "[len: %u][num_occurrencies: %u][flowId: ",
268
0
    p->pattern_len, p->num_occurrencies);
269
270
0
  i = 0;
271
0
  HASH_ITER(hh, p->flows, s, tmp) {
272
0
    fprintf(out, "%s%u", (i > 0) ? " " : "", s->flow_id);
273
0
    i++;
274
0
  }
275
276
0
  fprintf(out, "][packetIds: ");
277
278
  /* ******************************** */
279
280
0
  i = 0;
281
0
  HASH_ITER(hh, p->packets, s1, tmp1) {
282
0
    fprintf(out, "%s%u", (i > 0) ? " " : "", s1->packet_id);
283
0
    i++;
284
0
  }
285
286
0
  fprintf(out, "]\n");
287
288
289
0
}
290
291
/* ***************************************************** */
292
293
0
void ndpi_report_payload_stats(FILE *out) {
294
0
  struct payload_stats *p, *tmp;
295
0
  u_int num = 0;
296
297
0
  if(out)
298
0
    fprintf(out, "\n\nPayload Analysis\n");
299
300
0
  HASH_SORT(pstats, payload_stats_sort_asc);
301
302
0
  HASH_ITER(hh, pstats, p, tmp) {
303
0
    if(out && num <= max_num_reported_top_payloads)
304
0
      print_payload_stat(p, out);
305
306
0
    ndpi_free(p->pattern);
307
308
0
    {
309
0
      struct flow_id_stats *p1, *tmp1;
310
311
0
      HASH_ITER(hh, p->flows, p1, tmp1) {
312
0
  HASH_DEL(p->flows, p1);
313
0
  ndpi_free(p1);
314
0
      }
315
0
    }
316
317
0
    {
318
0
      struct packet_id_stats *p1, *tmp1;
319
320
0
      HASH_ITER(hh, p->packets, p1, tmp1) {
321
0
  HASH_DEL(p->packets, p1);
322
0
  ndpi_free(p1);
323
0
      }
324
0
    }
325
326
0
    HASH_DEL(pstats, p);
327
0
    ndpi_free(p);
328
0
    num++;
329
0
  }
330
0
}
331
332
/* ***************************************************** */
333
334
4.59M
void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) {
335
4.59M
  if(flow->ndpi_flow) { ndpi_flow_free(flow->ndpi_flow); flow->ndpi_flow = NULL; }
336
4.59M
}
337
338
/* ***************************************************** */
339
340
8
bool load_public_lists(struct ndpi_detection_module_struct *ndpi_str) {
341
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
342
  char *lists_path = "../lists/public_suffix_list.dat";
343
#else
344
8
  char *lists_path = "public_suffix_list.dat";
345
8
#endif
346
8
  struct stat st;
347
348
8
  if(stat(lists_path, &st) != 0)
349
0
    lists_path = &lists_path[1]; /* use local file */
350
351
8
  if(stat(lists_path, &st) == 0) {
352
8
    if(ndpi_load_domain_suffixes(ndpi_str, (char*)lists_path) == 0)
353
8
      return(true);
354
8
  }
355
356
0
  return(false);
357
8
}
358
359
/* ***************************************************** */
360
361
7.75k
void ndpi_stats_free(ndpi_stats_t *s) {
362
7.75k
  if (s->protocol_counter)           ndpi_free(s->protocol_counter);
363
7.75k
  if (s->protocol_counter_bytes)     ndpi_free(s->protocol_counter_bytes);
364
7.75k
  if (s->protocol_flows)             ndpi_free(s->protocol_flows);
365
7.75k
  if (s->fpc_protocol_counter)       ndpi_free(s->fpc_protocol_counter);
366
7.75k
  if (s->fpc_protocol_counter_bytes) ndpi_free(s->fpc_protocol_counter_bytes);
367
7.75k
  if (s->fpc_protocol_flows)         ndpi_free(s->fpc_protocol_flows);
368
369
7.75k
  s->num_protocols = 0;
370
7.75k
}
371
372
7.75k
int ndpi_stats_init(ndpi_stats_t *s, uint32_t num_protocols) {
373
7.75k
  memset(s, 0, sizeof(*s));
374
7.75k
  s->num_protocols = num_protocols;
375
376
7.75k
  s->protocol_counter           = ndpi_calloc(num_protocols, sizeof(u_int64_t));
377
7.75k
  s->protocol_counter_bytes     = ndpi_calloc(num_protocols, sizeof(u_int64_t));
378
7.75k
  s->protocol_flows             = ndpi_calloc(num_protocols, sizeof(u_int32_t));
379
7.75k
  s->fpc_protocol_counter       = ndpi_calloc(num_protocols, sizeof(u_int64_t));
380
7.75k
  s->fpc_protocol_counter_bytes = ndpi_calloc(num_protocols, sizeof(u_int64_t));
381
7.75k
  s->fpc_protocol_flows         = ndpi_calloc(num_protocols, sizeof(u_int32_t));
382
383
7.75k
  if(!s->protocol_counter || !s->protocol_counter_bytes || !s->protocol_flows ||
384
7.75k
     !s->fpc_protocol_counter || !s->fpc_protocol_counter_bytes || !s->fpc_protocol_flows) {
385
386
2.51k
    LOG(NDPI_LOG_ERROR, "[NDPI] %s: error allocating memory for ndpi_stats\n", __FUNCTION__);
387
2.51k
    return 0;
388
2.51k
  }
389
5.24k
  return 1;
390
7.75k
}
391
392
5.24k
void ndpi_stats_reset(ndpi_stats_t *s) {
393
5.24k
  memset(s->flow_count, 0, sizeof(s->flow_count));
394
5.24k
  s->guessed_flow_protocols = 0;
395
5.24k
  s->raw_packet_count = 0;
396
5.24k
  s->ip_packet_count = 0;
397
5.24k
  s->total_wire_bytes = 0;
398
5.24k
  s->total_ip_bytes = 0;
399
5.24k
  s->total_discarded_bytes = 0;
400
5.24k
  s->ndpi_flow_count = 0;
401
5.24k
  s->tcp_count = 0;
402
5.24k
  s->udp_count = 0;
403
5.24k
  s->mpls_count = 0;
404
5.24k
  s->pppoe_count = 0;
405
5.24k
  s->vlan_count = 0;
406
5.24k
  s->fragmented_count = 0;
407
5.24k
  s->max_packet_len = 0;
408
5.24k
  s->num_dissector_calls = 0;
409
410
5.24k
  memset(s->packet_len, 0, sizeof(s->packet_len));
411
5.24k
  memset(s->dpi_packet_count, 0, sizeof(s->dpi_packet_count));
412
5.24k
  memset(s->flow_confidence, 0, sizeof(s->flow_confidence));
413
5.24k
  memset(s->fpc_flow_confidence, 0, sizeof(s->fpc_flow_confidence));
414
5.24k
  memset(s->category_counter, 0, sizeof(s->category_counter));
415
5.24k
  memset(s->category_counter_bytes, 0, sizeof(s->category_counter_bytes));
416
5.24k
  memset(s->category_flows, 0, sizeof(s->category_flows));
417
5.24k
  memset(s->lru_stats, 0, sizeof(s->lru_stats));
418
5.24k
  memset(s->automa_stats, 0, sizeof(s->automa_stats));
419
5.24k
  memset(s->patricia_stats, 0, sizeof(s->patricia_stats));
420
421
5.24k
  if (s->protocol_counter)           memset(s->protocol_counter,           0, sizeof(u_int64_t) * s->num_protocols);
422
5.24k
  if (s->protocol_counter_bytes)     memset(s->protocol_counter_bytes,     0, sizeof(u_int64_t) * s->num_protocols);
423
5.24k
  if (s->protocol_flows)             memset(s->protocol_flows,             0, sizeof(u_int32_t) * s->num_protocols);
424
5.24k
  if (s->fpc_protocol_counter)       memset(s->fpc_protocol_counter,       0, sizeof(u_int64_t) * s->num_protocols);
425
5.24k
  if (s->fpc_protocol_counter_bytes) memset(s->fpc_protocol_counter_bytes, 0, sizeof(u_int64_t) * s->num_protocols);
426
5.24k
  if (s->fpc_protocol_flows)         memset(s->fpc_protocol_flows,         0, sizeof(u_int32_t) * s->num_protocols);
427
5.24k
}
428
429
/* ***************************************************** */
430
431
struct ndpi_workflow* ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs,
432
           pcap_t * pcap_handle, int do_init_flows_root,
433
           ndpi_serialization_format serialization_format,
434
8.91k
           struct ndpi_global_context *g_ctx) {
435
8.91k
  struct ndpi_detection_module_struct * module;
436
8.91k
  struct ndpi_workflow * workflow;
437
438
8.91k
  module = ndpi_init_detection_module(g_ctx);
439
440
8.91k
  if(module == NULL) {
441
46
    LOG(NDPI_LOG_ERROR, "global structure initialization failed\n");
442
46
    return NULL;
443
46
  }
444
445
8.86k
  if(protocolsDirPath != NULL)
446
8.86k
    ndpi_load_protocols_dir(module, protocolsDirPath);
447
  
448
8.86k
  workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow));
449
8.86k
  if(workflow == NULL) {
450
524
    LOG(NDPI_LOG_ERROR, "global structure initialization failed\n");
451
524
    ndpi_exit_detection_module(module);
452
524
    return NULL;
453
524
  }
454
455
8.34k
  workflow->pcap_handle = pcap_handle;
456
8.34k
  workflow->prefs       = *prefs;
457
8.34k
  workflow->ndpi_struct = module;
458
459
8.34k
  ndpi_set_user_data(module, workflow);
460
461
8.34k
  if(do_init_flows_root) {
462
8.33k
    workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *));
463
464
8.33k
    if(!workflow->ndpi_flows_root) {
465
579
      ndpi_exit_detection_module(module);
466
579
      ndpi_free(workflow);
467
579
      return NULL;
468
579
    }
469
8.33k
  }
470
471
7.76k
  workflow->ndpi_serialization_format = serialization_format;
472
473
7.76k
  if(do_load_lists)
474
8
    load_public_lists(module);
475
476
7.76k
  return workflow;
477
8.34k
}
478
479
/* ***************************************************** */
480
481
4.10M
void ndpi_flow_info_freer(void *node) {
482
4.10M
  struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node;
483
484
4.10M
  ndpi_flow_info_free_data(flow);
485
4.10M
  ndpi_free(flow);
486
4.10M
}
487
488
/* ***************************************************** */
489
490
4.11M
static void ndpi_free_flow_tls_data(struct ndpi_flow_info *flow) {
491
4.11M
  if(flow->dhcp_fingerprint) {
492
1.44k
    ndpi_free(flow->dhcp_fingerprint);
493
1.44k
    flow->dhcp_fingerprint = NULL;
494
1.44k
  }
495
496
4.11M
  if(flow->dhcp_class_ident) {
497
982
    ndpi_free(flow->dhcp_class_ident);
498
982
    flow->dhcp_class_ident = NULL;
499
982
  }
500
501
4.11M
  if(flow->server_hostname) {
502
585k
    ndpi_free(flow->server_hostname);
503
585k
    flow->server_hostname = NULL;
504
585k
  }
505
506
4.11M
  if(flow->bittorent_hash) {
507
1.42k
    ndpi_free(flow->bittorent_hash);
508
1.42k
    flow->bittorent_hash = NULL;
509
1.42k
  }
510
511
4.11M
  if(flow->telnet.username) {
512
541
    ndpi_free(flow->telnet.username);
513
541
    flow->telnet.username = NULL;
514
541
  }
515
516
4.11M
  if(flow->telnet.password) {
517
217
    ndpi_free(flow->telnet.password);
518
217
    flow->telnet.password = NULL;
519
217
  }
520
521
4.11M
  if(flow->ssh_tls.server_names) {
522
6.86k
    ndpi_free(flow->ssh_tls.server_names);
523
6.86k
    flow->ssh_tls.server_names = NULL;
524
6.86k
  }
525
526
4.11M
  if(flow->ssh_tls.advertised_alpns) {
527
37.0k
    ndpi_free(flow->ssh_tls.advertised_alpns);
528
37.0k
    flow->ssh_tls.advertised_alpns = NULL;
529
37.0k
  }
530
531
4.11M
  if(flow->ssh_tls.negotiated_alpn) {
532
6.05k
    ndpi_free(flow->ssh_tls.negotiated_alpn);
533
6.05k
    flow->ssh_tls.negotiated_alpn = NULL;
534
6.05k
  }
535
536
4.11M
  if(flow->ssh_tls.tls_supported_versions) {
537
31.2k
    ndpi_free(flow->ssh_tls.tls_supported_versions);
538
31.2k
    flow->ssh_tls.tls_supported_versions = NULL;
539
31.2k
  }
540
541
4.11M
  if(flow->ssh_tls.tls_issuerDN) {
542
9.04k
    ndpi_free(flow->ssh_tls.tls_issuerDN);
543
9.04k
    flow->ssh_tls.tls_issuerDN = NULL;
544
9.04k
  }
545
546
4.11M
  if(flow->ssh_tls.tls_subjectDN) {
547
9.84k
    ndpi_free(flow->ssh_tls.tls_subjectDN);
548
9.84k
    flow->ssh_tls.tls_subjectDN = NULL;
549
9.84k
  }
550
551
4.11M
  if(flow->ssh_tls.ja4_client_raw) {
552
42.5k
    ndpi_free(flow->ssh_tls.ja4_client_raw);
553
42.5k
    flow->ssh_tls.ja4_client_raw = NULL;
554
42.5k
  }
555
556
4.11M
  if(flow->ndpi_fingerprint) {
557
72.4k
    ndpi_free(flow->ndpi_fingerprint);
558
72.4k
    flow->ndpi_fingerprint = NULL;
559
72.4k
  }
560
561
4.11M
  if(flow->stun.mapped_address.aps) {
562
9.71k
    ndpi_free(flow->stun.mapped_address.aps);
563
9.71k
    flow->stun.mapped_address.aps = NULL;
564
9.71k
  }
565
4.11M
  if(flow->stun.other_address.aps) {
566
1.13k
    ndpi_free(flow->stun.other_address.aps);
567
1.13k
    flow->stun.other_address.aps = NULL;
568
1.13k
  }
569
4.11M
  if(flow->stun.peer_address.aps) {
570
5.08k
    ndpi_free(flow->stun.peer_address.aps);
571
5.08k
    flow->stun.peer_address.aps = NULL;
572
5.08k
  }
573
4.11M
  if(flow->stun.relayed_address.aps) {
574
3.07k
    ndpi_free(flow->stun.relayed_address.aps);
575
3.07k
    flow->stun.relayed_address.aps = NULL;
576
3.07k
  }
577
4.11M
  if(flow->stun.response_origin.aps) {
578
1.33k
    ndpi_free(flow->stun.response_origin.aps);
579
1.33k
    flow->stun.response_origin.aps = NULL;
580
1.33k
  }
581
4.11M
}
582
583
/* ***************************************************** */
584
585
4.11M
static void ndpi_free_flow_data_analysis(struct ndpi_flow_info *flow) {
586
4.11M
  if(flow->iat_c_to_s) ndpi_free_data_analysis(flow->iat_c_to_s, 1);
587
4.11M
  if(flow->iat_s_to_c) ndpi_free_data_analysis(flow->iat_s_to_c, 1);
588
589
4.11M
  if(flow->pktlen_c_to_s) ndpi_free_data_analysis(flow->pktlen_c_to_s, 1);
590
4.11M
  if(flow->pktlen_s_to_c) ndpi_free_data_analysis(flow->pktlen_s_to_c, 1);
591
592
4.11M
  if(flow->iat_flow) ndpi_free_data_analysis(flow->iat_flow, 1);
593
594
4.11M
  if(flow->entropy) ndpi_free(flow->entropy);
595
4.11M
  if(flow->last_entropy) ndpi_free(flow->last_entropy);
596
4.11M
}
597
598
/* ***************************************************** */
599
600
4.11M
void ndpi_flow_info_free_data(struct ndpi_flow_info *flow) {
601
602
4.11M
  ndpi_free_flow_info_half(flow);
603
4.11M
  ndpi_term_serializer(&flow->ndpi_flow_serializer);
604
4.11M
  ndpi_free_flow_data_analysis(flow);
605
4.11M
  ndpi_free_flow_tls_data(flow);
606
607
#ifdef DIRECTION_BINS
608
  ndpi_free_bin(&flow->payload_len_bin_src2dst);
609
  ndpi_free_bin(&flow->payload_len_bin_dst2src);
610
#else
611
4.11M
  ndpi_free_bin(&flow->payload_len_bin);
612
4.11M
#endif
613
614
4.11M
  if(flow->src_name)        ndpi_free(flow->src_name);
615
4.11M
  if(flow->dst_name)        ndpi_free(flow->dst_name);
616
4.11M
  if(flow->tcp_fingerprint) ndpi_free(flow->tcp_fingerprint);
617
4.11M
  if(flow->risk_str)        ndpi_free(flow->risk_str);
618
4.11M
  if(flow->flow_payload)    ndpi_free(flow->flow_payload);
619
4.11M
}
620
621
/* ***************************************************** */
622
623
7.75k
void ndpi_workflow_free(struct ndpi_workflow * workflow) {
624
7.75k
  u_int i;
625
626
769k
  for(i=0; i<workflow->prefs.num_roots; i++)
627
761k
    ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer);
628
629
7.75k
  if(addr_dump_path != NULL)
630
0
    ndpi_cache_address_dump(workflow->ndpi_struct, addr_dump_path, 0);
631
632
7.75k
  ndpi_exit_detection_module(workflow->ndpi_struct);
633
7.75k
  ndpi_free(workflow->ndpi_flows_root);
634
635
7.75k
  ndpi_stats_free(&workflow->stats);
636
637
7.75k
  ndpi_free(workflow);
638
7.75k
}
639
640
18.4M
static inline int cmp_n32(uint32_t a,uint32_t b) {
641
18.4M
  return a == b ? 0 : ntohl(a) < ntohl(b) ? -1:1;
642
18.4M
}
643
14.6M
static inline int cmp_n16(uint16_t a,uint16_t b) {
644
14.6M
  return a == b ? 0 : ntohs(a) < ntohs(b) ? -1:1;
645
14.6M
}
646
647
/* ***************************************************** */
648
649
110M
int ndpi_workflow_node_cmp(const void *a, const void *b) {
650
110M
  const struct ndpi_flow_info *fa = (const struct ndpi_flow_info*)a;
651
110M
  const struct ndpi_flow_info *fb = (const struct ndpi_flow_info*)b;
652
653
110M
  if(fa->hashval < fb->hashval) return(-1); else if(fa->hashval > fb->hashval) return(1);
654
655
  /* Flows have the same hash */
656
657
11.9M
  if(fa->vlan_id   < fb->vlan_id   ) return(-1); else { if(fa->vlan_id    > fb->vlan_id   ) return(1); }
658
11.9M
  if(fa->protocol  < fb->protocol  ) return(-1); else { if(fa->protocol   > fb->protocol  ) return(1); }
659
660
11.9M
  int r;
661
11.9M
  r = cmp_n32(fa->src_ip, fb->src_ip); if(r) return r;
662
8.07M
  r = cmp_n16(fa->src_port, fb->src_port) ; if(r) return r;
663
6.55M
  r = cmp_n32(fa->dst_ip, fb->dst_ip); if(r) return r;
664
6.55M
  r = cmp_n16(fa->dst_port, fb->dst_port);
665
666
6.55M
  return(r);
667
6.55M
}
668
669
/* ***************************************************** */
670
671
/**
672
 * \brief Update the byte count for the flow record.
673
 * \param f Flow data
674
 * \param x Data to use for update
675
 * \param len Length of the data (in bytes)
676
 * \return none
677
 */
678
static void
679
ndpi_flow_update_byte_count(struct ndpi_flow_info *flow, const void *x,
680
10.5M
                            unsigned int len, u_int8_t src_to_dst_direction) {
681
  /*
682
   * implementation note: The spec says that 4000 octets is enough of a
683
   * sample size to accurately reflect the byte distribution. Also, to avoid
684
   * wrapping of the byte count at the 16-bit boundry, we stop counting once
685
   * the 4000th octet has been seen for a flow.
686
   */
687
688
10.5M
  if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
689
    /* octet count was already incremented before processing this payload */
690
10.5M
    u_int32_t current_count;
691
692
10.5M
    if(src_to_dst_direction) {
693
8.50M
      current_count = flow->entropy->src2dst_l4_bytes - len;
694
8.50M
    } else {
695
2.07M
      current_count = flow->entropy->dst2src_l4_bytes - len;
696
2.07M
    }
697
698
10.5M
    if(current_count < ETTA_MIN_OCTETS) {
699
10.2M
      u_int32_t i;
700
10.2M
      const unsigned char *data = x;
701
702
2.49G
      for(i=0; i<len; i++) {
703
2.48G
        if(src_to_dst_direction) {
704
1.88G
          flow->entropy->src2dst_byte_count[data[i]]++;
705
1.88G
        } else {
706
599M
          flow->entropy->dst2src_byte_count[data[i]]++;
707
599M
        }
708
2.48G
        current_count++;
709
2.48G
        if(current_count >= ETTA_MIN_OCTETS) {
710
136k
          break;
711
136k
        }
712
2.48G
      }
713
10.2M
    }
714
10.5M
  }
715
10.5M
}
716
717
/* ***************************************************** */
718
719
/**
720
 * \brief Update the byte distribution mean for the flow record.
721
 * \param f Flow record
722
 * \param x Data to use for update
723
 * \param len Length of the data (in bytes)
724
 * \return none
725
 */
726
static void
727
ndpi_flow_update_byte_dist_mean_var(ndpi_flow_info_t *flow, const void *x,
728
10.5M
                                    unsigned int len, u_int8_t src_to_dst_direction) {
729
10.5M
  const unsigned char *data = x;
730
731
10.5M
  if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
732
10.5M
    unsigned int i;
733
734
3.31G
    for(i=0; i<len; i++) {
735
3.30G
      double delta;
736
737
3.30G
      if(src_to_dst_direction) {
738
2.46G
        flow->entropy->src2dst_num_bytes += 1;
739
2.46G
        delta = ((double)data[i] - flow->entropy->src2dst_bd_mean);
740
2.46G
        flow->entropy->src2dst_bd_mean += delta/((double)flow->entropy->src2dst_num_bytes);
741
2.46G
        flow->entropy->src2dst_bd_variance += delta*((double)data[i] - flow->entropy->src2dst_bd_mean);
742
2.46G
      } else {
743
844M
        flow->entropy->dst2src_num_bytes += 1;
744
844M
        delta = ((double)data[i] - flow->entropy->dst2src_bd_mean);
745
844M
        flow->entropy->dst2src_bd_mean += delta/((double)flow->entropy->dst2src_num_bytes);
746
844M
        flow->entropy->dst2src_bd_variance += delta*((double)data[i] - flow->entropy->dst2src_bd_mean);
747
844M
      }
748
3.30G
    }
749
10.5M
  }
750
10.5M
}
751
752
/* ***************************************************** */
753
754
static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow,
755
             const u_int8_t version,
756
             u_int16_t vlan_id,
757
             ndpi_packet_tunnel tunnel_type,
758
             const struct ndpi_iphdr *iph,
759
             const struct ndpi_ipv6hdr *iph6,
760
             u_int16_t ipsize,
761
             u_int16_t l4_packet_len,
762
             u_int16_t l4_offset,
763
             struct ndpi_tcphdr **tcph,
764
             struct ndpi_udphdr **udph,
765
             u_int16_t *sport, u_int16_t *dport,
766
             u_int8_t *proto,
767
             u_int8_t **payload,
768
             u_int16_t *payload_len,
769
             u_int8_t *src_to_dst_direction,
770
10.7M
                                                 pkt_timeval when) {
771
10.7M
  u_int32_t idx, hashval;
772
10.7M
  struct ndpi_flow_info flow;
773
10.7M
  void *ret;
774
10.7M
  const u_int8_t *l3, *l4;
775
10.7M
  u_int32_t l4_data_len = 0XFEEDFACE;
776
777
  /*
778
    Note: to keep things simple (ndpiReader is just a demo app)
779
    we handle IPv6 a-la-IPv4.
780
  */
781
10.7M
  if(version == IPVERSION) {
782
10.1M
    if(ipsize < 20)
783
28
      return NULL;
784
785
10.1M
    if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len)
786
10.1M
       /* || (iph->frag_off & htons(0x1FFF)) != 0 */)
787
40.3k
      return NULL;
788
789
10.1M
    l3 = (const u_int8_t*)iph;
790
10.1M
  } else {
791
545k
    if(l4_offset > ipsize)
792
0
      return NULL;
793
794
545k
    l3 = (const u_int8_t*)iph6;
795
545k
  }
796
10.6M
  if(ipsize < l4_offset + l4_packet_len)
797
1.76k
    return NULL;
798
799
10.6M
  *proto = iph->protocol;
800
801
10.6M
  if(l4_packet_len < 64)
802
4.72M
    workflow->stats.packet_len[0]++;
803
5.94M
  else if(l4_packet_len >= 64 && l4_packet_len < 128)
804
1.48M
    workflow->stats.packet_len[1]++;
805
4.46M
  else if(l4_packet_len >= 128 && l4_packet_len < 256)
806
1.64M
    workflow->stats.packet_len[2]++;
807
2.81M
  else if(l4_packet_len >= 256 && l4_packet_len < 1024)
808
1.75M
    workflow->stats.packet_len[3]++;
809
1.06M
  else if(l4_packet_len >= 1024 && l4_packet_len < 1500)
810
971k
    workflow->stats.packet_len[4]++;
811
89.0k
  else if(l4_packet_len >= 1500)
812
89.0k
    workflow->stats.packet_len[5]++;
813
814
10.6M
  if(l4_packet_len > workflow->stats.max_packet_len)
815
11.2k
    workflow->stats.max_packet_len = l4_packet_len;
816
817
10.6M
  l4 =& ((const u_int8_t *) l3)[l4_offset];
818
819
10.6M
  if(*proto == IPPROTO_TCP && l4_packet_len >= sizeof(struct ndpi_tcphdr)) {
820
7.56M
    u_int tcp_len;
821
822
    // TCP
823
7.56M
    workflow->stats.tcp_count++;
824
7.56M
    *tcph = (struct ndpi_tcphdr *)l4;
825
7.56M
    *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest);
826
7.56M
    tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len);
827
7.56M
    *payload = (u_int8_t*)&l4[tcp_len];
828
7.56M
    *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff);
829
7.56M
    l4_data_len = l4_packet_len - sizeof(struct ndpi_tcphdr);
830
7.56M
  } else if(*proto == IPPROTO_UDP && l4_packet_len >= sizeof(struct ndpi_udphdr)) {
831
    // UDP
832
2.93M
    workflow->stats.udp_count++;
833
2.93M
    *udph = (struct ndpi_udphdr *)l4;
834
2.93M
    *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest);
835
2.93M
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_udphdr)];
836
2.93M
    *payload_len = (l4_packet_len > sizeof(struct ndpi_udphdr)) ? l4_packet_len-sizeof(struct ndpi_udphdr) : 0;
837
2.93M
    l4_data_len = l4_packet_len - sizeof(struct ndpi_udphdr);
838
2.93M
  } else if(*proto == IPPROTO_ICMP) {
839
46.8k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmphdr )];
840
46.8k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmphdr)) ? l4_packet_len-sizeof(struct ndpi_icmphdr) : 0;
841
46.8k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmphdr);
842
46.8k
    *sport = *dport = 0;
843
125k
  } else if(*proto == IPPROTO_ICMPV6) {
844
62.0k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmp6hdr)];
845
62.0k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmp6hdr)) ? l4_packet_len-sizeof(struct ndpi_icmp6hdr) : 0;
846
62.0k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmp6hdr);
847
62.0k
    *sport = *dport = 0;
848
63.0k
  } else {
849
    // non tcp/udp protocols
850
63.0k
    *sport = *dport = 0;
851
63.0k
    l4_data_len = 0;
852
63.0k
  }
853
854
10.6M
  flow.protocol = iph->protocol, flow.vlan_id = vlan_id;
855
10.6M
  flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr;
856
10.6M
  flow.src_port = htons(*sport), flow.dst_port = htons(*dport);
857
10.6M
  flow.hashval = hashval = flow.protocol + ntohl(flow.src_ip) + ntohl(flow.dst_ip)
858
10.6M
    + ntohs(flow.src_port) + ntohs(flow.dst_port);
859
860
#if 0
861
  {
862
  char ip1[48],ip2[48];
863
       inet_ntop(AF_INET, &flow.src_ip, ip1, sizeof(ip1));
864
       inet_ntop(AF_INET, &flow.dst_ip, ip2, sizeof(ip2));
865
  printf("hashval=%u [%u][%u][%s:%u][%s:%u]\n", hashval, flow.protocol, flow.vlan_id,
866
        ip1, ntohs(flow.src_port),  ip2, ntohs(flow.dst_port));
867
  }
868
#endif
869
870
10.6M
  idx = hashval % workflow->prefs.num_roots;
871
10.6M
  ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
872
873
  /* to avoid two nodes in one binary tree for a flow */
874
10.6M
  int is_changed = 0;
875
10.6M
  if(ret == NULL) {
876
6.21M
    u_int32_t orig_src_ip = flow.src_ip;
877
6.21M
    u_int16_t orig_src_port = flow.src_port;
878
6.21M
    u_int32_t orig_dst_ip = flow.dst_ip;
879
6.21M
    u_int16_t orig_dst_port = flow.dst_port;
880
881
6.21M
    flow.src_ip = orig_dst_ip;
882
6.21M
    flow.src_port = orig_dst_port;
883
6.21M
    flow.dst_ip = orig_src_ip;
884
6.21M
    flow.dst_port = orig_src_port;
885
886
6.21M
    is_changed = 1;
887
888
6.21M
    ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
889
6.21M
  }
890
891
10.6M
  if(ret == NULL) {
892
4.11M
    if(workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) {
893
396
      LOG(NDPI_LOG_ERROR,
894
396
         "maximum flow count (%u) has been exceeded\n",
895
396
         workflow->prefs.max_ndpi_flows);
896
396
      return NULL;
897
4.11M
    } else {
898
4.11M
      struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)ndpi_malloc(sizeof(struct ndpi_flow_info));
899
900
4.11M
      if(newflow == NULL) {
901
1.45k
  LOG(NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__);
902
1.45k
  return(NULL);
903
1.45k
      } else
904
4.11M
        workflow->num_allocated_flows++;
905
906
4.11M
      memset(newflow, 0, sizeof(struct ndpi_flow_info));
907
4.11M
      newflow->flow_id = flow_id++;
908
4.11M
      newflow->hashval = hashval;
909
4.11M
      newflow->tunnel_type = tunnel_type;
910
4.11M
      newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id;
911
4.11M
      newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr;
912
4.11M
      newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport);
913
4.11M
      newflow->ip_version = version;
914
4.11M
      newflow->iat_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
915
4.11M
  newflow->iat_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW);
916
4.11M
      newflow->pktlen_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
917
4.11M
  newflow->pktlen_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
918
4.11M
  newflow->iat_flow = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW);
919
920
#ifdef DIRECTION_BINS
921
      ndpi_init_bin(&newflow->payload_len_bin_src2dst, ndpi_bin_family8, PLEN_NUM_BINS);
922
      ndpi_init_bin(&newflow->payload_len_bin_dst2src, ndpi_bin_family8, PLEN_NUM_BINS);
923
#else
924
4.11M
      ndpi_init_bin(&newflow->payload_len_bin, ndpi_bin_family8, PLEN_NUM_BINS);
925
4.11M
#endif
926
927
4.11M
      if (version == 4 || version == 6) {
928
4.11M
        uint16_t inet_addrlen = (version == 4) ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
929
4.11M
        newflow->src_name = ndpi_malloc(inet_addrlen);
930
4.11M
        newflow->dst_name = ndpi_malloc(inet_addrlen);
931
932
4.11M
        if(version == 4) {
933
3.98M
          if (newflow->src_name)
934
3.98M
            inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, inet_addrlen);
935
3.98M
          if (newflow->dst_name)
936
3.98M
            inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, inet_addrlen);
937
3.98M
        } else if (version == 6) {
938
130k
          newflow->src_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_src;
939
130k
          newflow->dst_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_dst;
940
941
130k
          if (newflow->src_name)
942
130k
            inet_ntop(AF_INET6, &newflow->src_ip6, newflow->src_name, inet_addrlen);
943
130k
          if (newflow->dst_name)
944
130k
            inet_ntop(AF_INET6, &newflow->dst_ip6, newflow->dst_name, inet_addrlen);
945
946
          /* For consistency across platforms replace :0: with :: */
947
130k
          if (newflow->src_name) ndpi_patchIPv6Address(newflow->src_name);
948
130k
          if (newflow->dst_name) ndpi_patchIPv6Address(newflow->dst_name);
949
130k
        }
950
4.11M
      }
951
952
4.11M
      if((newflow->ndpi_flow = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT)) == NULL) {
953
1.91k
  LOG(NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__);
954
1.91k
  ndpi_flow_info_free_data(newflow);
955
1.91k
  ndpi_free(newflow);
956
1.91k
  return(NULL);
957
1.91k
      } else
958
4.11M
  memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT);
959
960
4.11M
    if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown)
961
4.11M
    {
962
4.11M
      if (ndpi_init_serializer(&newflow->ndpi_flow_serializer,
963
4.11M
                               workflow->ndpi_serialization_format) != 0)
964
1.92k
      {
965
1.92k
        LOG(NDPI_LOG_ERROR, "ndpi serializer init failed\n");
966
1.92k
        ndpi_flow_info_free_data(newflow);
967
1.92k
        ndpi_free(newflow);
968
1.92k
        return(NULL);
969
1.92k
      }
970
4.11M
    }
971
972
4.10M
      if(ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp) == NULL) { /* Add */
973
1.59k
        ndpi_flow_info_free_data(newflow);
974
1.59k
        ndpi_free(newflow);
975
1.59k
        return(NULL);
976
1.59k
      }
977
4.10M
      workflow->stats.ndpi_flow_count++;
978
4.10M
      if(*proto == IPPROTO_TCP)
979
3.23M
        workflow->stats.flow_count[0]++;
980
874k
      else if(*proto == IPPROTO_UDP)
981
838k
        workflow->stats.flow_count[1]++;
982
36.3k
      else
983
36.3k
        workflow->stats.flow_count[2]++;
984
985
4.10M
      if(enable_flow_stats) {
986
4.08M
        newflow->entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
987
4.08M
        newflow->last_entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
988
4.08M
        if(!newflow->entropy || !newflow->last_entropy) {
989
0
          ndpi_tdelete(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
990
0
          ndpi_flow_info_free_data(newflow);
991
0
          ndpi_free(newflow);
992
0
          return(NULL);
993
0
        }
994
4.08M
        newflow->entropy->src2dst_pkt_len[newflow->entropy->src2dst_pkt_count] = l4_data_len;
995
4.08M
        newflow->entropy->src2dst_pkt_time[newflow->entropy->src2dst_pkt_count] = when;
996
4.08M
        if(newflow->entropy->src2dst_pkt_count == 0) {
997
4.08M
          newflow->entropy->src2dst_start = when;
998
4.08M
        }
999
4.08M
        newflow->entropy->src2dst_pkt_count++;
1000
        // Non zero app data.
1001
4.08M
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1002
4.04M
          newflow->entropy->src2dst_opackets++;
1003
4.04M
          newflow->entropy->src2dst_l4_bytes += l4_data_len;
1004
4.04M
        }
1005
4.08M
      }
1006
4.10M
      return newflow;
1007
4.10M
    }
1008
6.55M
  } else {
1009
6.55M
    struct ndpi_flow_info *rflow = *(struct ndpi_flow_info**)ret;
1010
1011
6.55M
    if(is_changed) {
1012
2.10M
  *src_to_dst_direction = 0, rflow->bidirectional |= 1;
1013
2.10M
    }
1014
4.45M
    else {
1015
4.45M
  *src_to_dst_direction = 1;
1016
4.45M
    }
1017
6.55M
    if(enable_flow_stats) {
1018
6.50M
      if(*src_to_dst_direction) {
1019
4.42M
        if(rflow->entropy->src2dst_pkt_count < max_num_packets_per_flow) {
1020
4.42M
          rflow->entropy->src2dst_pkt_len[rflow->entropy->src2dst_pkt_count] = l4_data_len;
1021
4.42M
          rflow->entropy->src2dst_pkt_time[rflow->entropy->src2dst_pkt_count] = when;
1022
4.42M
          rflow->entropy->src2dst_l4_bytes += l4_data_len;
1023
4.42M
          rflow->entropy->src2dst_pkt_count++;
1024
4.42M
        }
1025
        // Non zero app data.
1026
4.42M
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1027
4.21M
          rflow->entropy->src2dst_opackets++;
1028
4.21M
        }
1029
4.42M
      } else {
1030
2.07M
        if(rflow->entropy->dst2src_pkt_count < max_num_packets_per_flow) {
1031
2.07M
          rflow->entropy->dst2src_pkt_len[rflow->entropy->dst2src_pkt_count] = l4_data_len;
1032
2.07M
          rflow->entropy->dst2src_pkt_time[rflow->entropy->dst2src_pkt_count] = when;
1033
2.07M
          if(rflow->entropy->dst2src_pkt_count == 0) {
1034
636k
            rflow->entropy->dst2src_start = when;
1035
636k
          }
1036
2.07M
          rflow->entropy->dst2src_l4_bytes += l4_data_len;
1037
2.07M
          rflow->entropy->dst2src_pkt_count++;
1038
2.07M
        }
1039
        // Non zero app data.
1040
2.07M
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1041
1.91M
          rflow->entropy->dst2src_opackets++;
1042
1.91M
        }
1043
2.07M
      }
1044
6.50M
    }
1045
1046
6.55M
    return(rflow);
1047
6.55M
  }
1048
10.6M
}
1049
1050
/* ****************************************************** */
1051
1052
static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflow,
1053
              u_int16_t vlan_id,
1054
              ndpi_packet_tunnel tunnel_type,
1055
              const struct ndpi_ipv6hdr *iph6,
1056
              u_int16_t ipsize,
1057
              struct ndpi_tcphdr **tcph,
1058
              struct ndpi_udphdr **udph,
1059
              u_int16_t *sport, u_int16_t *dport,
1060
              u_int8_t *proto,
1061
              u_int8_t **payload,
1062
              u_int16_t *payload_len,
1063
              u_int8_t *src_to_dst_direction,
1064
546k
                                                  pkt_timeval when) {
1065
546k
  struct ndpi_iphdr iph;
1066
1067
546k
  if(ipsize < 40)
1068
52
    return(NULL);
1069
546k
  memset(&iph, 0, sizeof(iph));
1070
546k
  iph.version = IPVERSION;
1071
546k
  iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3];
1072
546k
  iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3];
1073
546k
  u_int8_t l4proto = iph6->ip6_hdr.ip6_un1_nxt;
1074
546k
  u_int16_t ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
1075
546k
  const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
1076
546k
  if(ipsize < sizeof(struct ndpi_ipv6hdr) + ip_len)
1077
380
    return(NULL);
1078
545k
  if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &l4proto) != 0) {
1079
674
    return(NULL);
1080
674
  }
1081
545k
  iph.protocol = l4proto;
1082
1083
545k
  return(get_ndpi_flow_info(workflow, 6, vlan_id, tunnel_type,
1084
545k
          &iph, iph6, ipsize,
1085
545k
          ip_len, l4ptr - (const u_int8_t *)iph6,
1086
545k
          tcph, udph, sport, dport,
1087
545k
          proto, payload,
1088
545k
          payload_len, src_to_dst_direction, when));
1089
545k
}
1090
1091
/* ****************************************************** */
1092
1093
14.5M
u_int8_t is_ndpi_proto(struct ndpi_flow_info *flow, u_int16_t id) {
1094
14.5M
  if((flow->detected_protocol.proto.master_protocol == id)
1095
14.5M
     || (flow->detected_protocol.proto.app_protocol == id))
1096
598k
    return(1);
1097
13.9M
  else
1098
13.9M
    return(0);
1099
14.5M
}
1100
1101
/* ****************************************************** */
1102
1103
74.3k
void correct_csv_data_field(char* data) {
1104
  /* Replace , with ; to avoid issues with CSVs */
1105
74.3k
  u_int i;
1106
1.08M
  for(i=0; data[i] != '\0'; i++) if(data[i] == ',') data[i] = ';';
1107
74.3k
}
1108
1109
/* ****************************************************** */
1110
1111
9.09M
u_int8_t plen2slot(u_int16_t plen) {
1112
  /*
1113
     Slots [32 bytes lenght]
1114
     0..31, 32..63 ...
1115
  */
1116
1117
9.09M
  if(plen > PLEN_MAX)
1118
86.3k
    return(PLEN_NUM_BINS-1);
1119
9.00M
  else
1120
9.00M
    return(plen/PLEN_BIN_LEN);
1121
9.09M
}
1122
1123
/* ****************************************************** */
1124
1125
static void dump_flow_fingerprint(struct ndpi_workflow * workflow,
1126
0
          struct ndpi_flow_info *flow) {
1127
0
  ndpi_serializer serializer;
1128
0
  bool rc;
1129
1130
0
  if(ndpi_init_serializer(&serializer, ndpi_serialization_format_json) == -1)
1131
0
    return;
1132
1133
0
  ndpi_serialize_start_of_block(&serializer, "fingerprint");
1134
0
  rc = ndpi_serialize_flow_fingerprint(workflow->ndpi_struct, flow->ndpi_flow, &serializer);
1135
0
  ndpi_serialize_end_of_block(&serializer);
1136
1137
0
  if(rc) {
1138
0
    char buf[64], *buffer;
1139
0
    u_int32_t buffer_len;
1140
1141
0
    ndpi_serialize_string_uint32(&serializer, "proto", flow->protocol);
1142
0
    ndpi_serialize_string_string(&serializer, "cli_ip", flow->src_name ? flow->src_name : "");
1143
0
    ndpi_serialize_string_uint32(&serializer, "cli_port", ntohs(flow->src_port));
1144
0
    ndpi_serialize_string_string(&serializer, "srv_ip", flow->dst_name ? flow->dst_name : "");
1145
0
    ndpi_serialize_string_uint32(&serializer, "srv_port", ntohs(flow->dst_port));
1146
0
    ndpi_serialize_string_string(&serializer, "proto",
1147
0
         ndpi_protocol2name(workflow->ndpi_struct,
1148
0
                flow->detected_protocol,
1149
0
                buf, sizeof(buf)));
1150
1151
0
    if(flow->server_hostname)
1152
0
      ndpi_serialize_string_string(&serializer, "server_hostname", flow->server_hostname);
1153
1154
0
    buffer = ndpi_serializer_get_buffer(&serializer, &buffer_len);
1155
0
    fprintf(fingerprint_fp, "%s\n", buffer);
1156
0
  }
1157
1158
0
  ndpi_term_serializer(&serializer);
1159
0
}
1160
1161
1162
static void add_to_address_port_list(ndpi_address_port_list *list, ndpi_address_port *ap)
1163
1.91M
{
1164
1.91M
  int new_num;
1165
1.91M
  void *new_buf;
1166
1.91M
  unsigned int i;
1167
1168
1.91M
  if(ap->port == 0)
1169
1.84M
    return;
1170
1171
  /* Avoid saving duplicates */
1172
126k
  for(i = 0; i < list->num_aps; i++)
1173
97.6k
    if(memcmp(&list->aps[i], ap, sizeof(*ap)) == 0)
1174
49.0k
      return;
1175
1176
29.0k
  if(list->num_aps == list->num_aps_allocated) {
1177
25.9k
    new_num = 1 + list->num_aps_allocated * 2;
1178
25.9k
    new_buf = ndpi_realloc(list->aps, list->num_aps_allocated * sizeof(ndpi_address_port),
1179
25.9k
                     new_num * sizeof(ndpi_address_port));
1180
25.9k
    if(!new_buf)
1181
2
      return;
1182
25.9k
    list->aps = new_buf;
1183
25.9k
    list->num_aps_allocated = new_num;
1184
25.9k
  }
1185
29.0k
  memcpy(&list->aps[list->num_aps++], ap, sizeof(ndpi_address_port));
1186
29.0k
}
1187
1188
/* ****************************************************** */
1189
1190
8.51M
static void process_ndpi_monitoring_info(struct ndpi_flow_info *flow) {
1191
8.51M
  if(!flow->ndpi_flow || !flow->ndpi_flow->monit)
1192
8.13M
    return;
1193
1194
383k
  if(flow->monitoring_state == 0 &&
1195
383k
     flow->ndpi_flow->monitoring) {
1196
    /* We just moved to monitoring state */
1197
3.53k
    flow->monitoring_state = 1;
1198
3.53k
    flow->num_packets_before_monitoring = flow->ndpi_flow->packet_direction_complete_counter[0] + flow->ndpi_flow->packet_direction_complete_counter[1];
1199
3.53k
  }
1200
1201
  /* In theory, we should check only for STUN.
1202
     However since we sometimes might not have STUN in protocol classification
1203
     (because we have only two protocols in flow->ndpi_flow->detected_protocol_stack[])
1204
     we need to check also for the other "master" protocols set by STUN dissector
1205
     See at the beginning of the STUN c file for further details
1206
   */
1207
383k
  if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_STUN ||
1208
383k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_STUN ||
1209
383k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_DTLS ||
1210
383k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_DTLS ||
1211
383k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_SRTP ||
1212
383k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_SRTP) {
1213
1214
379k
    add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.mapped_address);
1215
379k
    add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.other_address);
1216
379k
    add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.peer_address);
1217
379k
    add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.relayed_address);
1218
379k
    add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.response_origin);
1219
379k
    flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1220
1221
379k
    flow->stun.rtp_counters[0] = flow->ndpi_flow->stun.rtp_counters[0];
1222
379k
    flow->stun.rtp_counters[1] = flow->ndpi_flow->stun.rtp_counters[1];
1223
379k
  }
1224
383k
}
1225
1226
/* ****************************************************** */
1227
1228
static void serialize_monitoring_metadata(struct ndpi_flow_info *flow)
1229
4.05k
{
1230
4.05k
  unsigned int i;
1231
4.05k
  char buf[64];
1232
1233
4.05k
  if(!flow->ndpi_flow->monit)
1234
525
    return;
1235
1236
3.53k
  ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "monitoring");
1237
1238
3.53k
  switch(flow->detected_protocol.proto.master_protocol ? flow->detected_protocol.proto.master_protocol : flow->detected_protocol.proto.app_protocol) {
1239
2.13k
    case NDPI_PROTOCOL_STUN:
1240
2.64k
    case NDPI_PROTOCOL_DTLS:
1241
3.44k
    case NDPI_PROTOCOL_SRTP:
1242
3.44k
      ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "stun");
1243
1244
3.44k
      if(flow->stun.mapped_address.num_aps > 0) {
1245
2.11k
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "mapped_address");
1246
6.34k
        for(i = 0; i < flow->stun.mapped_address.num_aps; i++) {
1247
4.23k
          if(flow->stun.mapped_address.aps[i].port > 0) {
1248
4.23k
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "mapped_address",
1249
4.23k
                                         print_ndpi_address_port(&flow->stun.mapped_address.aps[i], buf, sizeof(buf)));
1250
4.23k
          }
1251
4.23k
        }
1252
2.11k
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1253
2.11k
      }
1254
1255
3.44k
      if(flow->stun.other_address.num_aps > 0) {
1256
218
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "other_address");
1257
603
        for(i = 0; i < flow->stun.other_address.num_aps; i++) {
1258
385
          if(flow->stun.other_address.aps[i].port > 0) {
1259
385
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "other_address",
1260
385
                                         print_ndpi_address_port(&flow->stun.other_address.aps[i], buf, sizeof(buf)));
1261
385
          }
1262
385
        }
1263
218
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1264
218
      }
1265
1266
3.44k
      if(flow->stun.peer_address.num_aps > 0) {
1267
1.08k
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "peer_address");
1268
3.88k
        for(i = 0; i < flow->stun.peer_address.num_aps; i++) {
1269
2.79k
          if(flow->stun.peer_address.aps[i].port > 0) {
1270
2.79k
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "peer_address",
1271
2.79k
                                         print_ndpi_address_port(&flow->stun.peer_address.aps[i], buf, sizeof(buf)));
1272
2.79k
          }
1273
2.79k
        }
1274
1.08k
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1275
1.08k
      }
1276
1277
3.44k
      if(flow->stun.relayed_address.num_aps > 0) {
1278
846
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "relayed_address");
1279
1.96k
        for(i = 0; i < flow->stun.relayed_address.num_aps; i++) {
1280
1.12k
          if(flow->stun.relayed_address.aps[i].port > 0) {
1281
1.12k
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "relayed_address",
1282
1.12k
                                         print_ndpi_address_port(&flow->stun.relayed_address.aps[i], buf, sizeof(buf)));
1283
1.12k
          }
1284
1.12k
        }
1285
846
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1286
846
      }
1287
1288
3.44k
      if(flow->stun.response_origin.num_aps > 0) {
1289
245
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "response_origin");
1290
695
        for(i = 0; i < flow->stun.response_origin.num_aps; i++) {
1291
450
          if(flow->stun.response_origin.aps[i].port > 0) {
1292
450
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "response_origin",
1293
450
                                         print_ndpi_address_port(&flow->stun.response_origin.aps[i], buf, sizeof(buf)));
1294
450
          }
1295
450
        }
1296
245
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1297
245
      }
1298
1299
3.44k
      ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer); /* stun */
1300
1301
3.44k
      break;
1302
3.53k
  }
1303
1304
3.53k
  ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer);
1305
3.53k
}
1306
1307
/* ****************************************************** */
1308
1309
4.56M
void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) {
1310
4.56M
  u_int i;
1311
4.56M
  char out[128], *s;
1312
1313
4.56M
  if(!flow->ndpi_flow) return;
1314
1315
4.09M
  flow->info_type = INFO_INVALID;
1316
1317
4.09M
  s = ndpi_get_flow_risk_info(flow->ndpi_flow, out, sizeof(out), 0 /* text */);
1318
1319
4.09M
  if(s != NULL)
1320
2.61M
    flow->risk_str = ndpi_strdup(s);
1321
1322
4.09M
  flow->confidence = flow->ndpi_flow->confidence;
1323
1324
4.09M
  flow->fpc = flow->ndpi_flow->fpc;
1325
1326
4.09M
  flow->num_dissector_calls = flow->ndpi_flow->num_dissector_calls;
1327
1328
4.09M
  ndpi_snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s",
1329
4.09M
    flow->ndpi_flow->host_server_name);
1330
1331
4.09M
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MINING)) {
1332
536
    ndpi_snprintf(flow->mining.currency, sizeof(flow->mining.currency), "%s",
1333
536
      flow->ndpi_flow->protos.mining.currency);
1334
536
  }
1335
1336
4.09M
  flow->risk = flow->ndpi_flow->risk;
1337
1338
4.09M
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DHCP)) {
1339
4.92k
    if(flow->ndpi_flow->protos.dhcp.fingerprint[0] != '\0')
1340
1.45k
      flow->dhcp_fingerprint = ndpi_strdup(flow->ndpi_flow->protos.dhcp.fingerprint);
1341
1342
4.92k
    if(flow->ndpi_flow->protos.dhcp.class_ident[0] != '\0')
1343
986
      flow->dhcp_class_ident = ndpi_strdup(flow->ndpi_flow->protos.dhcp.class_ident);
1344
4.08M
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_BITTORRENT) &&
1345
4.08M
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS) &&
1346
4.08M
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TLS)) {
1347
1.69M
    u_int j;
1348
1349
1.69M
    if(flow->ndpi_flow->protos.bittorrent.hash[0] != '\0') {
1350
1.45k
      u_int avail = sizeof(flow->ndpi_flow->protos.bittorrent.hash) * 2 + 1;
1351
1.45k
      flow->bittorent_hash = ndpi_malloc(avail);
1352
1353
1.45k
      if(flow->bittorent_hash) {
1354
29.9k
        for(i=0, j = 0; i < sizeof(flow->ndpi_flow->protos.bittorrent.hash); i++) {
1355
28.5k
          snprintf(&flow->bittorent_hash[j], avail-j, "%02x",
1356
28.5k
            flow->ndpi_flow->protos.bittorrent.hash[i]);
1357
1358
28.5k
          j += 2;
1359
28.5k
        }
1360
1361
1.42k
        flow->bittorent_hash[j] = '\0';
1362
1.42k
      }
1363
1.45k
    }
1364
1.69M
  }
1365
  /* TIVOCONNECT */
1366
2.39M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TIVOCONNECT)) {
1367
1.38k
    flow->info_type = INFO_TIVOCONNECT;
1368
1.38k
    ndpi_snprintf(flow->tivoconnect.identity_uuid, sizeof(flow->tivoconnect.identity_uuid),
1369
1.38k
                  "%s", flow->ndpi_flow->protos.tivoconnect.identity_uuid);
1370
1.38k
    ndpi_snprintf(flow->tivoconnect.machine, sizeof(flow->tivoconnect.machine),
1371
1.38k
                  "%s", flow->ndpi_flow->protos.tivoconnect.machine);
1372
1.38k
    ndpi_snprintf(flow->tivoconnect.platform, sizeof(flow->tivoconnect.platform),
1373
1.38k
                  "%s", flow->ndpi_flow->protos.tivoconnect.platform);
1374
1.38k
    ndpi_snprintf(flow->tivoconnect.services, sizeof(flow->tivoconnect.services),
1375
1.38k
                  "%s", flow->ndpi_flow->protos.tivoconnect.services);
1376
1.38k
  }
1377
  /* SOFTETHER */
1378
2.38M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SOFTETHER) &&
1379
2.38M
      !ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_HTTP)) {
1380
2.08k
    flow->info_type = INFO_SOFTETHER;
1381
2.08k
    ndpi_snprintf(flow->softether.ip, sizeof(flow->softether.ip), "%s",
1382
2.08k
                  flow->ndpi_flow->protos.softether.ip);
1383
2.08k
    ndpi_snprintf(flow->softether.port, sizeof(flow->softether.port), "%s",
1384
2.08k
                  flow->ndpi_flow->protos.softether.port);
1385
2.08k
    ndpi_snprintf(flow->softether.hostname, sizeof(flow->softether.hostname), "%s",
1386
2.08k
                  flow->ndpi_flow->protos.softether.hostname);
1387
2.08k
    ndpi_snprintf(flow->softether.fqdn, sizeof(flow->softether.fqdn), "%s",
1388
2.08k
                  flow->ndpi_flow->protos.softether.fqdn);
1389
2.08k
  }
1390
  /* SERVICE_LOCATION */
1391
2.38M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SERVICE_LOCATION)) {
1392
72.8k
    size_t i;
1393
1394
72.8k
    flow->info_type = INFO_GENERIC;
1395
72.8k
    flow->info[0] = 0;
1396
72.8k
    if (flow->ndpi_flow->protos.slp.url_count > 0)
1397
10.0k
      strncat(flow->info, "URL(s): ", sizeof(flow->info)-1);
1398
1399
83.7k
    for (i = 0; i < flow->ndpi_flow->protos.slp.url_count; ++i) {
1400
10.8k
      size_t length = strlen(flow->info);
1401
1402
10.8k
      strncat(flow->info + length, flow->ndpi_flow->protos.slp.url[i],
1403
10.8k
              sizeof(flow->info) - length);
1404
10.8k
      length = strlen(flow->info);
1405
1406
10.8k
      if (i < (size_t)flow->ndpi_flow->protos.slp.url_count - 1)
1407
809
        strncat(flow->info + length, ", ", sizeof(flow->info) - length);
1408
10.8k
    }
1409
72.8k
  }
1410
  /* NATPMP */
1411
2.31M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_NATPMP)) {
1412
2.84k
    flow->info_type = INFO_NATPMP;
1413
2.84k
    flow->natpmp.result_code = flow->ndpi_flow->protos.natpmp.result_code;
1414
2.84k
    flow->natpmp.internal_port = flow->ndpi_flow->protos.natpmp.internal_port;
1415
2.84k
    flow->natpmp.external_port = flow->ndpi_flow->protos.natpmp.external_port;
1416
2.84k
    inet_ntop(AF_INET, &flow->ndpi_flow->protos.natpmp.external_address.ipv4, &flow->natpmp.ip[0], sizeof(flow->natpmp.ip));
1417
2.84k
  }
1418
  /* DISCORD */
1419
2.31M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DISCORD) &&
1420
2.31M
          !ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1421
2.31M
          flow->ndpi_flow->protos.discord.client_ip[0] != '\0') {
1422
924
    flow->info_type = INFO_GENERIC;
1423
924
    ndpi_snprintf(flow->info, sizeof(flow->info), "Client IP: %s",
1424
924
                  flow->ndpi_flow->protos.discord.client_ip);
1425
924
  }
1426
  /* DNS */
1427
2.31M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS)) {
1428
73.3k
    if(flow->ndpi_flow->protos.dns.is_rsp_addr_ipv6[0] == 0)
1429
72.3k
    {
1430
72.3k
      flow->info_type = INFO_GENERIC;
1431
72.3k
      inet_ntop(AF_INET, &flow->ndpi_flow->protos.dns.rsp_addr[0].ipv4, flow->info, sizeof(flow->info));
1432
72.3k
    } else {
1433
1.03k
      flow->info_type = INFO_GENERIC;
1434
1.03k
      inet_ntop(AF_INET6, &flow->ndpi_flow->protos.dns.rsp_addr[0].ipv6, flow->info, sizeof(flow->info));
1435
1436
      /* For consistency across platforms replace :0: with :: */
1437
1.03k
      ndpi_patchIPv6Address(flow->info);
1438
1.03k
    }
1439
1440
73.3k
    if(flow->ndpi_flow->protos.dns.geolocation_iata_code[0] != '\0')
1441
205
      strcpy(flow->dns.geolocation_iata_code, flow->ndpi_flow->protos.dns.geolocation_iata_code);
1442
1443
73.3k
    if(flow->ndpi_flow->protos.dns.ptr_domain_name[0] != '\0')
1444
2.51k
      strcpy(flow->dns.ptr_domain_name, flow->ndpi_flow->protos.dns.ptr_domain_name);
1445
1446
73.3k
    flow->dns.transaction_id = flow->ndpi_flow->protos.dns.transaction_id;
1447
1448
#if 0
1449
    if(0) {
1450
      u_int8_t i;
1451
1452
      for(i=0; i<flow->ndpi_flow->protos.dns.num_rsp_addr; i++) {
1453
  char buf[64];
1454
1455
  if(flow->ndpi_flow->protos.dns.is_rsp_addr_ipv6[i] == 0) {
1456
    inet_ntop(AF_INET, &flow->ndpi_flow->protos.dns.rsp_addr[i].ipv4, buf, sizeof(buf));
1457
  } else {
1458
    inet_ntop(AF_INET6, &flow->ndpi_flow->protos.dns.rsp_addr[i].ipv6, buf, sizeof(buf));
1459
  }
1460
1461
  printf("(%s) %s [ttl: %u]\n", flow->host_server_name, buf, flow->ndpi_flow->protos.dns.rsp_addr_ttl[i]);
1462
      }
1463
    }
1464
#endif
1465
73.3k
  }
1466
  /* MDNS */
1467
2.23M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MDNS)) {
1468
7.26k
    flow->info_type = INFO_GENERIC;
1469
7.26k
    ndpi_snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->host_server_name);
1470
7.26k
  }
1471
  /* UBNTAC2 */
1472
2.23M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_UBNTAC2)) {
1473
1.00k
    flow->info_type = INFO_GENERIC;
1474
1.00k
    ndpi_snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.ubntac2.version);
1475
1.00k
  }
1476
  /* FTP, IMAP, SMTP, POP3 */
1477
2.22M
  else if(!ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1478
2.22M
          (ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_FTP_CONTROL) ||
1479
2.00M
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_MAIL_IMAP) ||
1480
2.00M
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_POP) ||
1481
2.00M
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_SMTP))) {
1482
20.5k
    flow->info_type = INFO_FTP_IMAP_POP_SMTP;
1483
20.5k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.username,
1484
20.5k
                  sizeof(flow->ftp_imap_pop_smtp.username),
1485
20.5k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.username);
1486
20.5k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.password,
1487
20.5k
                  sizeof(flow->ftp_imap_pop_smtp.password),
1488
20.5k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.password);
1489
20.5k
    flow->ftp_imap_pop_smtp.auth_failed =
1490
20.5k
      flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.auth_failed;
1491
20.5k
  }
1492
  /* TFTP */
1493
2.20M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TFTP)) {
1494
2.20k
    flow->info_type = INFO_GENERIC;
1495
2.20k
    if(flow->ndpi_flow->protos.tftp.filename[0] != '\0')
1496
219
      ndpi_snprintf(flow->info, sizeof(flow->info), "Filename: %s",
1497
219
                    flow->ndpi_flow->protos.tftp.filename);
1498
2.20k
  }
1499
  /* KERBEROS */
1500
2.20M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_KERBEROS)) {
1501
12.7k
    flow->info_type = INFO_KERBEROS;
1502
12.7k
    ndpi_snprintf(flow->kerberos.domain,
1503
12.7k
                  sizeof(flow->kerberos.domain),
1504
12.7k
                  "%s", flow->ndpi_flow->protos.kerberos.domain);
1505
12.7k
    ndpi_snprintf(flow->kerberos.hostname,
1506
12.7k
                  sizeof(flow->kerberos.hostname),
1507
12.7k
                  "%s", flow->ndpi_flow->protos.kerberos.hostname);
1508
12.7k
    ndpi_snprintf(flow->kerberos.username,
1509
12.7k
                  sizeof(flow->kerberos.username),
1510
12.7k
                  "%s", flow->ndpi_flow->protos.kerberos.username);
1511
  /* COLLECTD */
1512
2.19M
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_COLLECTD)) {
1513
359
    flow->info_type = INFO_GENERIC;
1514
359
    if(flow->ndpi_flow->protos.collectd.client_username[0] != '\0')
1515
27
      ndpi_snprintf(flow->info, sizeof(flow->info), "Username: %s",
1516
27
                    flow->ndpi_flow->protos.collectd.client_username);
1517
359
  }
1518
  /* SIP */
1519
2.19M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SIP)) {
1520
5.30k
    flow->info_type = INFO_SIP;
1521
5.30k
    if(flow->ndpi_flow->protos.sip.from)
1522
2.90k
      ndpi_snprintf(flow->sip.from, sizeof(flow->sip.from), "%s", flow->ndpi_flow->protos.sip.from);
1523
5.30k
    if(flow->ndpi_flow->protos.sip.from_imsi[0] != '\0')
1524
2
      ndpi_snprintf(flow->sip.from_imsi, sizeof(flow->sip.from_imsi), "%s", flow->ndpi_flow->protos.sip.from_imsi);
1525
5.30k
    if(flow->ndpi_flow->protos.sip.to)
1526
2.98k
      ndpi_snprintf(flow->sip.to, sizeof(flow->sip.to), "%s", flow->ndpi_flow->protos.sip.to);
1527
5.30k
    if(flow->ndpi_flow->protos.sip.to_imsi[0] != '\0')
1528
24
      ndpi_snprintf(flow->sip.to_imsi, sizeof(flow->sip.to_imsi), "%s", flow->ndpi_flow->protos.sip.to_imsi);
1529
5.30k
  }
1530
  /* BFCP */
1531
2.18M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_BFCP)) {
1532
256
    flow->info_type = INFO_BFCP;
1533
256
    flow->bfcp.conference_id = flow->ndpi_flow->protos.bfcp.conference_id;
1534
256
    flow->bfcp.user_id = flow->ndpi_flow->protos.bfcp.user_id;
1535
256
  }
1536
  /* TELNET */
1537
2.18M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TELNET)) {
1538
5.17k
    if(flow->ndpi_flow->protos.telnet.username[0] != '\0')
1539
541
      flow->telnet.username = ndpi_strdup(flow->ndpi_flow->protos.telnet.username);
1540
5.17k
    if(flow->ndpi_flow->protos.telnet.password[0] != '\0')
1541
217
      flow->telnet.password = ndpi_strdup(flow->ndpi_flow->protos.telnet.password);
1542
2.18M
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SSH)) {
1543
4.77k
    ndpi_snprintf(flow->host_server_name,
1544
4.77k
       sizeof(flow->host_server_name), "%s",
1545
4.77k
       flow->ndpi_flow->protos.ssh.client_signature);
1546
4.77k
    ndpi_snprintf(flow->ssh_tls.server_info, sizeof(flow->ssh_tls.server_info), "%s",
1547
4.77k
       flow->ndpi_flow->protos.ssh.server_signature);
1548
4.77k
    ndpi_snprintf(flow->ssh_tls.client_hassh, sizeof(flow->ssh_tls.client_hassh), "%s",
1549
4.77k
       flow->ndpi_flow->protos.ssh.hassh_client);
1550
4.77k
    ndpi_snprintf(flow->ssh_tls.server_hassh, sizeof(flow->ssh_tls.server_hassh), "%s",
1551
4.77k
       flow->ndpi_flow->protos.ssh.hassh_server);
1552
4.77k
  }
1553
  /* TLS/QUIC/DTLS/MAIL_S/FTPS */
1554
2.17M
  else if(ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack)) {
1555
222k
    flow->ssh_tls.ssl_version = flow->ndpi_flow->protos.tls_quic.ssl_version;
1556
222k
    flow->ssh_tls.quic_version = flow->ndpi_flow->protos.tls_quic.quic_version;
1557
1558
222k
    if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_QUIC))
1559
54.2k
      flow->idle_timeout_sec = flow->ndpi_flow->protos.tls_quic.quic_idle_timeout_sec;
1560
1561
222k
    if(flow->ndpi_flow->protos.tls_quic.server_names_len > 0 && flow->ndpi_flow->protos.tls_quic.server_names)
1562
6.88k
      flow->ssh_tls.server_names = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.server_names);
1563
1564
222k
    flow->ssh_tls.notBefore = flow->ndpi_flow->protos.tls_quic.notBefore;
1565
222k
    flow->ssh_tls.notAfter = flow->ndpi_flow->protos.tls_quic.notAfter;
1566
222k
    ndpi_snprintf(flow->ssh_tls.ja4_client, sizeof(flow->ssh_tls.ja4_client), "%s",
1567
222k
       flow->ndpi_flow->protos.tls_quic.ja4_client);
1568
1569
222k
    if(flow->ndpi_flow->ndpi.fingerprint)
1570
72.5k
      flow->ndpi_fingerprint = ndpi_strdup(flow->ndpi_flow->ndpi.fingerprint);
1571
  
1572
222k
    if(flow->ndpi_flow->protos.tls_quic.ja4_client_raw)
1573
42.5k
      flow->ssh_tls.ja4_client_raw = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.ja4_client_raw);
1574
1575
222k
    ndpi_snprintf(flow->ssh_tls.ja3_server, sizeof(flow->ssh_tls.ja3_server), "%s",
1576
222k
            flow->ndpi_flow->protos.tls_quic.ja3_server);
1577
222k
    flow->ssh_tls.server_unsafe_cipher = flow->ndpi_flow->protos.tls_quic.server_unsafe_cipher;
1578
222k
    flow->ssh_tls.server_cipher = flow->ndpi_flow->protos.tls_quic.server_cipher;
1579
1580
222k
    if(flow->ndpi_flow->protos.tls_quic.fingerprint_set) {
1581
11.1k
      memcpy(flow->ssh_tls.sha1_cert_fingerprint,
1582
11.1k
       flow->ndpi_flow->protos.tls_quic.sha1_certificate_fingerprint, 20);
1583
11.1k
      flow->ssh_tls.sha1_cert_fingerprint_set = 1;
1584
11.1k
    }
1585
1586
222k
    flow->ssh_tls.browser_heuristics = flow->ndpi_flow->protos.tls_quic.browser_heuristics;
1587
1588
222k
    if(flow->ndpi_flow->protos.tls_quic.issuerDN)
1589
9.05k
      flow->ssh_tls.tls_issuerDN = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.issuerDN);
1590
1591
222k
    if(flow->ndpi_flow->protos.tls_quic.subjectDN)
1592
9.86k
      flow->ssh_tls.tls_subjectDN = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.subjectDN);
1593
1594
222k
    flow->ssh_tls.encrypted_ch.version = flow->ndpi_flow->protos.tls_quic.encrypted_ch.version;
1595
1596
222k
    if(flow->ndpi_flow->protos.tls_quic.tls_supported_versions) {
1597
31.2k
      if((flow->ssh_tls.tls_supported_versions = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.tls_supported_versions)) != NULL)
1598
31.2k
  correct_csv_data_field(flow->ssh_tls.tls_supported_versions);
1599
31.2k
    }
1600
1601
222k
    if(flow->ndpi_flow->protos.tls_quic.advertised_alpns) {
1602
37.0k
      if((flow->ssh_tls.advertised_alpns = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.advertised_alpns)) != NULL)
1603
37.0k
  correct_csv_data_field(flow->ssh_tls.advertised_alpns);
1604
37.0k
    }
1605
1606
222k
    if(flow->ndpi_flow->protos.tls_quic.negotiated_alpn) {
1607
6.05k
      if((flow->ssh_tls.negotiated_alpn = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.negotiated_alpn)) != NULL)
1608
6.05k
  correct_csv_data_field(flow->ssh_tls.negotiated_alpn);
1609
6.05k
    }
1610
1611
222k
    if(enable_doh_dot_detection) {
1612
      /* For TLS we use TLS block lenght instead of payload lenght */
1613
1.32k
      ndpi_reset_bin(&flow->payload_len_bin);
1614
1615
1.32k
      for(i=0; i<flow->ndpi_flow->l4.tcp.tls.num_tls_blocks; i++) {
1616
0
  u_int16_t len = abs(flow->ndpi_flow->l4.tcp.tls.tls_application_blocks_len[i]);
1617
1618
  /* printf("[TLS_LEN] %u\n", len); */
1619
0
  ndpi_inc_bin(&flow->payload_len_bin, plen2slot(len), 1);
1620
0
      }
1621
1.32k
    }
1622
222k
  }
1623
  /* FASTCGI */
1624
1.95M
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_FASTCGI)) {
1625
1.20k
    flow->info_type = INFO_FASTCGI;
1626
1.20k
    flow->fast_cgi.method = flow->ndpi_flow->protos.fast_cgi.method;
1627
1.20k
    ndpi_snprintf(flow->fast_cgi.user_agent, sizeof(flow->fast_cgi.user_agent), "%s", flow->ndpi_flow->protos.fast_cgi.user_agent);
1628
1.20k
    ndpi_snprintf(flow->fast_cgi.url, sizeof(flow->fast_cgi.url), "%s", flow->ndpi_flow->protos.fast_cgi.url);
1629
1.20k
  }
1630
1631
4.09M
  if(!monitoring_enabled) {
1632
4.42k
    add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->stun.mapped_address);
1633
4.42k
    add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->stun.peer_address);
1634
4.42k
    add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->stun.relayed_address);
1635
4.42k
    add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->stun.response_origin);
1636
4.42k
    add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->stun.other_address);
1637
4.42k
  }
1638
1639
4.09M
  flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1640
1641
4.09M
  if(flow->ndpi_flow->tcp.fingerprint) {
1642
1.99M
    char buf[128];
1643
1644
1.99M
    snprintf(buf, sizeof(buf), "%s/%s", flow->ndpi_flow->tcp.fingerprint,
1645
1.99M
       ndpi_print_os_hint(flow->ndpi_flow->tcp.os_hint));
1646
1.99M
    flow->tcp_fingerprint = ndpi_strdup(buf);
1647
1.99M
  }
1648
  
1649
  /* HTTP metadata are "global" not in `flow->ndpi_flow->protos` union; for example, we can have
1650
     HTTP/BitTorrent and in that case we want to export also HTTP attributes */
1651
4.09M
  if(ndpi_stack_is_http_like(&flow->detected_protocol.protocol_stack)) { /* HTTP, HTTP_PROXY, HTTP_CONNECT */
1652
610k
    if(flow->ndpi_flow->http.url != NULL) {
1653
352k
      ndpi_snprintf(flow->http.url, sizeof(flow->http.url), "%s", flow->ndpi_flow->http.url);
1654
352k
    }
1655
    
1656
610k
    flow->http.response_status_code = flow->ndpi_flow->http.response_status_code;
1657
610k
    ndpi_snprintf(flow->http.content_type, sizeof(flow->http.content_type), "%s", flow->ndpi_flow->http.content_type ? flow->ndpi_flow->http.content_type : "");
1658
610k
    ndpi_snprintf(flow->http.server, sizeof(flow->http.server), "%s", flow->ndpi_flow->http.server ? flow->ndpi_flow->http.server : "");
1659
610k
    ndpi_snprintf(flow->http.request_content_type, sizeof(flow->http.request_content_type), "%s", flow->ndpi_flow->http.request_content_type ? flow->ndpi_flow->http.request_content_type : "");
1660
610k
    ndpi_snprintf(flow->http.nat_ip, sizeof(flow->http.nat_ip), "%s", flow->ndpi_flow->http.nat_ip ? flow->ndpi_flow->http.nat_ip : "");
1661
610k
    ndpi_snprintf(flow->http.filename, sizeof(flow->http.filename), "%s", flow->ndpi_flow->http.filename ? flow->ndpi_flow->http.filename : "");
1662
610k
    ndpi_snprintf(flow->http.username, sizeof(flow->http.username), "%s", flow->ndpi_flow->http.username ? flow->ndpi_flow->http.username : "");
1663
610k
    ndpi_snprintf(flow->http.password, sizeof(flow->http.password), "%s", flow->ndpi_flow->http.password ? flow->ndpi_flow->http.password : "");
1664
610k
  }
1665
1666
4.09M
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_RTP))
1667
7.08k
    memcpy(&flow->rtp, &flow->ndpi_flow->rtp, sizeof(flow->rtp));
1668
     
1669
4.09M
  ndpi_snprintf(flow->http.user_agent,
1670
4.09M
                sizeof(flow->http.user_agent),
1671
4.09M
                "%s", (flow->ndpi_flow->http.user_agent ? flow->ndpi_flow->http.user_agent : ""));
1672
1673
4.09M
  {
1674
4.09M
    ndpi_ip_addr_t ip_addr;
1675
4.09M
    struct ndpi_address_cache_item *c;
1676
1677
4.09M
    memset(&ip_addr, 0, sizeof(ip_addr));
1678
1679
4.09M
    if(flow->ip_version == 4)
1680
3.96M
      ip_addr.ipv4 = flow->dst_ip;
1681
128k
    else
1682
128k
      memcpy(&ip_addr.ipv6, &flow->dst_ip6, sizeof(struct ndpi_in6_addr));
1683
1684
4.09M
    c = ndpi_cache_address_find(workflow->ndpi_struct, ip_addr);
1685
1686
4.09M
    if(c) {
1687
585k
      flow->server_hostname = ndpi_strdup(c->hostname);
1688
585k
    }
1689
4.09M
  }
1690
1691
4.09M
  if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown) {
1692
4.09M
    if (ndpi_flow2json(workflow->ndpi_struct, flow->ndpi_flow,
1693
4.09M
                       flow->ip_version, flow->protocol,
1694
4.09M
           flow->vlan_id,
1695
4.09M
                       flow->src_ip, flow->dst_ip,
1696
4.09M
                       &flow->src_ip6, &flow->dst_ip6,
1697
4.09M
                       flow->src_port, flow->dst_port,
1698
4.09M
                       flow->detected_protocol,
1699
4.09M
                       &flow->ndpi_flow_serializer) != 0) {
1700
0
      LOG(NDPI_LOG_ERROR, "flow2json failed\n");
1701
0
      return;
1702
0
    }
1703
1704
4.09M
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed);
1705
4.09M
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "check_extra_packets", flow->check_extra_packets);
1706
1707
4.09M
    if(flow->ndpi_flow->monitoring) {
1708
4.05k
      serialize_monitoring_metadata(flow);
1709
4.05k
    }
1710
1711
4.09M
    if(flow->server_hostname)
1712
585k
      ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "server_hostname", flow->server_hostname);
1713
4.09M
  }
1714
1715
4.09M
  if(flow->detection_completed && (!flow->check_extra_packets)) {
1716
479k
    flow->flow_payload = flow->ndpi_flow->flow_payload, flow->flow_payload_len = flow->ndpi_flow->flow_payload_len;
1717
479k
    flow->ndpi_flow->flow_payload = NULL; /* We'll free the memory */
1718
1719
479k
    if(workflow->flow_callback != NULL)
1720
0
      workflow->flow_callback(workflow, flow, workflow->flow_callback_userdata);
1721
1722
479k
    if(fingerprint_fp)
1723
0
      dump_flow_fingerprint(workflow, flow);
1724
1725
479k
    ndpi_free_flow_info_half(flow);
1726
479k
  }
1727
4.09M
}
1728
1729
/* ****************************************************** */
1730
1731
/**
1732
 * @brief Clear entropy stats if it meets prereq.
1733
 */
1734
static void
1735
10.6M
ndpi_clear_entropy_stats(struct ndpi_flow_info *flow) {
1736
10.6M
  if(enable_flow_stats) {
1737
10.5M
    if(flow->entropy->src2dst_pkt_count + flow->entropy->dst2src_pkt_count == max_num_packets_per_flow) {
1738
325k
      memcpy(flow->last_entropy, flow->entropy,  sizeof(struct ndpi_entropy));
1739
325k
      memset(flow->entropy, 0x00, sizeof(struct ndpi_entropy));
1740
325k
    }
1741
10.5M
  }
1742
10.6M
}
1743
1744
7.55M
void update_tcp_flags_count(struct ndpi_flow_info* flow, struct ndpi_tcphdr* tcp, u_int8_t src_to_dst_direction){
1745
7.55M
  if(tcp->cwr){
1746
165k
    flow->cwr_count++;
1747
165k
    src_to_dst_direction ? flow->src2dst_cwr_count++ : flow->dst2src_cwr_count++;
1748
165k
  }
1749
7.55M
  if(tcp->ece){
1750
214k
    flow->ece_count++;
1751
214k
    src_to_dst_direction ? flow->src2dst_ece_count++ : flow->dst2src_ece_count++;
1752
214k
  }
1753
7.55M
  if(tcp->rst){
1754
274k
    flow->rst_count++;
1755
274k
    src_to_dst_direction ? flow->src2dst_rst_count++ : flow->dst2src_rst_count++;
1756
274k
  }
1757
7.55M
  if(tcp->ack){
1758
4.41M
    flow->ack_count++;
1759
4.41M
    src_to_dst_direction ? flow->src2dst_ack_count++ : flow->dst2src_ack_count++;
1760
4.41M
  }
1761
7.55M
  if(tcp->fin){
1762
370k
    flow->fin_count++;
1763
370k
    src_to_dst_direction ? flow->src2dst_fin_count++ : flow->dst2src_fin_count++;
1764
370k
  }
1765
7.55M
  if(tcp->syn){
1766
3.19M
    flow->syn_count++;
1767
3.19M
    src_to_dst_direction ? flow->src2dst_syn_count++ : flow->dst2src_syn_count++;
1768
3.19M
  }
1769
7.55M
  if(tcp->psh){
1770
2.58M
    flow->psh_count++;
1771
2.58M
    src_to_dst_direction ? flow->src2dst_psh_count++ : flow->dst2src_psh_count++;
1772
2.58M
  }
1773
7.55M
  if(tcp->urg){
1774
230k
    flow->urg_count++;
1775
230k
    src_to_dst_direction ? flow->src2dst_urg_count++ : flow->dst2src_urg_count++;
1776
230k
  }
1777
7.55M
}
1778
1779
/* ****************************************************** */
1780
1781
/**
1782
   Function to process the packet:
1783
   determine the flow of a packet and try to decode it
1784
   @return: 0 if success; else != 0
1785
1786
   @Note: ipsize = header->len - ip_offset ; rawsize = header->len
1787
*/
1788
static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow,
1789
             const u_int64_t time_ms,
1790
             u_int16_t vlan_id,
1791
             ndpi_packet_tunnel tunnel_type,
1792
             const struct ndpi_iphdr *iph,
1793
             struct ndpi_ipv6hdr *iph6,
1794
             u_int16_t ipsize, u_int16_t rawsize,
1795
             const struct pcap_pkthdr *header,
1796
             const u_char *packet,
1797
             pkt_timeval when,
1798
             ndpi_risk *flow_risk,
1799
10.7M
             struct ndpi_flow_info **flow_ext) {
1800
10.7M
  struct ndpi_flow_info *flow = NULL;
1801
10.7M
  struct ndpi_flow_struct *ndpi_flow = NULL;
1802
10.7M
  u_int8_t proto;
1803
10.7M
  struct ndpi_tcphdr *tcph = NULL;
1804
10.7M
  struct ndpi_udphdr *udph = NULL;
1805
10.7M
  u_int16_t sport, dport, payload_len = 0;
1806
10.7M
  u_int8_t *payload;
1807
10.7M
  u_int8_t src_to_dst_direction = 1;
1808
10.7M
  u_int8_t begin_or_end_tcp = 0;
1809
10.7M
  struct ndpi_proto nproto;
1810
1811
10.7M
  memset(&nproto, '\0', sizeof(nproto));
1812
1813
10.7M
  if(workflow->prefs.ignore_vlanid)
1814
42.8k
    vlan_id = 0;
1815
1816
10.7M
  if(iph)
1817
10.1M
    flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id,
1818
10.1M
            tunnel_type, iph, NULL,
1819
10.1M
            ipsize,
1820
10.1M
            ntohs(iph->tot_len) ? (ntohs(iph->tot_len) - (iph->ihl * 4)) : ipsize - (iph->ihl * 4) /* TSO */,
1821
10.1M
            iph->ihl * 4,
1822
10.1M
            &tcph, &udph, &sport, &dport,
1823
10.1M
            &proto,
1824
10.1M
            &payload, &payload_len, &src_to_dst_direction, when);
1825
546k
  else
1826
546k
    flow = get_ndpi_flow_info6(workflow, vlan_id,
1827
546k
             tunnel_type, iph6, ipsize,
1828
546k
             &tcph, &udph, &sport, &dport,
1829
546k
             &proto,
1830
546k
             &payload, &payload_len, &src_to_dst_direction, when);
1831
1832
10.7M
  if(flow != NULL) {
1833
10.6M
    pkt_timeval tdiff;
1834
1835
10.6M
    workflow->stats.ip_packet_count++;
1836
10.6M
    workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */,
1837
10.6M
      workflow->stats.total_ip_bytes += rawsize;
1838
10.6M
    ndpi_flow = flow->ndpi_flow;
1839
1840
10.6M
    if(tcph != NULL){
1841
7.55M
      update_tcp_flags_count(flow, tcph, src_to_dst_direction);
1842
7.55M
      if(tcph->syn && !flow->src2dst_bytes){
1843
2.05M
  flow->c_to_s_init_win = rawsize;
1844
5.50M
      }else if(tcph->syn && tcph->ack && flow->src2dst_bytes == flow->c_to_s_init_win){
1845
83.9k
  flow->s_to_c_init_win = rawsize;
1846
83.9k
      }
1847
7.55M
    }
1848
1849
10.6M
    if((tcph != NULL) && (tcph->fin || tcph->rst || tcph->syn))
1850
3.58M
      begin_or_end_tcp = 1;
1851
1852
10.6M
    if(flow->flow_last_pkt_time.tv_sec) {
1853
6.21M
      ndpi_timer_sub(&when, &flow->flow_last_pkt_time, &tdiff);
1854
1855
6.21M
      if(flow->iat_flow
1856
6.21M
   && (tdiff.tv_sec >= 0) /* Discard backward time */
1857
6.21M
   ) {
1858
6.14M
  u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1859
1860
6.14M
  if(ms > 0)
1861
2.29M
    ndpi_data_add_value(flow->iat_flow, ms);
1862
6.14M
      }
1863
6.21M
    }
1864
1865
10.6M
    memcpy(&flow->flow_last_pkt_time, &when, sizeof(when));
1866
1867
10.6M
    if(src_to_dst_direction) {
1868
8.55M
      if(flow->src2dst_last_pkt_time.tv_sec) {
1869
4.14M
  ndpi_timer_sub(&when, &flow->src2dst_last_pkt_time, &tdiff);
1870
1871
4.14M
  if(flow->iat_c_to_s
1872
4.14M
     && (tdiff.tv_sec >= 0) /* Discard backward time */
1873
4.14M
     ) {
1874
4.09M
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1875
1876
4.09M
    ndpi_data_add_value(flow->iat_c_to_s, ms);
1877
4.09M
  }
1878
4.14M
      }
1879
1880
8.55M
      ndpi_data_add_value(flow->pktlen_c_to_s, rawsize);
1881
8.55M
      flow->src2dst_packets++, flow->src2dst_bytes += rawsize, flow->src2dst_goodput_bytes += payload_len;
1882
8.55M
      memcpy(&flow->src2dst_last_pkt_time, &when, sizeof(when));
1883
1884
#ifdef DIRECTION_BINS
1885
      if(payload_len && (flow->src2dst_packets < MAX_NUM_BIN_PKTS))
1886
  ndpi_inc_bin(&flow->payload_len_bin_src2dst, plen2slot(payload_len));
1887
#endif
1888
8.55M
    } else {
1889
2.10M
      if(flow->dst2src_last_pkt_time.tv_sec && (!begin_or_end_tcp)) {
1890
1.36M
  ndpi_timer_sub(&when, &flow->dst2src_last_pkt_time, &tdiff);
1891
1892
1.36M
  if(flow->iat_s_to_c) {
1893
1.36M
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1894
1895
1.36M
    ndpi_data_add_value(flow->iat_s_to_c, ms);
1896
1.36M
  }
1897
1.36M
      }
1898
2.10M
      ndpi_data_add_value(flow->pktlen_s_to_c, rawsize);
1899
2.10M
      flow->dst2src_packets++, flow->dst2src_bytes += rawsize, flow->dst2src_goodput_bytes += payload_len;
1900
2.10M
      flow->risk &= ~(1ULL << NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */
1901
2.10M
      memcpy(&flow->dst2src_last_pkt_time, &when, sizeof(when));
1902
1903
#ifdef DIRECTION_BINS
1904
      if(payload_len && (flow->dst2src_packets < MAX_NUM_BIN_PKTS))
1905
  ndpi_inc_bin(&flow->payload_len_bin_dst2src, plen2slot(payload_len));
1906
#endif
1907
2.10M
    }
1908
1909
10.6M
#ifndef DIRECTION_BINS
1910
10.6M
    if(payload_len && ((flow->src2dst_packets+flow->dst2src_packets) < MAX_NUM_BIN_PKTS)) {
1911
#if 0
1912
      /* Discard packets until the protocol is detected */
1913
      if(flow->detected_protocol.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
1914
#endif
1915
9.09M
  ndpi_inc_bin(&flow->payload_len_bin, plen2slot(payload_len), 1);
1916
9.09M
    }
1917
10.6M
#endif
1918
1919
10.6M
    if(enable_payload_analyzer && (payload_len > 0))
1920
0
      ndpi_payload_analyzer(flow,
1921
0
          payload, payload_len,
1922
0
          workflow->stats.ip_packet_count);
1923
1924
10.6M
    if(enable_flow_stats) {
1925
      /* Update BD, distribution and mean. */
1926
10.5M
      ndpi_flow_update_byte_count(flow, payload, payload_len, src_to_dst_direction);
1927
10.5M
      ndpi_flow_update_byte_dist_mean_var(flow, payload, payload_len, src_to_dst_direction);
1928
      /* Update SPLT scores for first 32 packets. */
1929
10.5M
      if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
1930
10.5M
        if(flow->bidirectional)
1931
3.73M
          flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1932
3.73M
                flow->entropy->dst2src_pkt_len, flow->entropy->dst2src_pkt_time,
1933
3.73M
                flow->entropy->src2dst_start, flow->entropy->dst2src_start,
1934
3.73M
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1935
3.73M
                flow->src2dst_packets, flow->dst2src_packets,
1936
3.73M
                flow->entropy->src2dst_opackets, flow->entropy->dst2src_opackets,
1937
3.73M
                flow->entropy->src2dst_l4_bytes, flow->entropy->dst2src_l4_bytes, 1,
1938
3.73M
                flow->entropy->src2dst_byte_count, flow->entropy->dst2src_byte_count);
1939
6.85M
  else
1940
6.85M
    flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1941
6.85M
                NULL, NULL, flow->entropy->src2dst_start, flow->entropy->src2dst_start,
1942
6.85M
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1943
6.85M
                flow->src2dst_packets, 0,
1944
6.85M
                flow->entropy->src2dst_opackets, 0,
1945
6.85M
                flow->entropy->src2dst_l4_bytes, 0, 1,
1946
6.85M
                flow->entropy->src2dst_byte_count, NULL);
1947
10.5M
      }
1948
10.5M
    }
1949
1950
10.6M
    if(flow->first_seen_ms == 0)
1951
4.10M
      flow->first_seen_ms = time_ms;
1952
1953
10.6M
    flow->last_seen_ms = time_ms;
1954
1955
    /* Copy packets entropy if num packets count == 10 */
1956
10.6M
    ndpi_clear_entropy_stats(flow);
1957
    /* Reset IAT reeference times (see https://github.com/ntop/nDPI/pull/1316) */
1958
10.6M
    if(((flow->src2dst_packets + flow->dst2src_packets) % max_num_packets_per_flow) == 0) {
1959
328k
      memset(&flow->src2dst_last_pkt_time, '\0', sizeof(flow->src2dst_last_pkt_time));
1960
328k
      memset(&flow->dst2src_last_pkt_time, '\0', sizeof(flow->dst2src_last_pkt_time));
1961
328k
      memset(&flow->flow_last_pkt_time, '\0', sizeof(flow->flow_last_pkt_time));
1962
328k
    }
1963
1964
10.6M
    if((human_readeable_string_len != 0) && (!flow->has_human_readeable_strings)) {
1965
7.13M
      u_int8_t skip = 0;
1966
1967
7.13M
      if(proto == IPPROTO_TCP &&
1968
7.13M
   (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1969
5.40M
    is_ndpi_proto(flow, NDPI_PROTOCOL_SSH))) {
1970
533k
  if((flow->src2dst_packets+flow->dst2src_packets) < 10 /* MIN_NUM_ENCRYPT_SKIP_PACKETS */)
1971
169k
    skip = 1; /* Skip initial negotiation packets */
1972
533k
      }
1973
1974
7.13M
      if((!skip) && ((flow->src2dst_packets+flow->dst2src_packets) < 100)) {
1975
6.79M
  if(ndpi_has_human_readeable_string((char*)packet, header->caplen,
1976
6.79M
             human_readeable_string_len,
1977
6.79M
             flow->human_readeable_string_buffer,
1978
6.79M
             sizeof(flow->human_readeable_string_buffer)) == 1)
1979
1.76M
    flow->has_human_readeable_strings = 1;
1980
6.79M
      }
1981
7.13M
    } else {
1982
3.52M
      if(proto == IPPROTO_TCP &&
1983
3.52M
         (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1984
2.15M
          is_ndpi_proto(flow, NDPI_PROTOCOL_SSH)))
1985
65.5k
  flow->has_human_readeable_strings = 0;
1986
3.52M
    }
1987
10.6M
  } else { // flow is NULL
1988
50.5k
    workflow->stats.total_discarded_bytes += header->len;
1989
50.5k
    return(nproto);
1990
50.5k
  }
1991
1992
10.6M
  if(!flow->detection_completed) {
1993
8.56M
    struct ndpi_flow_input_info input_info;
1994
1995
8.56M
    u_int enough_packets =
1996
8.56M
      ((proto == IPPROTO_UDP && (max_num_udp_dissected_pkts > 0 && flow->src2dst_packets + flow->dst2src_packets >= max_num_udp_dissected_pkts)) ||
1997
8.56M
       (proto == IPPROTO_TCP && (max_num_tcp_dissected_pkts > 0 && flow->src2dst_packets + flow->dst2src_packets >= max_num_tcp_dissected_pkts))) ? 1 : 0;
1998
1999
#if 0
2000
    printf("%s()\n", __FUNCTION__);
2001
#endif
2002
2003
8.56M
    if(proto == IPPROTO_TCP)
2004
6.42M
      workflow->stats.dpi_packet_count[0]++;
2005
2.14M
    else if(proto == IPPROTO_UDP)
2006
2.09M
      workflow->stats.dpi_packet_count[1]++;
2007
49.2k
    else
2008
49.2k
      workflow->stats.dpi_packet_count[2]++;
2009
8.56M
    flow->dpi_packets++;
2010
2011
8.56M
    memset(&input_info, '\0', sizeof(input_info)); /* To be sure to set to "unknown" any fields */
2012
    /* Set here any information (easily) available; in this trivial example we don't have any */
2013
8.56M
    input_info.in_pkt_dir = NDPI_IN_PKT_DIR_UNKNOWN;
2014
8.56M
    input_info.seen_flow_beginning = NDPI_FLOW_BEGINNING_UNKNOWN;
2015
8.56M
    malloc_size_stats = 1;
2016
8.56M
    flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow,
2017
8.56M
                  iph ? (uint8_t *)iph : (uint8_t *)iph6,
2018
8.56M
                  ipsize, time_ms, &input_info);
2019
8.56M
    if(monitoring_enabled)
2020
8.51M
      process_ndpi_monitoring_info(flow);
2021
8.56M
    enough_packets |= ndpi_flow->fail_with_unknown;
2022
8.56M
    if(enough_packets || (flow->detected_protocol.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)) {
2023
2.67M
      if((!enough_packets)
2024
2.67M
   && ndpi_extra_dissection_possible(workflow->ndpi_struct, ndpi_flow))
2025
2.20M
  ; /* Wait for further metadata */
2026
479k
      else {
2027
  /* New protocol detected or give up */
2028
479k
  flow->detection_completed = 1;
2029
2030
479k
  if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN) {
2031
23.9k
    u_int8_t proto_guessed;
2032
2033
23.9k
    flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow,
2034
23.9k
                &proto_guessed);
2035
23.9k
    if(proto_guessed) workflow->stats.guessed_flow_protocols++;
2036
23.9k
  }
2037
2038
479k
  process_ndpi_collected_info(workflow, flow);
2039
479k
      }
2040
2.67M
    }
2041
    /* Let's try to save client-server direction */
2042
8.56M
    flow->current_pkt_from_client_to_server = input_info.in_pkt_dir;
2043
2044
8.56M
    malloc_size_stats = 0;
2045
8.56M
  } else {
2046
2.09M
    flow->current_pkt_from_client_to_server = NDPI_IN_PKT_DIR_UNKNOWN; /* Unknown */
2047
2.09M
  }
2048
2049
#if 0
2050
  if(flow->risk != 0) {
2051
    FILE *r = fopen("/tmp/e", "a");
2052
2053
    if(r) {
2054
      fprintf(r, "->>> %u [%08X]\n", flow->risk, flow->risk);
2055
      fclose(r);
2056
    }
2057
  }
2058
#endif
2059
2060
10.6M
  *flow_risk = flow->risk;
2061
10.6M
  *flow_ext = flow;
2062
2063
10.6M
  return(flow->detected_protocol);
2064
10.7M
}
2065
2066
/* ****************************************************** */
2067
2068
179k
int ndpi_is_datalink_supported(int datalink_type) {
2069
  /* Keep in sync with the similar switch in ndpi_workflow_process_packet */
2070
179k
  switch(datalink_type) {
2071
15.2k
  case DLT_NULL:
2072
15.2k
  case DLT_PPP_SERIAL:
2073
15.6k
  case DLT_C_HDLC:
2074
17.1k
  case DLT_PPP:
2075
17.1k
#ifdef DLT_IPV4
2076
22.2k
  case DLT_IPV4:
2077
22.2k
#endif
2078
22.2k
#ifdef DLT_IPV6
2079
23.3k
  case DLT_IPV6:
2080
23.3k
#endif
2081
163k
  case DLT_EN10MB:
2082
171k
  case DLT_LINUX_SLL:
2083
171k
  case DLT_IEEE802_11_RADIO:
2084
178k
  case DLT_RAW:
2085
178k
  case DLT_PPI:
2086
179k
  case LINKTYPE_LINUX_SLL2:
2087
179k
    return 1;
2088
286
  default:
2089
286
    return 0;
2090
179k
  }
2091
179k
}
2092
2093
2.77M
static bool ndpi_is_valid_vxlan(const struct pcap_pkthdr *header, const u_char *packet, u_int16_t ip_offset, u_int16_t ip_len){
2094
2.77M
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr)) {
2095
87.9k
    return false;
2096
87.9k
  }
2097
2.68M
  u_int32_t vxlan_dst_port  = ntohs(4789);
2098
2.68M
  struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2099
2.68M
  u_int offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr);
2100
  /**
2101
   * rfc-7348
2102
   *    VXLAN Header:  This is an 8-byte field that has:
2103
2104
    - Flags (8 bits): where the I flag MUST be set to 1 for a valid
2105
      VXLAN Network ID (VNI).  The other 7 bits (designated "R") are
2106
      reserved fields and MUST be set to zero on transmission and
2107
      ignored on receipt.
2108
2109
    - VXLAN Segment ID/VXLAN Network Identifier (VNI): this is a
2110
      24-bit value used to designate the individual VXLAN overlay
2111
      network on which the communicating VMs are situated.  VMs in
2112
      different VXLAN overlay networks cannot communicate with each
2113
      other.
2114
2115
    - Reserved fields (24 bits and 8 bits): MUST be set to zero on
2116
      transmission and ignored on receipt.
2117
         VXLAN Header:
2118
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2119
    |R|R|R|R|I|R|R|R|            Reserved                           |
2120
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2121
    |                VXLAN Network Identifier (VNI) |   Reserved    |
2122
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2123
  */
2124
2.68M
  if((udp->dest == vxlan_dst_port || udp->source == vxlan_dst_port) &&
2125
2.68M
    (packet[offset] == 0x8) &&
2126
2.68M
    (packet[offset + 1] == 0x0) &&
2127
2.68M
    (packet[offset + 2] == 0x0) &&
2128
2.68M
    (packet[offset + 3] == 0x0) &&
2129
2.68M
    (packet[offset + 7] ==  0x0)) {
2130
17.3k
    return true;
2131
17.3k
    }
2132
2.67M
  return false;
2133
2.68M
}
2134
2135
17.3k
static inline u_int ndpi_skip_vxlan(u_int16_t ip_offset, u_int16_t ip_len){
2136
17.3k
  return ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr);
2137
17.3k
}
2138
2139
static uint32_t ndpi_is_valid_gre_tunnel(const struct pcap_pkthdr *header,
2140
                const u_char *packet, const u_int16_t ip_offset,
2141
14.6k
                const u_int16_t ip_len) {
2142
14.6k
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr))
2143
0
    return 0; /* Too short for GRE header*/
2144
14.6k
  uint32_t offset = ip_offset + ip_len;
2145
14.6k
  struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[offset];
2146
14.6k
  offset += sizeof(struct ndpi_gre_basehdr);
2147
  /*
2148
    The GRE flags are encoded in the first two octets.  Bit 0 is the
2149
    most significant bit, bit 15 is the least significant bit.  Bits
2150
    13 through 15 are reserved for the Version field.  Bits 9 through
2151
    12 are reserved for future use and MUST be transmitted as zero.
2152
  */
2153
14.6k
  if(NDPI_GRE_IS_FLAGS(grehdr->flags))
2154
1.09k
    return 0;
2155
13.5k
  if(NDPI_GRE_IS_REC(grehdr->flags))
2156
1.33k
    return 0;
2157
  /*GRE rfc 2890 that update 1701*/
2158
12.1k
  if(NDPI_GRE_IS_VERSION_0(grehdr->flags)) {
2159
5.65k
    if(NDPI_GRE_IS_CSUM(grehdr->flags)) {
2160
1.27k
      if(header->caplen < offset + 4)
2161
102
        return 0;
2162
      /*checksum field and offset field*/
2163
1.17k
      offset += 4;
2164
1.17k
    }
2165
5.55k
    if(NDPI_GRE_IS_KEY(grehdr->flags)) {
2166
1.71k
      if(header->caplen < offset + 4)
2167
170
        return 0;
2168
1.54k
      offset += 4;
2169
1.54k
    }
2170
5.38k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2171
1.51k
      if(header->caplen < offset + 4)
2172
151
        return 0;
2173
1.36k
      offset += 4;
2174
1.36k
    }
2175
6.52k
  } else if(NDPI_GRE_IS_VERSION_1(grehdr->flags)) { /*rfc-2637 section 4.1 enhanced gre*/
2176
6.26k
    if(NDPI_GRE_IS_CSUM(grehdr->flags))
2177
180
      return 0;
2178
6.08k
    if(NDPI_GRE_IS_ROUTING(grehdr->flags))
2179
257
      return 0;
2180
5.82k
    if(!NDPI_GRE_IS_KEY(grehdr->flags))
2181
991
      return 0;
2182
4.83k
    if(NDPI_GRE_IS_STRICT(grehdr->flags))
2183
190
      return 0;
2184
4.64k
    if(grehdr->protocol != NDPI_GRE_PROTO_PPP)
2185
360
      return 0;
2186
    /*key field*/
2187
4.28k
    if(header->caplen < offset + 4)
2188
164
      return 0;
2189
4.12k
    offset += 4;
2190
4.12k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2191
1.08k
      if(header->caplen < offset + 4)
2192
144
        return 0;
2193
945
      offset += 4;
2194
945
    }
2195
3.97k
    if(NDPI_GRE_IS_ACK(grehdr->flags)) {
2196
616
      if(header->caplen < offset + 4)
2197
49
        return 0;
2198
567
      offset += 4;
2199
567
    }
2200
3.97k
  } else { /*support only ver 0, 1*/
2201
260
    return 0;
2202
260
  }
2203
9.16k
  return offset;
2204
12.1k
}
2205
2206
/* ****************************************************** */
2207
2208
struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow,
2209
                 const struct pcap_pkthdr *header,
2210
                 const u_char *packet,
2211
                 ndpi_risk *flow_risk,
2212
11.3M
                 struct ndpi_flow_info **flow) {
2213
  /*
2214
   * Declare pointers to packet headers
2215
   */
2216
  /* --- Ethernet header --- */
2217
11.3M
  const struct ndpi_ethhdr *ethernet;
2218
  /* --- LLC header --- */
2219
11.3M
  const struct ndpi_llc_header_snap *llc;
2220
2221
  /* --- Cisco HDLC header --- */
2222
11.3M
  const struct ndpi_chdlc *chdlc;
2223
2224
  /* --- Radio Tap header --- */
2225
11.3M
  const struct ndpi_radiotap_header *radiotap;
2226
  /* --- Wifi header --- */
2227
11.3M
  const struct ndpi_wifi_header *wifi;
2228
2229
  /* --- MPLS header --- */
2230
11.3M
  union mpls {
2231
11.3M
    uint32_t u32;
2232
11.3M
    struct ndpi_mpls_header mpls;
2233
11.3M
  } mpls;
2234
2235
  /** --- IP header --- **/
2236
11.3M
  struct ndpi_iphdr *iph;
2237
  /** --- IPv6 header --- **/
2238
11.3M
  struct ndpi_ipv6hdr *iph6;
2239
2240
11.3M
  struct ndpi_proto nproto;
2241
11.3M
  ndpi_packet_tunnel tunnel_type = ndpi_no_tunnel;
2242
2243
  /* lengths and offsets */
2244
11.3M
  u_int32_t eth_offset = 0, dlt;
2245
11.3M
  u_int16_t radio_len, header_length;
2246
11.3M
  u_int16_t fc;
2247
11.3M
  u_int16_t type = 0;
2248
11.3M
  int wifi_len = 0;
2249
11.3M
  int pyld_eth_len = 0;
2250
11.3M
  int check;
2251
11.3M
  u_int64_t time_ms;
2252
11.3M
  u_int16_t ip_offset = 0, ip_len;
2253
11.3M
  u_int16_t frag_off = 0, vlan_id = 0;
2254
11.3M
  u_int8_t proto = 0, recheck_type;
2255
11.3M
  u_int8_t ip_ver, ppp_type;
2256
  /*u_int32_t label;*/
2257
2258
  /* counters */
2259
11.3M
  u_int8_t vlan_packet = 0;
2260
2261
11.3M
  *flow_risk = 0 /* NDPI_NO_RISK */;
2262
11.3M
  *flow = NULL;
2263
2264
11.3M
  memset(&nproto, '\0', sizeof(nproto));
2265
2266
11.3M
  if((addr_dump_path != NULL) && (workflow->stats.raw_packet_count == 0)) {
2267
    /* At the first packet flush expired cached addresses */
2268
0
    ndpi_cache_address_flush_expired(workflow->ndpi_struct, header->ts.tv_sec);
2269
0
  }
2270
2271
  /* Increment raw packet counter */
2272
11.3M
  workflow->stats.raw_packet_count++;
2273
2274
  /* setting time */
2275
11.3M
  time_ms = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION);
2276
2277
  /* safety check */
2278
11.3M
  if(workflow->last_time > time_ms) {
2279
    /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */
2280
11.2M
    time_ms = workflow->last_time;
2281
11.2M
  }
2282
  /* update last time value */
2283
11.3M
  workflow->last_time = time_ms;
2284
2285
  /*** check Data Link type ***/
2286
11.3M
  int datalink_type;
2287
2288
#ifdef USE_DPDK
2289
  datalink_type = DLT_EN10MB;
2290
#else
2291
11.3M
  datalink_type = (int)pcap_datalink(workflow->pcap_handle);
2292
11.3M
#endif
2293
2294
11.3M
 datalink_check:
2295
  // 20 for min iph and 8 for min UDP
2296
11.3M
  if(header->caplen < eth_offset + 28)
2297
241k
    return(nproto); /* Too short */
2298
2299
  /* Keep in sync with ndpi_is_datalink_supported() */
2300
11.1M
  switch(datalink_type) {
2301
474k
  case DLT_NULL:
2302
474k
    if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2)
2303
72.1k
      type = ETH_P_IP;
2304
401k
    else
2305
401k
      type = ETH_P_IPV6;
2306
2307
474k
    ip_offset = 4 + eth_offset;
2308
474k
    break;
2309
2310
    /* Cisco PPP in HDLC-like framing - 50 */
2311
1.77k
  case DLT_PPP_SERIAL:
2312
1.77k
    chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2313
1.77k
    ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2314
1.77k
    type = ntohs(chdlc->proto_code);
2315
1.77k
    break;
2316
2317
    /* Cisco PPP - 9 or 104 */
2318
3.20k
  case DLT_C_HDLC:
2319
12.6k
  case DLT_PPP:
2320
12.6k
    if(packet[0] == 0x0f || packet[0] == 0x8f) {
2321
6.90k
      chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2322
6.90k
      ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2323
6.90k
      type = ntohs(chdlc->proto_code);
2324
6.90k
    } else {
2325
5.75k
      ip_offset = eth_offset + 2;
2326
5.75k
      ppp_type = ntohs(*((u_int16_t*)&packet[eth_offset]));
2327
5.75k
      if(ppp_type == 0x0021)
2328
1.01k
        type = ETH_P_IP;
2329
4.74k
      else if(ppp_type == 0x0057)
2330
450
        type = ETH_P_IPV6;
2331
4.29k
      else
2332
4.29k
        return(nproto);
2333
5.75k
    }
2334
8.36k
    break;
2335
2336
8.36k
#ifdef DLT_IPV4
2337
124k
  case DLT_IPV4:
2338
124k
    type = ETH_P_IP;
2339
124k
    ip_offset = eth_offset;
2340
124k
    break;
2341
0
#endif
2342
2343
0
#ifdef DLT_IPV6
2344
21.8k
  case DLT_IPV6:
2345
21.8k
    type = ETH_P_IPV6;
2346
21.8k
    ip_offset = eth_offset;
2347
21.8k
    break;
2348
0
#endif
2349
2350
    /* IEEE 802.3 Ethernet - 1 */
2351
10.2M
  case DLT_EN10MB:
2352
10.2M
    ethernet = (struct ndpi_ethhdr *) &packet[eth_offset];
2353
10.2M
    ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset;
2354
10.2M
    check = ntohs(ethernet->h_proto);
2355
2356
10.2M
    if(check <= 1500)
2357
85.3k
      pyld_eth_len = check;
2358
10.1M
    else if(check >= 1536)
2359
10.1M
      type = check;
2360
2361
10.2M
    if(pyld_eth_len != 0) {
2362
81.9k
      llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]);
2363
      /* check for LLC layer with SNAP extension */
2364
81.9k
      if(llc->dsap == SNAP || llc->ssap == SNAP) {
2365
1.36k
  type = llc->snap.proto_ID;
2366
1.36k
  ip_offset += + 8;
2367
1.36k
      }
2368
      /* No SNAP extension - Spanning Tree pkt must be discarted */
2369
80.5k
      else if(llc->dsap == BSTP || llc->ssap == BSTP) {
2370
3.35k
  goto v4_warning;
2371
3.35k
      }
2372
81.9k
    }
2373
10.2M
    break;
2374
2375
    /* Linux Cooked Capture - 113 */
2376
10.2M
  case DLT_LINUX_SLL:
2377
135k
    type = (packet[eth_offset+14] << 8) + packet[eth_offset+15];
2378
135k
    ip_offset = 16 + eth_offset;
2379
135k
    break;
2380
2381
    /* Linux Cooked Capture v2 - 276 */
2382
1.76k
  case LINKTYPE_LINUX_SLL2:
2383
1.76k
    type = (packet[eth_offset+10] << 8) + packet[eth_offset+11];
2384
1.76k
    ip_offset = 20 + eth_offset;
2385
1.76k
    break;
2386
2387
    /* Radiotap link-layer - 127 */
2388
14.2k
  case DLT_IEEE802_11_RADIO:
2389
14.2k
    radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset];
2390
14.2k
    radio_len = radiotap->len;
2391
2392
    /* Check Bad FCS presence */
2393
14.2k
    if((radiotap->flags & BAD_FCS) == BAD_FCS) {
2394
952
      workflow->stats.total_discarded_bytes +=  header->len;
2395
952
      return(nproto);
2396
952
    }
2397
2398
13.3k
    if(header->caplen < (eth_offset + radio_len + sizeof(struct ndpi_wifi_header)))
2399
3.92k
      return(nproto);
2400
2401
    /* Calculate 802.11 header length (variable) */
2402
9.39k
    wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len);
2403
9.39k
    fc = wifi->fc;
2404
2405
    /* check wifi data presence */
2406
9.39k
    if(FCF_TYPE(fc) == WIFI_DATA) {
2407
5.84k
      if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) ||
2408
5.84k
   (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc)))
2409
3.40k
  wifi_len = 26; /* + 4 byte fcs */
2410
5.84k
    } else   /* no data frames */
2411
3.55k
      return(nproto);
2412
2413
    /* Check ether_type from LLC */
2414
5.84k
    if(header->caplen < (eth_offset + wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap)))
2415
2.13k
      return(nproto);
2416
3.71k
    llc = (struct ndpi_llc_header_snap*)(packet + eth_offset + wifi_len + radio_len);
2417
3.71k
    if(llc->dsap == SNAP)
2418
86
      type = ntohs(llc->snap.proto_ID);
2419
2420
    /* Set IP header offset */
2421
3.71k
    ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset;
2422
3.71k
    break;
2423
2424
79.7k
  case DLT_RAW:
2425
79.7k
    ip_offset = eth_offset;
2426
    /* Heuristic: no explicit field with next protocol */
2427
79.7k
    ip_ver = (packet[ip_offset] & 0xF0) >> 4;
2428
79.7k
    if(ip_ver == 4)
2429
67.3k
      type = ETH_P_IP;
2430
12.3k
    else if(ip_ver == 6)
2431
8.67k
      type = ETH_P_IPV6;
2432
3.69k
    else
2433
3.69k
      return(nproto);
2434
2435
76.0k
    break;
2436
2437
76.0k
  case DLT_PPI:
2438
3.43k
    header_length = le16toh(*(u_int16_t *)&packet[eth_offset + 2]);
2439
3.43k
    dlt = le32toh(*(u_int32_t *)&packet[eth_offset + 4]);
2440
3.43k
    if(dlt != DLT_EN10MB) /* Handle only standard ethernet, for the time being */
2441
2.46k
      return(nproto);
2442
963
    datalink_type = DLT_EN10MB;
2443
963
    eth_offset += header_length;
2444
963
    goto datalink_check;
2445
2446
0
  default:
2447
    /*
2448
     * We shoudn't be here, because we already checked that this datalink is supported.
2449
     * Should ndpi_is_datalink_supported() be updated?
2450
     */
2451
0
    printf("Unknown datalink %d\n", datalink_type);
2452
0
    return(nproto);
2453
11.1M
  }
2454
2455
11.1M
 ether_type_check:
2456
11.1M
  recheck_type = 0;
2457
2458
  /* check ether type */
2459
11.1M
  switch(type) {
2460
86.9k
  case ETH_P_VLAN:
2461
86.9k
    if(ip_offset+4 >= (int)header->caplen)
2462
89
      return(nproto);
2463
86.8k
    vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2464
86.8k
    type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2465
86.8k
    ip_offset += 4;
2466
86.8k
    vlan_packet = 1;
2467
2468
    // double tagging for 802.1Q
2469
121k
    while((type == 0x8100) && (((bpf_u_int32)ip_offset+4) < header->caplen)) {
2470
34.9k
      vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2471
34.9k
      type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2472
34.9k
      ip_offset += 4;
2473
34.9k
    }
2474
86.8k
    recheck_type = 1;
2475
86.8k
    break;
2476
2477
963
  case ETH_P_MPLS_UNI:
2478
1.38k
  case ETH_P_MPLS_MULTI:
2479
1.38k
    if(ip_offset+4 >= (int)header->caplen)
2480
172
      return(nproto);
2481
1.21k
    mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2482
1.21k
    mpls.u32 = ntohl(mpls.u32);
2483
1.21k
    workflow->stats.mpls_count++;
2484
1.21k
    type = ETH_P_IP, ip_offset += 4;
2485
2486
7.57k
    while(!mpls.mpls.s && (((bpf_u_int32)ip_offset) + 4 < header->caplen)) {
2487
6.36k
      mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2488
6.36k
      mpls.u32 = ntohl(mpls.u32);
2489
6.36k
      ip_offset += 4;
2490
6.36k
    }
2491
1.21k
    recheck_type = 1;
2492
1.21k
    break;
2493
2494
6.92k
  case ETH_P_PPPoE:
2495
6.92k
    workflow->stats.pppoe_count++;
2496
6.92k
    type = ETH_P_IP;
2497
6.92k
    ip_offset += 8;
2498
6.92k
    recheck_type = 1;
2499
6.92k
    break;
2500
2501
10.0M
  case ETH_P_IP:
2502
10.8M
  case ETH_P_IPV6:
2503
    /* Good let's keep decoding */
2504
10.8M
    break;
2505
2506
198k
  default:
2507
198k
    return(nproto);
2508
11.1M
  }
2509
2510
10.9M
  if(recheck_type)
2511
95.0k
    goto ether_type_check;
2512
2513
10.8M
  workflow->stats.vlan_count += vlan_packet;
2514
2515
10.9M
 iph_check:
2516
  /* Check and set IP header size and total packet length */
2517
10.9M
  if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2518
5.98k
    return(nproto); /* Too short for next IP header*/
2519
2520
10.8M
  iph = (struct ndpi_iphdr *) &packet[ip_offset];
2521
2522
  /* just work on Ethernet packets that contain IP */
2523
10.8M
  if(type == ETH_P_IP && header->caplen >= ip_offset) {
2524
10.0M
    frag_off = ntohs(iph->frag_off);
2525
2526
10.0M
    proto = iph->protocol;
2527
10.0M
    if(header->caplen < header->len) {
2528
229k
      static u_int8_t cap_warning_used = 0;
2529
2530
229k
      if(cap_warning_used == 0) {
2531
9
  if(!workflow->prefs.quiet_mode)
2532
8
    LOG(NDPI_LOG_DEBUG,
2533
9
       "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
2534
9
  cap_warning_used = 1;
2535
9
      }
2536
229k
    }
2537
10.0M
  }
2538
2539
10.8M
  if(iph->version == IPVERSION) {
2540
10.2M
    ip_len = ((u_int16_t)iph->ihl * 4);
2541
10.2M
    iph6 = NULL;
2542
2543
10.2M
    if(iph->protocol == IPPROTO_IPV6
2544
10.2M
       || iph->protocol == NDPI_IPIP_PROTOCOL_TYPE
2545
10.2M
       ) {
2546
7.41k
      ip_offset += ip_len;
2547
7.41k
      if(ip_len > 0)
2548
7.11k
        goto iph_check;
2549
7.41k
    }
2550
2551
10.2M
    if((frag_off & 0x1FFF) != 0) {
2552
84.5k
      static u_int8_t ipv4_frags_warning_used = 0;
2553
84.5k
      workflow->stats.fragmented_count++;
2554
2555
84.5k
      if(ipv4_frags_warning_used == 0) {
2556
9
  if(!workflow->prefs.quiet_mode)
2557
9
    LOG(NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
2558
9
  ipv4_frags_warning_used = 1;
2559
9
      }
2560
2561
84.5k
      workflow->stats.total_discarded_bytes +=  header->len;
2562
84.5k
      return(nproto);
2563
84.5k
    }
2564
10.2M
  } else if(iph->version == 6) {
2565
565k
    if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2566
1.96k
      return(nproto); /* Too short for IPv6 header*/
2567
2568
563k
    iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2569
563k
    proto = iph6->ip6_hdr.ip6_un1_nxt;
2570
563k
    ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
2571
2572
563k
    if(header->caplen < (ip_offset + sizeof(struct ndpi_ipv6hdr) + ntohs(iph6->ip6_hdr.ip6_un1_plen)))
2573
7.17k
      return(nproto); /* Too short for IPv6 payload*/
2574
2575
556k
    const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
2576
556k
    u_int16_t ipsize = header->caplen - ip_offset;
2577
2578
556k
    if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &proto) != 0) {
2579
8.01k
      return(nproto);
2580
8.01k
    }
2581
2582
548k
    if(proto == IPPROTO_IPV6
2583
548k
       || proto == NDPI_IPIP_PROTOCOL_TYPE
2584
548k
       ) {
2585
2.58k
      if(l4ptr > packet) { /* Better safe than sorry */
2586
2.58k
        ip_offset = (l4ptr - packet);
2587
2.58k
        goto iph_check;
2588
2.58k
      }
2589
2.58k
    }
2590
2591
546k
    iph = NULL;
2592
546k
  } else {
2593
33.6k
    static u_int8_t ipv4_warning_used = 0;
2594
2595
43.6k
  v4_warning:
2596
43.6k
    if(ipv4_warning_used == 0) {
2597
9
      if(!workflow->prefs.quiet_mode)
2598
8
        LOG(NDPI_LOG_DEBUG,
2599
9
     "\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n");
2600
9
      ipv4_warning_used = 1;
2601
9
    }
2602
2603
43.6k
    workflow->stats.total_discarded_bytes +=  header->len;
2604
43.6k
    return(nproto);
2605
33.6k
  }
2606
2607
10.7M
  if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) {
2608
2.86M
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr))
2609
916
      return(nproto); /* Too short for UDP header*/
2610
2.86M
    else {
2611
2.86M
      struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2612
2.86M
      u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest);
2613
2614
2.86M
      if(((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) &&
2615
2.86M
         (ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 8 /* Minimum GTPv1 header len */ < header->caplen)) {
2616
  /* Check if it's GTPv1 */
2617
69.5k
  u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2618
69.5k
  u_int8_t flags = packet[offset];
2619
69.5k
  u_int8_t message_type = packet[offset+1];
2620
69.5k
  u_int8_t exts_parsing_error = 0;
2621
2622
69.5k
  if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) &&
2623
69.5k
     (message_type == 0xFF /* T-PDU */)) {
2624
2625
45.5k
    offset += 8; /* GTPv1 header len */
2626
45.5k
    if(flags & 0x07)
2627
24.6k
      offset += 4; /* sequence_number + pdu_number + next_ext_header fields */
2628
    /* Extensions parsing */
2629
45.5k
    if(flags & 0x04) {
2630
5.31k
      unsigned int ext_length = 0;
2631
2632
8.90k
      while(offset < header->caplen) {
2633
7.05k
        ext_length = packet[offset] << 2;
2634
7.05k
        offset += ext_length;
2635
7.05k
        if(offset >= header->caplen || ext_length == 0) {
2636
1.62k
          exts_parsing_error = 1;
2637
1.62k
          break;
2638
1.62k
        }
2639
5.42k
        if(packet[offset - 1] == 0)
2640
1.83k
          break;
2641
5.42k
      }
2642
5.31k
    }
2643
2644
45.5k
    if(offset < header->caplen && !exts_parsing_error) {
2645
      /* Ok, valid GTP-U */
2646
27.1k
      tunnel_type = ndpi_gtp_tunnel;
2647
27.1k
      ip_offset = offset;
2648
27.1k
      iph = (struct ndpi_iphdr *)&packet[ip_offset];
2649
27.1k
      if(iph->version == 6) {
2650
3.20k
        iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2651
3.20k
        iph = NULL;
2652
3.20k
              if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2653
869
          return(nproto);
2654
23.9k
      } else if(iph->version != IPVERSION) {
2655
        // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count);
2656
6.63k
        goto v4_warning;
2657
17.2k
      } else {
2658
17.2k
              if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2659
1.19k
          return(nproto);
2660
17.2k
      }
2661
27.1k
    }
2662
45.5k
  }
2663
2.79M
      } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) {
2664
  /* https://en.wikipedia.org/wiki/TZSP */
2665
4.77k
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 4)
2666
250
    return(nproto); /* Too short for TZSP*/
2667
2668
4.52k
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2669
4.52k
  u_int8_t version       = packet[offset];
2670
4.52k
  u_int8_t ts_type       = packet[offset+1];
2671
4.52k
  u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2]));
2672
2673
4.52k
  tunnel_type = ndpi_tzsp_tunnel;
2674
2675
4.52k
  if((version == 1) && (ts_type == 0) && (encapsulates == 1)) {
2676
904
    u_int8_t stop = 0;
2677
2678
904
    offset += 4;
2679
2680
904
    while((!stop) && (offset < header->caplen)) {
2681
806
      u_int8_t tag_type = packet[offset];
2682
806
      u_int8_t tag_len;
2683
2684
806
      switch(tag_type) {
2685
207
      case 0: /* PADDING Tag */
2686
207
        tag_len = 1;
2687
207
        break;
2688
60
      case 1: /* END Tag */
2689
60
        tag_len = 1, stop = 1;
2690
60
        break;
2691
539
      default:
2692
539
        if(offset + 1 >= header->caplen)
2693
104
          return(nproto); /* Invalid packet */
2694
435
        tag_len = packet[offset+1];
2695
435
        break;
2696
806
      }
2697
2698
702
      offset += tag_len;
2699
2700
702
      if(offset >= header->caplen)
2701
233
        return(nproto); /* Invalid packet */
2702
469
      else {
2703
469
        eth_offset = offset;
2704
469
        goto datalink_check;
2705
469
      }
2706
702
    }
2707
904
  }
2708
2.79M
      } else if((sport == NDPI_CAPWAP_DATA_PORT) || (dport == NDPI_CAPWAP_DATA_PORT)) {
2709
  /* We dissect ONLY CAPWAP traffic */
2710
14.4k
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2711
2712
14.4k
  if((offset+1) < header->caplen) {
2713
13.6k
    uint8_t preamble = packet[offset];
2714
2715
13.6k
    if((preamble & 0x0F) == 0) { /* CAPWAP header */
2716
11.0k
      u_int16_t msg_len = (packet[offset+1] & 0xF8) >> 1;
2717
2718
11.0k
      offset += msg_len;
2719
2720
11.0k
      if((offset + 32 < header->caplen) &&
2721
11.0k
         (packet[offset + 1] == 0x08)) {
2722
        /* IEEE 802.11 Data */
2723
2.39k
        offset += 24;
2724
        /* LLC header is 8 bytes */
2725
2.39k
        type = ntohs((u_int16_t)*((u_int16_t*)&packet[offset+6]));
2726
2727
2.39k
        ip_offset = offset + 8;
2728
2729
2.39k
        tunnel_type = ndpi_capwap_tunnel;
2730
2.39k
        goto iph_check;
2731
2.39k
      }
2732
11.0k
    }
2733
13.6k
  }
2734
2.77M
      }else if(ndpi_is_valid_vxlan(header, packet, ip_offset, ip_len)){
2735
17.3k
        tunnel_type = ndpi_vxlan_tunnel;
2736
17.3k
        eth_offset = ndpi_skip_vxlan(ip_offset, ip_len);
2737
17.3k
        goto datalink_check;
2738
17.3k
      }
2739
2.86M
    }
2740
7.88M
  } else if(workflow->prefs.decode_tunnels && (proto == IPPROTO_GRE)) {
2741
15.0k
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr))
2742
452
      return(nproto); /* Too short for GRE header*/
2743
14.6k
    u_int32_t offset = 0;
2744
14.6k
    if((offset = ndpi_is_valid_gre_tunnel(header, packet, ip_offset, ip_len))) {
2745
9.16k
      tunnel_type = ndpi_gre_tunnel;
2746
9.16k
      struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[ip_offset + ip_len];
2747
9.16k
      if(grehdr->protocol == ntohs(ETH_P_IP) || grehdr->protocol == ntohs(ETH_P_IPV6)) {
2748
880
        ip_offset = offset;
2749
880
        goto iph_check;
2750
8.28k
      } else if(grehdr->protocol ==  NDPI_GRE_PROTO_PPP) {  // ppp protocol
2751
3.96k
        ip_offset = offset + NDPI_PPP_HDRLEN;
2752
3.96k
        goto iph_check;
2753
4.31k
      } else {
2754
4.31k
        eth_offset = offset;
2755
4.31k
        goto datalink_check;
2756
4.31k
      }
2757
9.16k
    } else {
2758
5.44k
      return(nproto);
2759
5.44k
    }
2760
14.6k
  }
2761
2762
  /* process the packet */
2763
10.7M
  return(packet_processing(workflow, time_ms, vlan_id, tunnel_type, iph, iph6,
2764
10.7M
         header->caplen - ip_offset,
2765
10.7M
         header->caplen, header, packet, header->ts,
2766
10.7M
         flow_risk, flow));
2767
10.7M
}
2768
2769
/* *********************************************** */
2770
2771
#ifdef USE_DPDK
2772
2773
#include <rte_version.h>
2774
#include <rte_ether.h>
2775
2776
static const struct rte_eth_conf port_conf_default = {
2777
#if(RTE_VERSION < RTE_VERSION_NUM(19, 8, 0, 0))
2778
                  .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
2779
#else
2780
                  .rxmode = { .max_rx_pkt_len = RTE_ETHER_MAX_LEN }
2781
#endif
2782
};
2783
2784
/* ************************************ */
2785
2786
int dpdk_port_init(int port, struct rte_mempool *mbuf_pool) {
2787
  struct rte_eth_conf port_conf = port_conf_default;
2788
  const u_int16_t rx_rings = 1, tx_rings = 1;
2789
  int retval;
2790
  u_int16_t q;
2791
2792
  /* 1 RX queue */
2793
  retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
2794
2795
  if(retval != 0)
2796
    return retval;
2797
2798
  for(q = 0; q < rx_rings; q++) {
2799
    retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL, mbuf_pool);
2800
    if(retval < 0)
2801
      return retval;
2802
  }
2803
2804
  for(q = 0; q < tx_rings; q++) {
2805
    retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, rte_eth_dev_socket_id(port), NULL);
2806
    if(retval < 0)
2807
      return retval;
2808
  }
2809
2810
  retval = rte_eth_dev_start(port);
2811
2812
  if(retval < 0)
2813
    return retval;
2814
2815
  rte_eth_promiscuous_enable(port);
2816
2817
  return 0;
2818
}
2819
2820
int dpdk_port_deinit(int port) {
2821
  rte_eth_dev_stop(port);
2822
  rte_eth_dev_close(port);
2823
  return 0;
2824
}
2825
2826
#endif