Coverage Report

Created: 2025-11-20 06:48

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