Coverage Report

Created: 2025-11-06 06:29

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
51.0k
#define SNAP                   0XAA
51
49.3k
#define BSTP                   0x42     /* Bridge Spanning Tree Protocol */
52
53
/* Keep last 32 packets */
54
1.09M
#define DATA_ANALUYSIS_SLIDING_WINDOW    32
55
56
/* mask for FCF */
57
1.85k
#define WIFI_DATA                        0x2    /* 0000 0010 */
58
1.85k
#define FCF_TYPE(fc)     (((fc) >> 2) & 0x3)    /* 0000 0011 = 0x3 */
59
#define FCF_SUBTYPE(fc)  (((fc) >> 4) & 0xF)    /* 0000 1111 = 0xF */
60
4.21k
#define FCF_TO_DS(fc)        ((fc) & 0x0100)
61
1.61k
#define FCF_FROM_DS(fc)      ((fc) & 0x0200)
62
63
/* mask for Bad FCF presence */
64
5.02k
#define BAD_FCS                         0x50    /* 0101 0000 */
65
66
513k
#define GTP_U_V1_PORT                  2152
67
474k
#define NDPI_CAPWAP_DATA_PORT          5247
68
476k
#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
0
       u_int32_t packet_id) {
124
0
  struct payload_stats *ret, *ret_found;
125
0
  struct flow_id_stats *f, *f_found;
126
0
  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
0
  HASH_FIND(hh, pstats, payload, payload_len, ret);
136
0
  if(ret == NULL) {
137
0
    if((ret = (struct payload_stats*)ndpi_calloc(1, sizeof(struct payload_stats))) == NULL)
138
0
      return -1; /* OOM */
139
140
0
    if((ret->pattern = (u_int8_t*)ndpi_malloc(payload_len)) == NULL) {
141
0
      ndpi_free(ret);
142
0
      return -1;
143
0
    }
144
145
0
    memcpy(ret->pattern, payload, payload_len);
146
0
    ret->pattern_len = payload_len;
147
0
    ret->num_occurrencies = 1;
148
149
0
    HASH_ADD(hh, pstats, pattern[0], payload_len, ret);
150
151
0
    HASH_FIND(hh, pstats, payload, payload_len, ret_found);
152
0
    if(ret_found == NULL) { /* The insertion failed (because of a memory allocation error) */
153
0
      ndpi_free(ret->pattern);
154
0
      ndpi_free(ret);
155
0
      return -1;
156
0
    }
157
158
#ifdef DEBUG_PAYLOAD
159
    printf("Added element [total: %u]\n", HASH_COUNT(pstats));
160
#endif
161
0
  } else {
162
0
    ret->num_occurrencies++;
163
    // printf("==> %u\n", ret->num_occurrencies);
164
0
  }
165
166
0
  HASH_FIND_INT(ret->flows, &flow->flow_id, f);
167
0
  if(f == NULL) {
168
0
    if((f = (struct flow_id_stats*)ndpi_calloc(1, sizeof(struct flow_id_stats))) == NULL)
169
0
      return -1; /* OOM */
170
171
0
    f->flow_id = flow->flow_id;
172
0
    HASH_ADD_INT(ret->flows, flow_id, f);
173
174
0
    HASH_FIND_INT(ret->flows, &flow->flow_id, f_found);
175
0
    if(f_found == NULL) { /* The insertion failed (because of a memory allocation error) */
176
0
      ndpi_free(f);
177
0
      return -1;
178
0
    }
179
0
  }
180
181
0
  HASH_FIND_INT(ret->packets, &packet_id, p);
182
0
  if(p == NULL) {
183
0
    if((p = (struct packet_id_stats*)ndpi_calloc(1, sizeof(struct packet_id_stats))) == NULL)
184
0
      return -1; /* OOM */
185
0
    p->packet_id = packet_id;
186
187
0
    HASH_ADD_INT(ret->packets, packet_id, p);
188
189
0
    HASH_FIND_INT(ret->packets, &packet_id, p_found);
190
0
    if(p_found == NULL) { /* The insertion failed (because of a memory allocation error) */
191
0
      ndpi_free(p);
192
0
    }
193
0
  }
194
0
  return 0;
195
0
}
196
197
/* *********************************************************** */
198
199
void ndpi_payload_analyzer(struct ndpi_flow_info *flow,
200
         u_int8_t *payload, u_int16_t payload_len,
201
0
         u_int32_t packet_id) {
202
0
  u_int16_t i, j;
203
0
  u_int16_t scan_len = ndpi_min(max_packet_payload_dissection, payload_len);
204
205
0
  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
0
  } else
217
0
    return;
218
219
0
  for(i=0; i<scan_len; i++) {
220
0
    for(j=min_pattern_len; j <= max_pattern_len; j++) {
221
0
      if((i+j) < payload_len) {
222
0
  if(ndpi_analyze_payload(flow, &payload[i], j, packet_id) == -1) {
223
0
          LOG(NDPI_LOG_ERROR, "Error ndpi_analyze_payload (allocation failure)\n");
224
0
  }
225
0
      }
226
0
    }
227
0
  }
228
0
}
229
230
/* ***************************************************** */
231
232
0
static int payload_stats_sort_asc(void *_a, void *_b) {
233
0
  struct payload_stats *a = (struct payload_stats *)_a;
234
0
  struct payload_stats *b = (struct payload_stats *)_b;
235
236
  //return(a->num_occurrencies - b->num_occurrencies);
237
0
  return(b->num_occurrencies - a->num_occurrencies);
238
0
}
239
240
/* ***************************************************** */
241
242
0
static void print_payload_stat(struct payload_stats *p, FILE *out) {
243
0
  u_int i;
244
0
  struct flow_id_stats *s, *tmp;
245
0
  struct packet_id_stats *s1, *tmp1;
246
247
0
  fprintf(out, "\t[");
248
249
0
  for(i=0; i<p->pattern_len; i++) {
250
0
    fprintf(out, "%c", ndpi_isprint(p->pattern[i]) ? p->pattern[i] : '.');
251
0
  }
252
253
0
  fprintf(out, "]");
254
0
  for(; i<16; i++) fprintf(out, " ");
255
0
  fprintf(out, "[");
256
257
0
  for(i=0; i<p->pattern_len; i++) {
258
0
    fprintf(out, "%s%02X", (i > 0) ? " " : "", ndpi_isprint(p->pattern[i]) ? p->pattern[i] : '.');
259
0
  }
260
261
0
  fprintf(out, "]");
262
263
0
  for(; i<16; i++) fprintf(out, "  ");
264
0
  for(i=p->pattern_len; i<max_pattern_len; i++) fprintf(out, " ");
265
266
0
  fprintf(out, "[len: %u][num_occurrencies: %u][flowId: ",
267
0
    p->pattern_len, p->num_occurrencies);
268
269
0
  i = 0;
270
0
  HASH_ITER(hh, p->flows, s, tmp) {
271
0
    fprintf(out, "%s%u", (i > 0) ? " " : "", s->flow_id);
272
0
    i++;
273
0
  }
274
275
0
  fprintf(out, "][packetIds: ");
276
277
  /* ******************************** */
278
279
0
  i = 0;
280
0
  HASH_ITER(hh, p->packets, s1, tmp1) {
281
0
    fprintf(out, "%s%u", (i > 0) ? " " : "", s1->packet_id);
282
0
    i++;
283
0
  }
284
285
0
  fprintf(out, "]\n");
286
287
288
0
}
289
290
/* ***************************************************** */
291
292
0
void ndpi_report_payload_stats(FILE *out) {
293
0
  struct payload_stats *p, *tmp;
294
0
  u_int num = 0;
295
296
0
  if(out)
297
0
    fprintf(out, "\n\nPayload Analysis\n");
298
299
0
  HASH_SORT(pstats, payload_stats_sort_asc);
300
301
0
  HASH_ITER(hh, pstats, p, tmp) {
302
0
    if(out && num <= max_num_reported_top_payloads)
303
0
      print_payload_stat(p, out);
304
305
0
    ndpi_free(p->pattern);
306
307
0
    {
308
0
      struct flow_id_stats *p1, *tmp1;
309
310
0
      HASH_ITER(hh, p->flows, p1, tmp1) {
311
0
  HASH_DEL(p->flows, p1);
312
0
  ndpi_free(p1);
313
0
      }
314
0
    }
315
316
0
    {
317
0
      struct packet_id_stats *p1, *tmp1;
318
319
0
      HASH_ITER(hh, p->packets, p1, tmp1) {
320
0
  HASH_DEL(p->packets, p1);
321
0
  ndpi_free(p1);
322
0
      }
323
0
    }
324
325
0
    HASH_DEL(pstats, p);
326
0
    ndpi_free(p);
327
0
    num++;
328
0
  }
329
0
}
330
331
/* ***************************************************** */
332
333
267k
void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) {
334
267k
  if(flow->ndpi_flow) { ndpi_flow_free(flow->ndpi_flow); flow->ndpi_flow = NULL; }
335
267k
}
336
337
/* ***************************************************** */
338
339
0
void ndpi_stats_free(ndpi_stats_t *s) {
340
0
  if (s->protocol_counter)           ndpi_free(s->protocol_counter);
341
0
  if (s->protocol_counter_bytes)     ndpi_free(s->protocol_counter_bytes);
342
0
  if (s->protocol_flows)             ndpi_free(s->protocol_flows);
343
0
  if (s->fpc_protocol_counter)       ndpi_free(s->fpc_protocol_counter);
344
0
  if (s->fpc_protocol_counter_bytes) ndpi_free(s->fpc_protocol_counter_bytes);
345
0
  if (s->fpc_protocol_flows)         ndpi_free(s->fpc_protocol_flows);
346
347
0
  s->num_protocols = 0;
348
0
}
349
350
0
int ndpi_stats_init(ndpi_stats_t *s, uint32_t num_protocols) {
351
0
  memset(s, 0, sizeof(*s));
352
0
  s->num_protocols = num_protocols;
353
354
0
  s->protocol_counter           = ndpi_calloc(num_protocols, sizeof(u_int64_t));
355
0
  s->protocol_counter_bytes     = ndpi_calloc(num_protocols, sizeof(u_int64_t));
356
0
  s->protocol_flows             = ndpi_calloc(num_protocols, sizeof(u_int32_t));
357
0
  s->fpc_protocol_counter       = ndpi_calloc(num_protocols, sizeof(u_int64_t));
358
0
  s->fpc_protocol_counter_bytes = ndpi_calloc(num_protocols, sizeof(u_int64_t));
359
0
  s->fpc_protocol_flows         = ndpi_calloc(num_protocols, sizeof(u_int32_t));
360
361
0
  if(!s->protocol_counter || !s->protocol_counter_bytes || !s->protocol_flows ||
362
0
     !s->fpc_protocol_counter || !s->fpc_protocol_counter_bytes || !s->fpc_protocol_flows) {
363
364
0
    LOG(NDPI_LOG_ERROR, "[NDPI] %s: error allocating memory for ndpi_stats\n", __FUNCTION__);
365
0
    return 0;
366
0
  }
367
0
  return 1;
368
0
}
369
370
0
void ndpi_stats_reset(ndpi_stats_t *s) {
371
0
  memset(s->flow_count, 0, sizeof(s->flow_count));
372
0
  s->guessed_flow_protocols = 0;
373
0
  s->raw_packet_count = 0;
374
0
  s->ip_packet_count = 0;
375
0
  s->total_wire_bytes = 0;
376
0
  s->total_ip_bytes = 0;
377
0
  s->total_discarded_bytes = 0;
378
0
  s->ndpi_flow_count = 0;
379
0
  s->tcp_count = 0;
380
0
  s->udp_count = 0;
381
0
  s->mpls_count = 0;
382
0
  s->pppoe_count = 0;
383
0
  s->vlan_count = 0;
384
0
  s->fragmented_count = 0;
385
0
  s->max_packet_len = 0;
386
0
  s->num_dissector_calls = 0;
387
388
0
  memset(s->packet_len, 0, sizeof(s->packet_len));
389
0
  memset(s->dpi_packet_count, 0, sizeof(s->dpi_packet_count));
390
0
  memset(s->flow_confidence, 0, sizeof(s->flow_confidence));
391
0
  memset(s->fpc_flow_confidence, 0, sizeof(s->fpc_flow_confidence));
392
0
  memset(s->category_counter, 0, sizeof(s->category_counter));
393
0
  memset(s->category_counter_bytes, 0, sizeof(s->category_counter_bytes));
394
0
  memset(s->category_flows, 0, sizeof(s->category_flows));
395
0
  memset(s->lru_stats, 0, sizeof(s->lru_stats));
396
0
  memset(s->automa_stats, 0, sizeof(s->automa_stats));
397
0
  memset(s->patricia_stats, 0, sizeof(s->patricia_stats));
398
0
  memset(s->hash_stats, 0, sizeof(s->hash_stats));
399
400
0
  if (s->protocol_counter)           memset(s->protocol_counter,           0, sizeof(u_int64_t) * s->num_protocols);
401
0
  if (s->protocol_counter_bytes)     memset(s->protocol_counter_bytes,     0, sizeof(u_int64_t) * s->num_protocols);
402
0
  if (s->protocol_flows)             memset(s->protocol_flows,             0, sizeof(u_int32_t) * s->num_protocols);
403
0
  if (s->fpc_protocol_counter)       memset(s->fpc_protocol_counter,       0, sizeof(u_int64_t) * s->num_protocols);
404
0
  if (s->fpc_protocol_counter_bytes) memset(s->fpc_protocol_counter_bytes, 0, sizeof(u_int64_t) * s->num_protocols);
405
0
  if (s->fpc_protocol_flows)         memset(s->fpc_protocol_flows,         0, sizeof(u_int32_t) * s->num_protocols);
406
0
}
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
1
           struct ndpi_global_context *g_ctx) {
414
1
  struct ndpi_detection_module_struct * module;
415
1
  struct ndpi_workflow * workflow;
416
417
1
  module = ndpi_init_detection_module(g_ctx);
418
419
1
  if(module == NULL) {
420
0
    LOG(NDPI_LOG_ERROR, "global structure initialization failed\n");
421
0
    return NULL;
422
0
  }
423
424
1
  workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow));
425
1
  if(workflow == NULL) {
426
0
    LOG(NDPI_LOG_ERROR, "global structure initialization failed\n");
427
0
    ndpi_exit_detection_module(module);
428
0
    return NULL;
429
0
  }
430
431
1
  workflow->pcap_handle = pcap_handle;
432
1
  workflow->prefs       = *prefs;
433
1
  workflow->ndpi_struct = module;
434
435
1
  ndpi_set_user_data(module, workflow);
436
437
1
  if(do_init_flows_root) {
438
0
    workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *));
439
440
0
    if(!workflow->ndpi_flows_root) {
441
0
      ndpi_exit_detection_module(module);
442
0
      ndpi_free(workflow);
443
0
      return NULL;
444
0
    }
445
0
  }
446
447
1
  workflow->ndpi_serialization_format = serialization_format;
448
449
1
  return workflow;
450
1
}
451
452
/* ***************************************************** */
453
454
219k
void ndpi_flow_info_freer(void *node) {
455
219k
  struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node;
456
457
219k
  ndpi_flow_info_free_data(flow);
458
219k
  ndpi_free(flow);
459
219k
}
460
461
/* ***************************************************** */
462
463
219k
static void ndpi_free_flow_tls_data(struct ndpi_flow_info *flow) {
464
219k
  if(flow->dhcp_fingerprint) {
465
234
    ndpi_free(flow->dhcp_fingerprint);
466
234
    flow->dhcp_fingerprint = NULL;
467
234
  }
468
469
219k
  if(flow->dhcp_class_ident) {
470
143
    ndpi_free(flow->dhcp_class_ident);
471
143
    flow->dhcp_class_ident = NULL;
472
143
  }
473
474
219k
  if(flow->server_hostname) {
475
5.83k
    ndpi_free(flow->server_hostname);
476
5.83k
    flow->server_hostname = NULL;
477
5.83k
  }
478
479
219k
  if(flow->bittorent_hash) {
480
98
    ndpi_free(flow->bittorent_hash);
481
98
    flow->bittorent_hash = NULL;
482
98
  }
483
484
219k
  if(flow->telnet.username) {
485
66
    ndpi_free(flow->telnet.username);
486
66
    flow->telnet.username = NULL;
487
66
  }
488
489
219k
  if(flow->telnet.password) {
490
30
    ndpi_free(flow->telnet.password);
491
30
    flow->telnet.password = NULL;
492
30
  }
493
494
219k
  if(flow->ssh_tls.server_names) {
495
1.28k
    ndpi_free(flow->ssh_tls.server_names);
496
1.28k
    flow->ssh_tls.server_names = NULL;
497
1.28k
  }
498
499
219k
  if(flow->ssh_tls.advertised_alpns) {
500
6.14k
    ndpi_free(flow->ssh_tls.advertised_alpns);
501
6.14k
    flow->ssh_tls.advertised_alpns = NULL;
502
6.14k
  }
503
504
219k
  if(flow->ssh_tls.negotiated_alpn) {
505
864
    ndpi_free(flow->ssh_tls.negotiated_alpn);
506
864
    flow->ssh_tls.negotiated_alpn = NULL;
507
864
  }
508
509
219k
  if(flow->ssh_tls.tls_supported_versions) {
510
5.37k
    ndpi_free(flow->ssh_tls.tls_supported_versions);
511
5.37k
    flow->ssh_tls.tls_supported_versions = NULL;
512
5.37k
  }
513
514
219k
  if(flow->ssh_tls.tls_issuerDN) {
515
1.50k
    ndpi_free(flow->ssh_tls.tls_issuerDN);
516
1.50k
    flow->ssh_tls.tls_issuerDN = NULL;
517
1.50k
  }
518
519
219k
  if(flow->ssh_tls.tls_subjectDN) {
520
1.60k
    ndpi_free(flow->ssh_tls.tls_subjectDN);
521
1.60k
    flow->ssh_tls.tls_subjectDN = NULL;
522
1.60k
  }
523
524
219k
  if(flow->ssh_tls.ja4_client_raw) {
525
8.18k
    ndpi_free(flow->ssh_tls.ja4_client_raw);
526
8.18k
    flow->ssh_tls.ja4_client_raw = NULL;
527
8.18k
  }
528
529
219k
  if(flow->ndpi_fingerprint) {
530
8.40k
    ndpi_free(flow->ndpi_fingerprint);
531
8.40k
    flow->ndpi_fingerprint = NULL;
532
8.40k
  }
533
534
219k
  if(flow->stun.mapped_address.aps) {
535
1.67k
    ndpi_free(flow->stun.mapped_address.aps);
536
1.67k
    flow->stun.mapped_address.aps = NULL;
537
1.67k
  }
538
219k
  if(flow->stun.other_address.aps) {
539
129
    ndpi_free(flow->stun.other_address.aps);
540
129
    flow->stun.other_address.aps = NULL;
541
129
  }
542
219k
  if(flow->stun.peer_address.aps) {
543
563
    ndpi_free(flow->stun.peer_address.aps);
544
563
    flow->stun.peer_address.aps = NULL;
545
563
  }
546
219k
  if(flow->stun.relayed_address.aps) {
547
694
    ndpi_free(flow->stun.relayed_address.aps);
548
694
    flow->stun.relayed_address.aps = NULL;
549
694
  }
550
219k
  if(flow->stun.response_origin.aps) {
551
164
    ndpi_free(flow->stun.response_origin.aps);
552
164
    flow->stun.response_origin.aps = NULL;
553
164
  }
554
219k
}
555
556
/* ***************************************************** */
557
558
219k
static void ndpi_free_flow_data_analysis(struct ndpi_flow_info *flow) {
559
219k
  if(flow->iat_c_to_s) ndpi_free_data_analysis(flow->iat_c_to_s, 1);
560
219k
  if(flow->iat_s_to_c) ndpi_free_data_analysis(flow->iat_s_to_c, 1);
561
562
219k
  if(flow->pktlen_c_to_s) ndpi_free_data_analysis(flow->pktlen_c_to_s, 1);
563
219k
  if(flow->pktlen_s_to_c) ndpi_free_data_analysis(flow->pktlen_s_to_c, 1);
564
565
219k
  if(flow->iat_flow) ndpi_free_data_analysis(flow->iat_flow, 1);
566
567
219k
  if(flow->entropy) ndpi_free(flow->entropy);
568
219k
  if(flow->last_entropy) ndpi_free(flow->last_entropy);
569
219k
}
570
571
/* ***************************************************** */
572
573
219k
void ndpi_flow_info_free_data(struct ndpi_flow_info *flow) {
574
575
219k
  ndpi_free_flow_info_half(flow);
576
219k
  ndpi_term_serializer(&flow->ndpi_flow_serializer);
577
219k
  ndpi_free_flow_data_analysis(flow);
578
219k
  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
219k
  ndpi_free_bin(&flow->payload_len_bin);
585
219k
#endif
586
587
219k
  if(flow->src_name)        ndpi_free(flow->src_name);
588
219k
  if(flow->dst_name)        ndpi_free(flow->dst_name);
589
219k
  if(flow->tcp_fingerprint) ndpi_free(flow->tcp_fingerprint);
590
219k
  if(flow->risk_str)        ndpi_free(flow->risk_str);
591
219k
  if(flow->flow_payload)    ndpi_free(flow->flow_payload);
592
219k
}
593
594
/* ***************************************************** */
595
596
0
void ndpi_workflow_free(struct ndpi_workflow * workflow) {
597
0
  u_int i;
598
599
0
  for(i=0; i<workflow->prefs.num_roots; i++)
600
0
    ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer);
601
602
0
  if(addr_dump_path != NULL)
603
0
    ndpi_cache_address_dump(workflow->ndpi_struct, addr_dump_path, 0);
604
605
0
  ndpi_exit_detection_module(workflow->ndpi_struct);
606
0
  ndpi_free(workflow->ndpi_flows_root);
607
608
0
  ndpi_stats_free(&workflow->stats);
609
610
0
  ndpi_free(workflow);
611
0
}
612
613
1.39M
static inline int cmp_n32(uint32_t a,uint32_t b) {
614
1.39M
  return a == b ? 0 : ntohl(a) < ntohl(b) ? -1:1;
615
1.39M
}
616
1.17M
static inline int cmp_n16(uint16_t a,uint16_t b) {
617
1.17M
  return a == b ? 0 : ntohs(a) < ntohs(b) ? -1:1;
618
1.17M
}
619
620
/* ***************************************************** */
621
622
5.43M
int ndpi_workflow_node_cmp(const void *a, const void *b) {
623
5.43M
  const struct ndpi_flow_info *fa = (const struct ndpi_flow_info*)a;
624
5.43M
  const struct ndpi_flow_info *fb = (const struct ndpi_flow_info*)b;
625
626
5.43M
  if(fa->hashval < fb->hashval) return(-1); else if(fa->hashval > fb->hashval) return(1);
627
628
  /* Flows have the same hash */
629
630
827k
  if(fa->vlan_id   < fb->vlan_id   ) return(-1); else { if(fa->vlan_id    > fb->vlan_id   ) return(1); }
631
825k
  if(fa->protocol  < fb->protocol  ) return(-1); else { if(fa->protocol   > fb->protocol  ) return(1); }
632
633
823k
  int r;
634
823k
  r = cmp_n32(fa->src_ip, fb->src_ip); if(r) return r;
635
607k
  r = cmp_n16(fa->src_port, fb->src_port) ; if(r) return r;
636
568k
  r = cmp_n32(fa->dst_ip, fb->dst_ip); if(r) return r;
637
567k
  r = cmp_n16(fa->dst_port, fb->dst_port);
638
639
567k
  return(r);
640
568k
}
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
786k
                            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
786k
  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
786k
    u_int32_t current_count;
664
665
786k
    if(src_to_dst_direction) {
666
614k
      current_count = flow->entropy->src2dst_l4_bytes - len;
667
614k
    } else {
668
171k
      current_count = flow->entropy->dst2src_l4_bytes - len;
669
171k
    }
670
671
786k
    if(current_count < ETTA_MIN_OCTETS) {
672
740k
      u_int32_t i;
673
740k
      const unsigned char *data = x;
674
675
132M
      for(i=0; i<len; i++) {
676
131M
        if(src_to_dst_direction) {
677
85.3M
          flow->entropy->src2dst_byte_count[data[i]]++;
678
85.3M
        } else {
679
46.5M
          flow->entropy->dst2src_byte_count[data[i]]++;
680
46.5M
        }
681
131M
        current_count++;
682
131M
        if(current_count >= ETTA_MIN_OCTETS) {
683
8.82k
          break;
684
8.82k
        }
685
131M
      }
686
740k
    }
687
786k
  }
688
786k
}
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
786k
                                    unsigned int len, u_int8_t src_to_dst_direction) {
702
786k
  const unsigned char *data = x;
703
704
786k
  if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
705
786k
    unsigned int i;
706
707
163M
    for(i=0; i<len; i++) {
708
162M
      double delta;
709
710
162M
      if(src_to_dst_direction) {
711
100M
        flow->entropy->src2dst_num_bytes += 1;
712
100M
        delta = ((double)data[i] - flow->entropy->src2dst_bd_mean);
713
100M
        flow->entropy->src2dst_bd_mean += delta/((double)flow->entropy->src2dst_num_bytes);
714
100M
        flow->entropy->src2dst_bd_variance += delta*((double)data[i] - flow->entropy->src2dst_bd_mean);
715
100M
      } else {
716
61.8M
        flow->entropy->dst2src_num_bytes += 1;
717
61.8M
        delta = ((double)data[i] - flow->entropy->dst2src_bd_mean);
718
61.8M
        flow->entropy->dst2src_bd_mean += delta/((double)flow->entropy->dst2src_num_bytes);
719
61.8M
        flow->entropy->dst2src_bd_variance += delta*((double)data[i] - flow->entropy->dst2src_bd_mean);
720
61.8M
      }
721
162M
    }
722
786k
  }
723
786k
}
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
793k
                                                 pkt_timeval when) {
744
793k
  u_int32_t idx, hashval;
745
793k
  struct ndpi_flow_info flow;
746
793k
  void *ret;
747
793k
  const u_int8_t *l3, *l4;
748
793k
  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
793k
  if(version == IPVERSION) {
755
723k
    if(ipsize < 20)
756
10
      return NULL;
757
758
723k
    if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len)
759
723k
       /* || (iph->frag_off & htons(0x1FFF)) != 0 */)
760
6.74k
      return NULL;
761
762
716k
    l3 = (const u_int8_t*)iph;
763
716k
  } else {
764
70.5k
    if(l4_offset > ipsize)
765
0
      return NULL;
766
767
70.5k
    l3 = (const u_int8_t*)iph6;
768
70.5k
  }
769
787k
  if(ipsize < l4_offset + l4_packet_len)
770
901
    return NULL;
771
772
786k
  *proto = iph->protocol;
773
774
786k
  if(l4_packet_len < 64)
775
463k
    workflow->stats.packet_len[0]++;
776
322k
  else if(l4_packet_len >= 64 && l4_packet_len < 128)
777
89.7k
    workflow->stats.packet_len[1]++;
778
232k
  else if(l4_packet_len >= 128 && l4_packet_len < 256)
779
87.1k
    workflow->stats.packet_len[2]++;
780
145k
  else if(l4_packet_len >= 256 && l4_packet_len < 1024)
781
80.8k
    workflow->stats.packet_len[3]++;
782
64.8k
  else if(l4_packet_len >= 1024 && l4_packet_len < 1500)
783
60.8k
    workflow->stats.packet_len[4]++;
784
3.96k
  else if(l4_packet_len >= 1500)
785
3.96k
    workflow->stats.packet_len[5]++;
786
787
786k
  if(l4_packet_len > workflow->stats.max_packet_len)
788
238
    workflow->stats.max_packet_len = l4_packet_len;
789
790
786k
  l4 =& ((const u_int8_t *) l3)[l4_offset];
791
792
786k
  if(*proto == IPPROTO_TCP && l4_packet_len >= sizeof(struct ndpi_tcphdr)) {
793
453k
    u_int tcp_len;
794
795
    // TCP
796
453k
    workflow->stats.tcp_count++;
797
453k
    *tcph = (struct ndpi_tcphdr *)l4;
798
453k
    *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest);
799
453k
    tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len);
800
453k
    *payload = (u_int8_t*)&l4[tcp_len];
801
453k
    *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff);
802
453k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_tcphdr);
803
453k
  } else if(*proto == IPPROTO_UDP && l4_packet_len >= sizeof(struct ndpi_udphdr)) {
804
    // UDP
805
299k
    workflow->stats.udp_count++;
806
299k
    *udph = (struct ndpi_udphdr *)l4;
807
299k
    *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest);
808
299k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_udphdr)];
809
299k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_udphdr)) ? l4_packet_len-sizeof(struct ndpi_udphdr) : 0;
810
299k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_udphdr);
811
299k
  } else if(*proto == IPPROTO_ICMP) {
812
8.22k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmphdr )];
813
8.22k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmphdr)) ? l4_packet_len-sizeof(struct ndpi_icmphdr) : 0;
814
8.22k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmphdr);
815
8.22k
    *sport = *dport = 0;
816
25.0k
  } else if(*proto == IPPROTO_ICMPV6) {
817
5.38k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmp6hdr)];
818
5.38k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmp6hdr)) ? l4_packet_len-sizeof(struct ndpi_icmp6hdr) : 0;
819
5.38k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmp6hdr);
820
5.38k
    *sport = *dport = 0;
821
19.6k
  } else {
822
    // non tcp/udp protocols
823
19.6k
    *sport = *dport = 0;
824
19.6k
    l4_data_len = 0;
825
19.6k
  }
826
827
786k
  flow.protocol = iph->protocol, flow.vlan_id = vlan_id;
828
786k
  flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr;
829
786k
  flow.src_port = htons(*sport), flow.dst_port = htons(*dport);
830
786k
  flow.hashval = hashval = flow.protocol + ntohl(flow.src_ip) + ntohl(flow.dst_ip)
831
786k
    + 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
786k
  idx = hashval % workflow->prefs.num_roots;
844
786k
  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
786k
  int is_changed = 0;
848
786k
  if(ret == NULL) {
849
390k
    u_int32_t orig_src_ip = flow.src_ip;
850
390k
    u_int16_t orig_src_port = flow.src_port;
851
390k
    u_int32_t orig_dst_ip = flow.dst_ip;
852
390k
    u_int16_t orig_dst_port = flow.dst_port;
853
854
390k
    flow.src_ip = orig_dst_ip;
855
390k
    flow.src_port = orig_dst_port;
856
390k
    flow.dst_ip = orig_src_ip;
857
390k
    flow.dst_port = orig_src_port;
858
859
390k
    is_changed = 1;
860
861
390k
    ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
862
390k
  }
863
864
786k
  if(ret == NULL) {
865
219k
    if(workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) {
866
0
      LOG(NDPI_LOG_ERROR,
867
0
         "maximum flow count (%u) has been exceeded\n",
868
0
         workflow->prefs.max_ndpi_flows);
869
0
      return NULL;
870
219k
    } else {
871
219k
      struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)ndpi_malloc(sizeof(struct ndpi_flow_info));
872
873
219k
      if(newflow == NULL) {
874
0
  LOG(NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__);
875
0
  return(NULL);
876
0
      } else
877
219k
        workflow->num_allocated_flows++;
878
879
219k
      memset(newflow, 0, sizeof(struct ndpi_flow_info));
880
219k
      newflow->flow_id = flow_id++;
881
219k
      newflow->hashval = hashval;
882
219k
      newflow->tunnel_type = tunnel_type;
883
219k
      newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id;
884
219k
      newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr;
885
219k
      newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport);
886
219k
      newflow->ip_version = version;
887
219k
      newflow->iat_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
888
219k
  newflow->iat_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW);
889
219k
      newflow->pktlen_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
890
219k
  newflow->pktlen_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
891
219k
  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
219k
      ndpi_init_bin(&newflow->payload_len_bin, ndpi_bin_family8, PLEN_NUM_BINS);
898
219k
#endif
899
900
219k
      if (version == 4 || version == 6) {
901
219k
        uint16_t inet_addrlen = (version == 4) ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
902
219k
        newflow->src_name = ndpi_malloc(inet_addrlen);
903
219k
        newflow->dst_name = ndpi_malloc(inet_addrlen);
904
905
219k
        if(version == 4) {
906
200k
          if (newflow->src_name)
907
200k
            inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, inet_addrlen);
908
200k
          if (newflow->dst_name)
909
200k
            inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, inet_addrlen);
910
200k
        } else if (version == 6) {
911
18.4k
          newflow->src_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_src;
912
18.4k
          newflow->dst_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_dst;
913
914
18.4k
          if (newflow->src_name)
915
18.4k
            inet_ntop(AF_INET6, &newflow->src_ip6, newflow->src_name, inet_addrlen);
916
18.4k
          if (newflow->dst_name)
917
18.4k
            inet_ntop(AF_INET6, &newflow->dst_ip6, newflow->dst_name, inet_addrlen);
918
919
          /* For consistency across platforms replace :0: with :: */
920
18.4k
          if (newflow->src_name) ndpi_patchIPv6Address(newflow->src_name);
921
18.4k
          if (newflow->dst_name) ndpi_patchIPv6Address(newflow->dst_name);
922
18.4k
        }
923
219k
      }
924
925
219k
      if((newflow->ndpi_flow = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT)) == NULL) {
926
0
  LOG(NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__);
927
0
  ndpi_flow_info_free_data(newflow);
928
0
  ndpi_free(newflow);
929
0
  return(NULL);
930
0
      } else
931
219k
  memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT);
932
933
219k
    if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown)
934
219k
    {
935
219k
      if (ndpi_init_serializer(&newflow->ndpi_flow_serializer,
936
219k
                               workflow->ndpi_serialization_format) != 0)
937
0
      {
938
0
        LOG(NDPI_LOG_ERROR, "ndpi serializer init failed\n");
939
0
        ndpi_flow_info_free_data(newflow);
940
0
        ndpi_free(newflow);
941
0
        return(NULL);
942
0
      }
943
219k
    }
944
945
219k
      if(ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp) == NULL) { /* Add */
946
0
        ndpi_flow_info_free_data(newflow);
947
0
        ndpi_free(newflow);
948
0
        return(NULL);
949
0
      }
950
219k
      workflow->stats.ndpi_flow_count++;
951
219k
      if(*proto == IPPROTO_TCP)
952
128k
        workflow->stats.flow_count[0]++;
953
90.8k
      else if(*proto == IPPROTO_UDP)
954
83.1k
        workflow->stats.flow_count[1]++;
955
7.67k
      else
956
7.67k
        workflow->stats.flow_count[2]++;
957
958
219k
      if(enable_flow_stats) {
959
219k
        newflow->entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
960
219k
        newflow->last_entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
961
219k
        if(!newflow->entropy || !newflow->last_entropy) {
962
0
          ndpi_tdelete(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
963
0
          ndpi_flow_info_free_data(newflow);
964
0
          ndpi_free(newflow);
965
0
          return(NULL);
966
0
        }
967
219k
        newflow->entropy->src2dst_pkt_len[newflow->entropy->src2dst_pkt_count] = l4_data_len;
968
219k
        newflow->entropy->src2dst_pkt_time[newflow->entropy->src2dst_pkt_count] = when;
969
219k
        if(newflow->entropy->src2dst_pkt_count == 0) {
970
219k
          newflow->entropy->src2dst_start = when;
971
219k
        }
972
219k
        newflow->entropy->src2dst_pkt_count++;
973
        // Non zero app data.
974
219k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
975
211k
          newflow->entropy->src2dst_opackets++;
976
211k
          newflow->entropy->src2dst_l4_bytes += l4_data_len;
977
211k
        }
978
219k
      }
979
219k
      return newflow;
980
219k
    }
981
567k
  } else {
982
567k
    struct ndpi_flow_info *rflow = *(struct ndpi_flow_info**)ret;
983
984
567k
    if(is_changed) {
985
171k
  *src_to_dst_direction = 0, rflow->bidirectional |= 1;
986
171k
    }
987
395k
    else {
988
395k
  *src_to_dst_direction = 1;
989
395k
    }
990
567k
    if(enable_flow_stats) {
991
567k
      if(*src_to_dst_direction) {
992
395k
        if(rflow->entropy->src2dst_pkt_count < max_num_packets_per_flow) {
993
395k
          rflow->entropy->src2dst_pkt_len[rflow->entropy->src2dst_pkt_count] = l4_data_len;
994
395k
          rflow->entropy->src2dst_pkt_time[rflow->entropy->src2dst_pkt_count] = when;
995
395k
          rflow->entropy->src2dst_l4_bytes += l4_data_len;
996
395k
          rflow->entropy->src2dst_pkt_count++;
997
395k
        }
998
        // Non zero app data.
999
395k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1000
354k
          rflow->entropy->src2dst_opackets++;
1001
354k
        }
1002
395k
      } else {
1003
171k
        if(rflow->entropy->dst2src_pkt_count < max_num_packets_per_flow) {
1004
171k
          rflow->entropy->dst2src_pkt_len[rflow->entropy->dst2src_pkt_count] = l4_data_len;
1005
171k
          rflow->entropy->dst2src_pkt_time[rflow->entropy->dst2src_pkt_count] = when;
1006
171k
          if(rflow->entropy->dst2src_pkt_count == 0) {
1007
51.1k
            rflow->entropy->dst2src_start = when;
1008
51.1k
          }
1009
171k
          rflow->entropy->dst2src_l4_bytes += l4_data_len;
1010
171k
          rflow->entropy->dst2src_pkt_count++;
1011
171k
        }
1012
        // Non zero app data.
1013
171k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1014
150k
          rflow->entropy->dst2src_opackets++;
1015
150k
        }
1016
171k
      }
1017
567k
    }
1018
1019
567k
    return(rflow);
1020
567k
  }
1021
786k
}
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
70.5k
                                                  pkt_timeval when) {
1038
70.5k
  struct ndpi_iphdr iph;
1039
1040
70.5k
  if(ipsize < 40)
1041
10
    return(NULL);
1042
70.5k
  memset(&iph, 0, sizeof(iph));
1043
70.5k
  iph.version = IPVERSION;
1044
70.5k
  iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3];
1045
70.5k
  iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3];
1046
70.5k
  u_int8_t l4proto = iph6->ip6_hdr.ip6_un1_nxt;
1047
70.5k
  u_int16_t ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
1048
70.5k
  const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
1049
70.5k
  if(ipsize < sizeof(struct ndpi_ipv6hdr) + ip_len)
1050
12
    return(NULL);
1051
70.5k
  if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &l4proto) != 0) {
1052
26
    return(NULL);
1053
26
  }
1054
70.5k
  iph.protocol = l4proto;
1055
1056
70.5k
  return(get_ndpi_flow_info(workflow, 6, vlan_id, tunnel_type,
1057
70.5k
          &iph, iph6, ipsize,
1058
70.5k
          ip_len, l4ptr - (const u_int8_t *)iph6,
1059
70.5k
          tcph, udph, sport, dport,
1060
70.5k
          proto, payload,
1061
70.5k
          payload_len, src_to_dst_direction, when));
1062
70.5k
}
1063
1064
/* ****************************************************** */
1065
1066
837k
u_int8_t is_ndpi_proto(struct ndpi_flow_info *flow, u_int16_t id) {
1067
837k
  if((flow->detected_protocol.proto.master_protocol == id)
1068
784k
     || (flow->detected_protocol.proto.app_protocol == id))
1069
73.0k
    return(1);
1070
764k
  else
1071
764k
    return(0);
1072
837k
}
1073
1074
/* ****************************************************** */
1075
1076
12.3k
void correct_csv_data_field(char* data) {
1077
  /* Replace , with ; to avoid issues with CSVs */
1078
12.3k
  u_int i;
1079
192k
  for(i=0; data[i] != '\0'; i++) if(data[i] == ',') data[i] = ';';
1080
12.3k
}
1081
1082
/* ****************************************************** */
1083
1084
610k
u_int8_t plen2slot(u_int16_t plen) {
1085
  /*
1086
     Slots [32 bytes lenght]
1087
     0..31, 32..63 ...
1088
  */
1089
1090
610k
  if(plen > PLEN_MAX)
1091
3.66k
    return(PLEN_NUM_BINS-1);
1092
606k
  else
1093
606k
    return(plen/PLEN_BIN_LEN);
1094
610k
}
1095
1096
/* ****************************************************** */
1097
1098
static void dump_flow_fingerprint(struct ndpi_workflow * workflow,
1099
0
          struct ndpi_flow_info *flow) {
1100
0
  ndpi_serializer serializer;
1101
0
  bool rc;
1102
1103
0
  if(ndpi_init_serializer(&serializer, ndpi_serialization_format_json) == -1)
1104
0
    return;
1105
1106
0
  ndpi_serialize_start_of_block(&serializer, "fingerprint");
1107
0
  rc = ndpi_serialize_flow_fingerprint(workflow->ndpi_struct, flow->ndpi_flow, &serializer);
1108
0
  ndpi_serialize_end_of_block(&serializer);
1109
1110
0
  if(rc) {
1111
0
    char buf[64], *buffer;
1112
0
    u_int32_t buffer_len;
1113
1114
0
    ndpi_serialize_string_uint32(&serializer, "proto", flow->protocol);
1115
0
    ndpi_serialize_string_string(&serializer, "cli_ip", flow->src_name ? flow->src_name : "");
1116
0
    ndpi_serialize_string_uint32(&serializer, "cli_port", ntohs(flow->src_port));
1117
0
    ndpi_serialize_string_string(&serializer, "srv_ip", flow->dst_name ? flow->dst_name : "");
1118
0
    ndpi_serialize_string_uint32(&serializer, "srv_port", ntohs(flow->dst_port));
1119
0
    ndpi_serialize_string_string(&serializer, "proto",
1120
0
         ndpi_protocol2name(workflow->ndpi_struct,
1121
0
                flow->detected_protocol.proto,
1122
0
                buf, sizeof(buf)));
1123
1124
0
    if(flow->server_hostname)
1125
0
      ndpi_serialize_string_string(&serializer, "server_hostname", flow->server_hostname);
1126
1127
0
    buffer = ndpi_serializer_get_buffer(&serializer, &buffer_len);
1128
0
    fprintf(fingerprint_fp, "%s\n", buffer);
1129
0
  }
1130
1131
0
  ndpi_term_serializer(&serializer);
1132
0
}
1133
1134
1135
static void add_to_address_port_list(ndpi_address_port_list *list, ndpi_address_port *ap)
1136
228k
{
1137
228k
  int new_num;
1138
228k
  void *new_buf;
1139
228k
  unsigned int i;
1140
1141
228k
  if(ap->port == 0)
1142
216k
    return;
1143
1144
  /* Avoid saving duplicates */
1145
17.5k
  for(i = 0; i < list->num_aps; i++)
1146
13.0k
    if(memcmp(&list->aps[i], ap, sizeof(*ap)) == 0)
1147
7.02k
      return;
1148
1149
4.41k
  if(list->num_aps == list->num_aps_allocated) {
1150
4.00k
    new_num = 1 + list->num_aps_allocated * 2;
1151
4.00k
    new_buf = ndpi_realloc(list->aps, list->num_aps_allocated * sizeof(ndpi_address_port),
1152
4.00k
                     new_num * sizeof(ndpi_address_port));
1153
4.00k
    if(!new_buf)
1154
0
      return;
1155
4.00k
    list->aps = new_buf;
1156
4.00k
    list->num_aps_allocated = new_num;
1157
4.00k
  }
1158
4.41k
  memcpy(&list->aps[list->num_aps++], ap, sizeof(ndpi_address_port));
1159
4.41k
}
1160
1161
/* ****************************************************** */
1162
1163
581k
static void process_ndpi_monitoring_info(struct ndpi_flow_info *flow) {
1164
581k
  if(!flow->ndpi_flow || !flow->ndpi_flow->monit)
1165
534k
    return;
1166
1167
46.4k
  if(flow->monitoring_state == 0 &&
1168
26.1k
     flow->ndpi_flow->state == NDPI_STATE_MONITORING) {
1169
    /* We just moved to monitoring state */
1170
261
    flow->monitoring_state = 1;
1171
261
    flow->num_packets_before_monitoring = flow->ndpi_flow->packet_direction_complete_counter[0] + flow->ndpi_flow->packet_direction_complete_counter[1];
1172
261
  }
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
46.4k
  if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_STUN ||
1181
43.6k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_STUN ||
1182
20.8k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_DTLS ||
1183
20.7k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_DTLS ||
1184
15.6k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_SRTP ||
1185
45.6k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_SRTP) {
1186
1187
45.6k
    add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.mapped_address);
1188
45.6k
    add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.other_address);
1189
45.6k
    add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.peer_address);
1190
45.6k
    add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.relayed_address);
1191
45.6k
    add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.response_origin);
1192
45.6k
    flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1193
1194
45.6k
    flow->stun.rtp_counters[0] = flow->ndpi_flow->stun.rtp_counters[0];
1195
45.6k
    flow->stun.rtp_counters[1] = flow->ndpi_flow->stun.rtp_counters[1];
1196
45.6k
  }
1197
46.4k
}
1198
1199
/* ****************************************************** */
1200
1201
static void serialize_monitoring_metadata(struct ndpi_flow_info *flow)
1202
307
{
1203
307
  unsigned int i;
1204
307
  char buf[64];
1205
1206
307
  if(!flow->ndpi_flow->monit)
1207
46
    return;
1208
1209
261
  ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "monitoring");
1210
1211
261
  switch(flow->detected_protocol.proto.master_protocol ? flow->detected_protocol.proto.master_protocol : flow->detected_protocol.proto.app_protocol) {
1212
88
    case NDPI_PROTOCOL_STUN:
1213
148
    case NDPI_PROTOCOL_DTLS:
1214
255
    case NDPI_PROTOCOL_SRTP:
1215
255
      ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "stun");
1216
1217
255
      if(flow->stun.mapped_address.num_aps > 0) {
1218
214
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "mapped_address");
1219
653
        for(i = 0; i < flow->stun.mapped_address.num_aps; i++) {
1220
439
          if(flow->stun.mapped_address.aps[i].port > 0) {
1221
439
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "mapped_address",
1222
439
                                         print_ndpi_address_port(&flow->stun.mapped_address.aps[i], buf, sizeof(buf)));
1223
439
          }
1224
439
        }
1225
214
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1226
214
      }
1227
1228
255
      if(flow->stun.other_address.num_aps > 0) {
1229
18
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "other_address");
1230
39
        for(i = 0; i < flow->stun.other_address.num_aps; i++) {
1231
21
          if(flow->stun.other_address.aps[i].port > 0) {
1232
21
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "other_address",
1233
21
                                         print_ndpi_address_port(&flow->stun.other_address.aps[i], buf, sizeof(buf)));
1234
21
          }
1235
21
        }
1236
18
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1237
18
      }
1238
1239
255
      if(flow->stun.peer_address.num_aps > 0) {
1240
92
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "peer_address");
1241
405
        for(i = 0; i < flow->stun.peer_address.num_aps; i++) {
1242
313
          if(flow->stun.peer_address.aps[i].port > 0) {
1243
313
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "peer_address",
1244
313
                                         print_ndpi_address_port(&flow->stun.peer_address.aps[i], buf, sizeof(buf)));
1245
313
          }
1246
313
        }
1247
92
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1248
92
      }
1249
1250
255
      if(flow->stun.relayed_address.num_aps > 0) {
1251
123
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "relayed_address");
1252
274
        for(i = 0; i < flow->stun.relayed_address.num_aps; i++) {
1253
151
          if(flow->stun.relayed_address.aps[i].port > 0) {
1254
151
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "relayed_address",
1255
151
                                         print_ndpi_address_port(&flow->stun.relayed_address.aps[i], buf, sizeof(buf)));
1256
151
          }
1257
151
        }
1258
123
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1259
123
      }
1260
1261
255
      if(flow->stun.response_origin.num_aps > 0) {
1262
22
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "response_origin");
1263
50
        for(i = 0; i < flow->stun.response_origin.num_aps; i++) {
1264
28
          if(flow->stun.response_origin.aps[i].port > 0) {
1265
28
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "response_origin",
1266
28
                                         print_ndpi_address_port(&flow->stun.response_origin.aps[i], buf, sizeof(buf)));
1267
28
          }
1268
28
        }
1269
22
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1270
22
      }
1271
1272
255
      ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer); /* stun */
1273
1274
255
      break;
1275
261
  }
1276
1277
261
  ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer);
1278
261
}
1279
1280
/* ****************************************************** */
1281
1282
267k
void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) {
1283
267k
  u_int i;
1284
267k
  char out[128], *s;
1285
1286
267k
  if(!flow->ndpi_flow) return;
1287
1288
219k
  flow->info_type = INFO_INVALID;
1289
1290
219k
  s = ndpi_get_flow_risk_info(flow->ndpi_flow, out, sizeof(out), 0 /* text */);
1291
1292
219k
  if(s != NULL)
1293
185k
    flow->risk_str = ndpi_strdup(s);
1294
1295
219k
  flow->confidence = flow->ndpi_flow->confidence;
1296
1297
219k
  flow->num_dissector_calls = flow->ndpi_flow->num_dissector_calls;
1298
1299
219k
  ndpi_snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s",
1300
219k
    flow->ndpi_flow->host_server_name);
1301
1302
219k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MINING)) {
1303
87
    ndpi_snprintf(flow->mining.currency, sizeof(flow->mining.currency), "%s",
1304
87
      flow->ndpi_flow->protos.mining.currency);
1305
87
  }
1306
1307
219k
  flow->risk = flow->ndpi_flow->risk;
1308
1309
219k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DHCP)) {
1310
624
    if(flow->ndpi_flow->protos.dhcp.fingerprint[0] != '\0')
1311
234
      flow->dhcp_fingerprint = ndpi_strdup(flow->ndpi_flow->protos.dhcp.fingerprint);
1312
1313
624
    if(flow->ndpi_flow->protos.dhcp.class_ident[0] != '\0')
1314
143
      flow->dhcp_class_ident = ndpi_strdup(flow->ndpi_flow->protos.dhcp.class_ident);
1315
218k
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_BITTORRENT) &&
1316
10.8k
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS) &&
1317
10.8k
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TLS)) {
1318
10.7k
    u_int j;
1319
1320
10.7k
    if(flow->ndpi_flow->protos.bittorrent.hash[0] != '\0') {
1321
98
      u_int avail = sizeof(flow->ndpi_flow->protos.bittorrent.hash) * 2 + 1;
1322
98
      flow->bittorent_hash = ndpi_malloc(avail);
1323
1324
98
      if(flow->bittorent_hash) {
1325
2.05k
        for(i=0, j = 0; i < sizeof(flow->ndpi_flow->protos.bittorrent.hash); i++) {
1326
1.96k
          snprintf(&flow->bittorent_hash[j], avail-j, "%02x",
1327
1.96k
            flow->ndpi_flow->protos.bittorrent.hash[i]);
1328
1329
1.96k
          j += 2;
1330
1.96k
        }
1331
1332
98
        flow->bittorent_hash[j] = '\0';
1333
98
      }
1334
98
    }
1335
10.7k
  }
1336
  /* TIVOCONNECT */
1337
207k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TIVOCONNECT)) {
1338
181
    flow->info_type = INFO_TIVOCONNECT;
1339
181
    ndpi_snprintf(flow->tivoconnect.identity_uuid, sizeof(flow->tivoconnect.identity_uuid),
1340
181
                  "%s", flow->ndpi_flow->protos.tivoconnect.identity_uuid);
1341
181
    ndpi_snprintf(flow->tivoconnect.machine, sizeof(flow->tivoconnect.machine),
1342
181
                  "%s", flow->ndpi_flow->protos.tivoconnect.machine);
1343
181
    ndpi_snprintf(flow->tivoconnect.platform, sizeof(flow->tivoconnect.platform),
1344
181
                  "%s", flow->ndpi_flow->protos.tivoconnect.platform);
1345
181
    ndpi_snprintf(flow->tivoconnect.services, sizeof(flow->tivoconnect.services),
1346
181
                  "%s", flow->ndpi_flow->protos.tivoconnect.services);
1347
181
  }
1348
  /* SOFTETHER */
1349
207k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SOFTETHER) &&
1350
254
      !ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_HTTP)) {
1351
230
    flow->info_type = INFO_SOFTETHER;
1352
230
    ndpi_snprintf(flow->softether.ip, sizeof(flow->softether.ip), "%s",
1353
230
                  flow->ndpi_flow->protos.softether.ip);
1354
230
    ndpi_snprintf(flow->softether.port, sizeof(flow->softether.port), "%s",
1355
230
                  flow->ndpi_flow->protos.softether.port);
1356
230
    ndpi_snprintf(flow->softether.hostname, sizeof(flow->softether.hostname), "%s",
1357
230
                  flow->ndpi_flow->protos.softether.hostname);
1358
230
    ndpi_snprintf(flow->softether.fqdn, sizeof(flow->softether.fqdn), "%s",
1359
230
                  flow->ndpi_flow->protos.softether.fqdn);
1360
230
  }
1361
  /* SERVICE_LOCATION */
1362
207k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SERVICE_LOCATION)) {
1363
3.96k
    size_t i;
1364
1365
3.96k
    flow->info_type = INFO_GENERIC;
1366
3.96k
    flow->info[0] = 0;
1367
3.96k
    if (flow->ndpi_flow->protos.slp.url_count > 0)
1368
758
      strncat(flow->info, "URL(s): ", sizeof(flow->info)-1);
1369
1370
4.83k
    for (i = 0; i < flow->ndpi_flow->protos.slp.url_count; ++i) {
1371
868
      size_t length = strlen(flow->info);
1372
1373
868
      strncat(flow->info + length, flow->ndpi_flow->protos.slp.url[i],
1374
868
              sizeof(flow->info) - length);
1375
868
      length = strlen(flow->info);
1376
1377
868
      if (i < (size_t)flow->ndpi_flow->protos.slp.url_count - 1)
1378
110
        strncat(flow->info + length, ", ", sizeof(flow->info) - length);
1379
868
    }
1380
3.96k
  }
1381
  /* NATPMP */
1382
203k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_NATPMP)) {
1383
339
    flow->info_type = INFO_NATPMP;
1384
339
    flow->natpmp.result_code = flow->ndpi_flow->protos.natpmp.result_code;
1385
339
    flow->natpmp.internal_port = flow->ndpi_flow->protos.natpmp.internal_port;
1386
339
    flow->natpmp.external_port = flow->ndpi_flow->protos.natpmp.external_port;
1387
339
    inet_ntop(AF_INET, &flow->ndpi_flow->protos.natpmp.external_address.ipv4, &flow->natpmp.ip[0], sizeof(flow->natpmp.ip));
1388
339
  }
1389
  /* DISCORD */
1390
203k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DISCORD) &&
1391
902
          !ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1392
871
          flow->ndpi_flow->protos.discord.client_ip[0] != '\0') {
1393
80
    flow->info_type = INFO_GENERIC;
1394
80
    ndpi_snprintf(flow->info, sizeof(flow->info), "Client IP: %s",
1395
80
                  flow->ndpi_flow->protos.discord.client_ip);
1396
80
  }
1397
  /* DNS */
1398
203k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS)) {
1399
7.10k
    if(flow->ndpi_flow->protos.dns.is_rsp_addr_ipv6[0] == 0)
1400
6.99k
    {
1401
6.99k
      flow->info_type = INFO_GENERIC;
1402
6.99k
      inet_ntop(AF_INET, &flow->ndpi_flow->protos.dns.rsp_addr[0].ipv4, flow->info, sizeof(flow->info));
1403
6.99k
    } else {
1404
110
      flow->info_type = INFO_GENERIC;
1405
110
      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
110
      ndpi_patchIPv6Address(flow->info);
1409
110
    }
1410
1411
7.10k
    if(flow->ndpi_flow->protos.dns.geolocation_iata_code[0] != '\0')
1412
23
      strcpy(flow->dns.geolocation_iata_code, flow->ndpi_flow->protos.dns.geolocation_iata_code);
1413
1414
7.10k
    if(flow->ndpi_flow->protos.dns.ptr_domain_name[0] != '\0')
1415
327
      strcpy(flow->dns.ptr_domain_name, flow->ndpi_flow->protos.dns.ptr_domain_name);
1416
1417
7.10k
    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
7.10k
  }
1437
  /* MDNS */
1438
195k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MDNS)) {
1439
975
    flow->info_type = INFO_GENERIC;
1440
975
    ndpi_snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->host_server_name);
1441
975
  }
1442
  /* UBNTAC2 */
1443
194k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_UBNTAC2)) {
1444
105
    flow->info_type = INFO_GENERIC;
1445
105
    ndpi_snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.ubntac2.version);
1446
105
  }
1447
  /* FTP, IMAP, SMTP, POP3 */
1448
194k
  else if(!ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1449
174k
          (ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_FTP_CONTROL) ||
1450
173k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_MAIL_IMAP) ||
1451
173k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_POP) ||
1452
173k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_SMTP))) {
1453
2.78k
    flow->info_type = INFO_FTP_IMAP_POP_SMTP;
1454
2.78k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.username,
1455
2.78k
                  sizeof(flow->ftp_imap_pop_smtp.username),
1456
2.78k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.username);
1457
2.78k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.password,
1458
2.78k
                  sizeof(flow->ftp_imap_pop_smtp.password),
1459
2.78k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.password);
1460
2.78k
    flow->ftp_imap_pop_smtp.auth_failed =
1461
2.78k
      flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.auth_failed;
1462
2.78k
  }
1463
  /* TFTP */
1464
192k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TFTP)) {
1465
571
    flow->info_type = INFO_GENERIC;
1466
571
    if(flow->ndpi_flow->protos.tftp.filename[0] != '\0')
1467
29
      ndpi_snprintf(flow->info, sizeof(flow->info), "Filename: %s",
1468
29
                    flow->ndpi_flow->protos.tftp.filename);
1469
571
  }
1470
  /* KERBEROS */
1471
191k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_KERBEROS)) {
1472
1.88k
    flow->info_type = INFO_KERBEROS;
1473
1.88k
    ndpi_snprintf(flow->kerberos.domain,
1474
1.88k
                  sizeof(flow->kerberos.domain),
1475
1.88k
                  "%s", flow->ndpi_flow->protos.kerberos.domain);
1476
1.88k
    ndpi_snprintf(flow->kerberos.hostname,
1477
1.88k
                  sizeof(flow->kerberos.hostname),
1478
1.88k
                  "%s", flow->ndpi_flow->protos.kerberos.hostname);
1479
1.88k
    ndpi_snprintf(flow->kerberos.username,
1480
1.88k
                  sizeof(flow->kerberos.username),
1481
1.88k
                  "%s", flow->ndpi_flow->protos.kerberos.username);
1482
  /* COLLECTD */
1483
189k
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_COLLECTD)) {
1484
40
    flow->info_type = INFO_GENERIC;
1485
40
    if(flow->ndpi_flow->protos.collectd.client_username[0] != '\0')
1486
1
      ndpi_snprintf(flow->info, sizeof(flow->info), "Username: %s",
1487
1
                    flow->ndpi_flow->protos.collectd.client_username);
1488
40
  }
1489
  /* SIP */
1490
189k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SIP)) {
1491
488
    flow->info_type = INFO_SIP;
1492
488
    if(flow->ndpi_flow->protos.sip.from)
1493
280
      ndpi_snprintf(flow->sip.from, sizeof(flow->sip.from), "%s", flow->ndpi_flow->protos.sip.from);
1494
488
    if(flow->ndpi_flow->protos.sip.from_imsi[0] != '\0')
1495
0
      ndpi_snprintf(flow->sip.from_imsi, sizeof(flow->sip.from_imsi), "%s", flow->ndpi_flow->protos.sip.from_imsi);
1496
488
    if(flow->ndpi_flow->protos.sip.to)
1497
280
      ndpi_snprintf(flow->sip.to, sizeof(flow->sip.to), "%s", flow->ndpi_flow->protos.sip.to);
1498
488
    if(flow->ndpi_flow->protos.sip.to_imsi[0] != '\0')
1499
5
      ndpi_snprintf(flow->sip.to_imsi, sizeof(flow->sip.to_imsi), "%s", flow->ndpi_flow->protos.sip.to_imsi);
1500
488
  }
1501
  /* BFCP */
1502
189k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_BFCP)) {
1503
76
    flow->info_type = INFO_BFCP;
1504
76
    flow->bfcp.conference_id = flow->ndpi_flow->protos.bfcp.conference_id;
1505
76
    flow->bfcp.user_id = flow->ndpi_flow->protos.bfcp.user_id;
1506
76
  }
1507
  /* TELNET */
1508
189k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TELNET)) {
1509
598
    if(flow->ndpi_flow->protos.telnet.username[0] != '\0')
1510
66
      flow->telnet.username = ndpi_strdup(flow->ndpi_flow->protos.telnet.username);
1511
598
    if(flow->ndpi_flow->protos.telnet.password[0] != '\0')
1512
30
      flow->telnet.password = ndpi_strdup(flow->ndpi_flow->protos.telnet.password);
1513
188k
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SSH)) {
1514
837
    ndpi_snprintf(flow->host_server_name,
1515
837
       sizeof(flow->host_server_name), "%s",
1516
837
       flow->ndpi_flow->protos.ssh.client_signature);
1517
837
    ndpi_snprintf(flow->ssh_tls.server_info, sizeof(flow->ssh_tls.server_info), "%s",
1518
837
       flow->ndpi_flow->protos.ssh.server_signature);
1519
837
    ndpi_snprintf(flow->ssh_tls.client_hassh, sizeof(flow->ssh_tls.client_hassh), "%s",
1520
837
       flow->ndpi_flow->protos.ssh.hassh_client);
1521
837
    ndpi_snprintf(flow->ssh_tls.server_hassh, sizeof(flow->ssh_tls.server_hassh), "%s",
1522
837
       flow->ndpi_flow->protos.ssh.hassh_server);
1523
837
  }
1524
  /* TLS/QUIC/DTLS/MAIL_S/FTPS */
1525
187k
  else if(ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack)) {
1526
20.4k
    flow->ssh_tls.ssl_version = flow->ndpi_flow->protos.tls_quic.ssl_version;
1527
20.4k
    flow->ssh_tls.quic_version = flow->ndpi_flow->protos.tls_quic.quic_version;
1528
1529
20.4k
    if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_QUIC))
1530
6.96k
      flow->idle_timeout_sec = flow->ndpi_flow->protos.tls_quic.quic_idle_timeout_sec;
1531
1532
20.4k
    if(flow->ndpi_flow->protos.tls_quic.server_names_len > 0 && flow->ndpi_flow->protos.tls_quic.server_names)
1533
1.28k
      flow->ssh_tls.server_names = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.server_names);
1534
1535
20.4k
    flow->ssh_tls.notBefore = flow->ndpi_flow->protos.tls_quic.notBefore;
1536
20.4k
    flow->ssh_tls.notAfter = flow->ndpi_flow->protos.tls_quic.notAfter;
1537
20.4k
    ndpi_snprintf(flow->ssh_tls.ja4_client, sizeof(flow->ssh_tls.ja4_client), "%s",
1538
20.4k
       flow->ndpi_flow->protos.tls_quic.ja4_client);
1539
1540
20.4k
    if(flow->ndpi_flow->ndpi.fingerprint)
1541
8.40k
      flow->ndpi_fingerprint = ndpi_strdup(flow->ndpi_flow->ndpi.fingerprint);
1542
1543
20.4k
    if(flow->ndpi_flow->protos.tls_quic.ja4_client_raw)
1544
8.18k
      flow->ssh_tls.ja4_client_raw = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.ja4_client_raw);
1545
1546
20.4k
    ndpi_snprintf(flow->ssh_tls.ja3_server, sizeof(flow->ssh_tls.ja3_server), "%s",
1547
20.4k
            flow->ndpi_flow->protos.tls_quic.ja3_server);
1548
20.4k
    flow->ssh_tls.server_unsafe_cipher = flow->ndpi_flow->protos.tls_quic.server_unsafe_cipher;
1549
20.4k
    flow->ssh_tls.server_cipher = flow->ndpi_flow->protos.tls_quic.server_cipher;
1550
1551
20.4k
    if(flow->ndpi_flow->protos.tls_quic.fingerprint_set) {
1552
1.83k
      memcpy(flow->ssh_tls.sha1_cert_fingerprint,
1553
1.83k
       flow->ndpi_flow->protos.tls_quic.sha1_certificate_fingerprint, 20);
1554
1.83k
      flow->ssh_tls.sha1_cert_fingerprint_set = 1;
1555
1.83k
    }
1556
1557
20.4k
    flow->ssh_tls.browser_heuristics = flow->ndpi_flow->protos.tls_quic.browser_heuristics;
1558
1559
20.4k
    if(flow->ndpi_flow->protos.tls_quic.issuerDN)
1560
1.50k
      flow->ssh_tls.tls_issuerDN = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.issuerDN);
1561
1562
20.4k
    if(flow->ndpi_flow->protos.tls_quic.subjectDN)
1563
1.60k
      flow->ssh_tls.tls_subjectDN = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.subjectDN);
1564
1565
20.4k
    flow->ssh_tls.encrypted_ch.version = flow->ndpi_flow->protos.tls_quic.encrypted_ch.version;
1566
1567
20.4k
    if(flow->ndpi_flow->protos.tls_quic.tls_supported_versions) {
1568
5.37k
      if((flow->ssh_tls.tls_supported_versions = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.tls_supported_versions)) != NULL)
1569
5.37k
  correct_csv_data_field(flow->ssh_tls.tls_supported_versions);
1570
5.37k
    }
1571
1572
20.4k
    if(flow->ndpi_flow->protos.tls_quic.advertised_alpns) {
1573
6.14k
      if((flow->ssh_tls.advertised_alpns = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.advertised_alpns)) != NULL)
1574
6.14k
  correct_csv_data_field(flow->ssh_tls.advertised_alpns);
1575
6.14k
    }
1576
1577
20.4k
    if(flow->ndpi_flow->protos.tls_quic.negotiated_alpn) {
1578
864
      if((flow->ssh_tls.negotiated_alpn = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.negotiated_alpn)) != NULL)
1579
864
  correct_csv_data_field(flow->ssh_tls.negotiated_alpn);
1580
864
    }
1581
1582
20.4k
    if(flow->protocol == IPPROTO_TCP) {
1583
12.5k
      if(enable_doh_dot_detection) {
1584
  /* For TLS we use TLS block lenght instead of payload lenght */
1585
0
  ndpi_reset_bin(&flow->payload_len_bin);
1586
  
1587
0
  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
0
      }
1594
      
1595
12.5k
      flow->ssh_tls.num_blocks = flow->ndpi_flow->l4.tcp.tls.num_tls_blocks;
1596
12.5k
      memcpy(flow->ssh_tls.blocks, flow->ndpi_flow->l4.tcp.tls.tls_blocks, sizeof(flow->ndpi_flow->l4.tcp.tls.tls_blocks));
1597
12.5k
    }
1598
20.4k
  }
1599
  /* FASTCGI */
1600
167k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_FASTCGI)) {
1601
189
    flow->info_type = INFO_FASTCGI;
1602
189
    flow->fast_cgi.method = flow->ndpi_flow->protos.fast_cgi.method;
1603
189
    ndpi_snprintf(flow->fast_cgi.user_agent, sizeof(flow->fast_cgi.user_agent), "%s", flow->ndpi_flow->protos.fast_cgi.user_agent);
1604
189
    ndpi_snprintf(flow->fast_cgi.url, sizeof(flow->fast_cgi.url), "%s", flow->ndpi_flow->protos.fast_cgi.url);
1605
189
  }
1606
1607
219k
  if(!monitoring_enabled) {
1608
0
    add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->stun.mapped_address);
1609
0
    add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->stun.peer_address);
1610
0
    add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->stun.relayed_address);
1611
0
    add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->stun.response_origin);
1612
0
    add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->stun.other_address);
1613
0
  }
1614
1615
219k
  flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1616
1617
219k
  if(flow->ndpi_flow->tcp.fingerprint) {
1618
54.1k
    char buf[128];
1619
1620
54.1k
    snprintf(buf, sizeof(buf), "%s/%s", flow->ndpi_flow->tcp.fingerprint,
1621
54.1k
       ndpi_print_os_hint(flow->ndpi_flow->tcp.os_hint));
1622
54.1k
    flow->tcp_fingerprint = ndpi_strdup(buf);
1623
54.1k
  }
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
219k
  if(ndpi_stack_is_http_like(&flow->detected_protocol.protocol_stack)) { /* HTTP, HTTP_PROXY, HTTP_CONNECT */
1628
37.3k
    if(flow->ndpi_flow->http.url != NULL) {
1629
23.9k
      ndpi_snprintf(flow->http.url, sizeof(flow->http.url), "%s", flow->ndpi_flow->http.url);
1630
23.9k
    }
1631
1632
37.3k
    flow->http.response_status_code = flow->ndpi_flow->http.response_status_code;
1633
37.3k
    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
37.3k
    ndpi_snprintf(flow->http.server, sizeof(flow->http.server), "%s", flow->ndpi_flow->http.server ? flow->ndpi_flow->http.server : "");
1635
37.3k
    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
37.3k
    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
37.3k
    ndpi_snprintf(flow->http.filename, sizeof(flow->http.filename), "%s", flow->ndpi_flow->http.filename ? flow->ndpi_flow->http.filename : "");
1638
37.3k
    ndpi_snprintf(flow->http.username, sizeof(flow->http.username), "%s", flow->ndpi_flow->http.username ? flow->ndpi_flow->http.username : "");
1639
37.3k
    ndpi_snprintf(flow->http.password, sizeof(flow->http.password), "%s", flow->ndpi_flow->http.password ? flow->ndpi_flow->http.password : "");
1640
37.3k
  }
1641
1642
219k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_RTP))
1643
423
    memcpy(&flow->rtp, &flow->ndpi_flow->rtp, sizeof(flow->rtp));
1644
1645
219k
  ndpi_snprintf(flow->http.user_agent,
1646
219k
                sizeof(flow->http.user_agent),
1647
219k
                "%s", (flow->ndpi_flow->http.user_agent ? flow->ndpi_flow->http.user_agent : ""));
1648
1649
219k
  {
1650
219k
    ndpi_ip_addr_t ip_addr;
1651
219k
    struct ndpi_address_cache_item *c;
1652
1653
219k
    memset(&ip_addr, 0, sizeof(ip_addr));
1654
1655
219k
    if(flow->ip_version == 4)
1656
200k
      ip_addr.ipv4 = flow->dst_ip;
1657
18.4k
    else
1658
18.4k
      memcpy(&ip_addr.ipv6, &flow->dst_ip6, sizeof(struct ndpi_in6_addr));
1659
1660
219k
    c = ndpi_cache_address_find(workflow->ndpi_struct, ip_addr);
1661
1662
219k
    if(c) {
1663
5.83k
      flow->server_hostname = ndpi_strdup(c->hostname);
1664
5.83k
    }
1665
219k
  }
1666
1667
219k
  if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown) {
1668
219k
    if (ndpi_flow2json(workflow->ndpi_struct, flow->ndpi_flow,
1669
219k
                       flow->ip_version, flow->protocol,
1670
219k
           flow->vlan_id,
1671
219k
                       flow->src_ip, flow->dst_ip,
1672
219k
                       &flow->src_ip6, &flow->dst_ip6,
1673
219k
                       flow->src_port, flow->dst_port,
1674
219k
                       flow->detected_protocol,
1675
219k
                       &flow->ndpi_flow_serializer) != 0) {
1676
0
      LOG(NDPI_LOG_ERROR, "flow2json failed\n");
1677
0
      return;
1678
0
    }
1679
1680
219k
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed);
1681
219k
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "check_extra_packets", flow->check_extra_packets);
1682
1683
219k
    if(flow->ndpi_flow->state == NDPI_STATE_MONITORING) {
1684
307
      serialize_monitoring_metadata(flow);
1685
307
    }
1686
1687
219k
    if(flow->server_hostname)
1688
5.83k
      ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "server_hostname", flow->server_hostname);
1689
219k
  }
1690
1691
219k
  if(flow->detection_completed && (!flow->check_extra_packets)) {
1692
47.9k
    flow->flow_payload = flow->ndpi_flow->flow_payload, flow->flow_payload_len = flow->ndpi_flow->flow_payload_len;
1693
47.9k
    flow->ndpi_flow->flow_payload = NULL; /* We'll free the memory */
1694
1695
47.9k
    if(workflow->flow_callback != NULL)
1696
47.9k
      workflow->flow_callback(workflow, flow, workflow->flow_callback_userdata);
1697
1698
47.9k
    if(fingerprint_fp)
1699
0
      dump_flow_fingerprint(workflow, flow);
1700
1701
47.9k
    ndpi_free_flow_info_half(flow);
1702
47.9k
  }
1703
219k
}
1704
1705
/* ****************************************************** */
1706
1707
/**
1708
 * @brief Clear entropy stats if it meets prereq.
1709
 */
1710
static void
1711
786k
ndpi_clear_entropy_stats(struct ndpi_flow_info *flow) {
1712
786k
  if(enable_flow_stats) {
1713
786k
    if(flow->entropy->src2dst_pkt_count + flow->entropy->dst2src_pkt_count == max_num_packets_per_flow) {
1714
35.7k
      memcpy(flow->last_entropy, flow->entropy,  sizeof(struct ndpi_entropy));
1715
35.7k
      memset(flow->entropy, 0x00, sizeof(struct ndpi_entropy));
1716
35.7k
    }
1717
786k
  }
1718
786k
}
1719
1720
453k
void update_tcp_flags_count(struct ndpi_flow_info* flow, struct ndpi_tcphdr* tcp, u_int8_t src_to_dst_direction){
1721
453k
  if(tcp->cwr){
1722
19.9k
    flow->cwr_count++;
1723
19.9k
    src_to_dst_direction ? flow->src2dst_cwr_count++ : flow->dst2src_cwr_count++;
1724
19.9k
  }
1725
453k
  if(tcp->ece){
1726
39.7k
    flow->ece_count++;
1727
39.7k
    src_to_dst_direction ? flow->src2dst_ece_count++ : flow->dst2src_ece_count++;
1728
39.7k
  }
1729
453k
  if(tcp->rst){
1730
53.1k
    flow->rst_count++;
1731
53.1k
    src_to_dst_direction ? flow->src2dst_rst_count++ : flow->dst2src_rst_count++;
1732
53.1k
  }
1733
453k
  if(tcp->ack){
1734
339k
    flow->ack_count++;
1735
339k
    src_to_dst_direction ? flow->src2dst_ack_count++ : flow->dst2src_ack_count++;
1736
339k
  }
1737
453k
  if(tcp->fin){
1738
51.4k
    flow->fin_count++;
1739
51.4k
    src_to_dst_direction ? flow->src2dst_fin_count++ : flow->dst2src_fin_count++;
1740
51.4k
  }
1741
453k
  if(tcp->syn){
1742
128k
    flow->syn_count++;
1743
128k
    src_to_dst_direction ? flow->src2dst_syn_count++ : flow->dst2src_syn_count++;
1744
128k
  }
1745
453k
  if(tcp->psh){
1746
189k
    flow->psh_count++;
1747
189k
    src_to_dst_direction ? flow->src2dst_psh_count++ : flow->dst2src_psh_count++;
1748
189k
  }
1749
453k
  if(tcp->urg){
1750
49.7k
    flow->urg_count++;
1751
49.7k
    src_to_dst_direction ? flow->src2dst_urg_count++ : flow->dst2src_urg_count++;
1752
49.7k
  }
1753
453k
}
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
793k
             struct ndpi_flow_info **flow_ext) {
1776
793k
  struct ndpi_flow_info *flow = NULL;
1777
793k
  struct ndpi_flow_struct *ndpi_flow = NULL;
1778
793k
  u_int8_t proto;
1779
793k
  struct ndpi_tcphdr *tcph = NULL;
1780
793k
  struct ndpi_udphdr *udph = NULL;
1781
793k
  u_int16_t sport, dport, payload_len = 0;
1782
793k
  u_int8_t *payload;
1783
793k
  u_int8_t src_to_dst_direction = 1;
1784
793k
  u_int8_t begin_or_end_tcp = 0;
1785
793k
  struct ndpi_proto nproto;
1786
1787
793k
  memset(&nproto, '\0', sizeof(nproto));
1788
1789
793k
  if(workflow->prefs.ignore_vlanid)
1790
0
    vlan_id = 0;
1791
1792
793k
  if(iph)
1793
723k
    flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id,
1794
723k
            tunnel_type, iph, NULL,
1795
723k
            ipsize,
1796
723k
            ntohs(iph->tot_len) ? (ntohs(iph->tot_len) - (iph->ihl * 4)) : ipsize - (iph->ihl * 4) /* TSO */,
1797
723k
            iph->ihl * 4,
1798
723k
            &tcph, &udph, &sport, &dport,
1799
723k
            &proto,
1800
723k
            &payload, &payload_len, &src_to_dst_direction, when);
1801
70.5k
  else
1802
70.5k
    flow = get_ndpi_flow_info6(workflow, vlan_id,
1803
70.5k
             tunnel_type, iph6, ipsize,
1804
70.5k
             &tcph, &udph, &sport, &dport,
1805
70.5k
             &proto,
1806
70.5k
             &payload, &payload_len, &src_to_dst_direction, when);
1807
1808
793k
  if(flow != NULL) {
1809
786k
    pkt_timeval tdiff;
1810
1811
786k
    workflow->stats.ip_packet_count++;
1812
786k
    workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */,
1813
786k
      workflow->stats.total_ip_bytes += rawsize;
1814
786k
    ndpi_flow = flow->ndpi_flow;
1815
1816
786k
    if(tcph != NULL){
1817
453k
      update_tcp_flags_count(flow, tcph, src_to_dst_direction);
1818
453k
      if(tcph->syn && !flow->src2dst_bytes){
1819
63.8k
  flow->c_to_s_init_win = rawsize;
1820
389k
      }else if(tcph->syn && tcph->ack && flow->src2dst_bytes == flow->c_to_s_init_win){
1821
12.6k
  flow->s_to_c_init_win = rawsize;
1822
12.6k
      }
1823
453k
    }
1824
1825
786k
    if((tcph != NULL) && (tcph->fin || tcph->rst || tcph->syn))
1826
170k
      begin_or_end_tcp = 1;
1827
1828
786k
    if(flow->flow_last_pkt_time.tv_sec) {
1829
521k
      ndpi_timer_sub(&when, &flow->flow_last_pkt_time, &tdiff);
1830
1831
521k
      if(flow->iat_flow
1832
521k
   && (tdiff.tv_sec >= 0) /* Discard backward time */
1833
521k
   ) {
1834
505k
  u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1835
1836
505k
  if(ms > 0)
1837
212k
    ndpi_data_add_value(flow->iat_flow, ms);
1838
505k
      }
1839
521k
    }
1840
1841
786k
    memcpy(&flow->flow_last_pkt_time, &when, sizeof(when));
1842
1843
786k
    if(src_to_dst_direction) {
1844
614k
      if(flow->src2dst_last_pkt_time.tv_sec) {
1845
351k
  ndpi_timer_sub(&when, &flow->src2dst_last_pkt_time, &tdiff);
1846
1847
351k
  if(flow->iat_c_to_s
1848
351k
     && (tdiff.tv_sec >= 0) /* Discard backward time */
1849
351k
     ) {
1850
338k
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1851
1852
338k
    ndpi_data_add_value(flow->iat_c_to_s, ms);
1853
338k
  }
1854
351k
      }
1855
1856
614k
      ndpi_data_add_value(flow->pktlen_c_to_s, rawsize);
1857
614k
      flow->src2dst_packets++, flow->src2dst_bytes += rawsize, flow->src2dst_goodput_bytes += payload_len;
1858
614k
      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
614k
    } else {
1865
171k
      if(flow->dst2src_last_pkt_time.tv_sec && (!begin_or_end_tcp)) {
1866
112k
  ndpi_timer_sub(&when, &flow->dst2src_last_pkt_time, &tdiff);
1867
1868
112k
  if(flow->iat_s_to_c) {
1869
112k
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1870
1871
112k
    ndpi_data_add_value(flow->iat_s_to_c, ms);
1872
112k
  }
1873
112k
      }
1874
171k
      ndpi_data_add_value(flow->pktlen_s_to_c, rawsize);
1875
171k
      flow->dst2src_packets++, flow->dst2src_bytes += rawsize, flow->dst2src_goodput_bytes += payload_len;
1876
171k
      flow->risk &= ~(1ULL << NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */
1877
171k
      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
171k
    }
1884
1885
786k
#ifndef DIRECTION_BINS
1886
786k
    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
610k
  ndpi_inc_bin(&flow->payload_len_bin, plen2slot(payload_len), 1);
1892
610k
    }
1893
786k
#endif
1894
1895
786k
    if(enable_payload_analyzer && (payload_len > 0))
1896
0
      ndpi_payload_analyzer(flow,
1897
0
          payload, payload_len,
1898
0
          workflow->stats.ip_packet_count);
1899
1900
786k
    if(enable_flow_stats) {
1901
      /* Update BD, distribution and mean. */
1902
786k
      ndpi_flow_update_byte_count(flow, payload, payload_len, src_to_dst_direction);
1903
786k
      ndpi_flow_update_byte_dist_mean_var(flow, payload, payload_len, src_to_dst_direction);
1904
      /* Update SPLT scores for first 32 packets. */
1905
786k
      if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
1906
786k
        if(flow->bidirectional)
1907
335k
          flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1908
335k
                flow->entropy->dst2src_pkt_len, flow->entropy->dst2src_pkt_time,
1909
335k
                flow->entropy->src2dst_start, flow->entropy->dst2src_start,
1910
335k
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1911
335k
                flow->src2dst_packets, flow->dst2src_packets,
1912
335k
                flow->entropy->src2dst_opackets, flow->entropy->dst2src_opackets,
1913
335k
                flow->entropy->src2dst_l4_bytes, flow->entropy->dst2src_l4_bytes, 1,
1914
335k
                flow->entropy->src2dst_byte_count, flow->entropy->dst2src_byte_count);
1915
451k
  else
1916
451k
    flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1917
451k
                NULL, NULL, flow->entropy->src2dst_start, flow->entropy->src2dst_start,
1918
451k
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1919
451k
                flow->src2dst_packets, 0,
1920
451k
                flow->entropy->src2dst_opackets, 0,
1921
451k
                flow->entropy->src2dst_l4_bytes, 0, 1,
1922
451k
                flow->entropy->src2dst_byte_count, NULL);
1923
786k
      }
1924
786k
    }
1925
1926
786k
    if(flow->first_seen_ms == 0)
1927
219k
      flow->first_seen_ms = time_ms;
1928
1929
786k
    flow->last_seen_ms = time_ms;
1930
1931
    /* Copy packets entropy if num packets count == 10 */
1932
786k
    ndpi_clear_entropy_stats(flow);
1933
    /* Reset IAT reeference times (see https://github.com/ntop/nDPI/pull/1316) */
1934
786k
    if(((flow->src2dst_packets + flow->dst2src_packets) % max_num_packets_per_flow) == 0) {
1935
35.7k
      memset(&flow->src2dst_last_pkt_time, '\0', sizeof(flow->src2dst_last_pkt_time));
1936
35.7k
      memset(&flow->dst2src_last_pkt_time, '\0', sizeof(flow->dst2src_last_pkt_time));
1937
35.7k
      memset(&flow->flow_last_pkt_time, '\0', sizeof(flow->flow_last_pkt_time));
1938
35.7k
    }
1939
1940
786k
    if((human_readeable_string_len != 0) && (!flow->has_human_readeable_strings)) {
1941
544k
      u_int8_t skip = 0;
1942
1943
544k
      if(proto == IPPROTO_TCP &&
1944
314k
   (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1945
250k
    is_ndpi_proto(flow, NDPI_PROTOCOL_SSH))) {
1946
66.6k
  if((flow->src2dst_packets+flow->dst2src_packets) < 10 /* MIN_NUM_ENCRYPT_SKIP_PACKETS */)
1947
17.4k
    skip = 1; /* Skip initial negotiation packets */
1948
66.6k
      }
1949
1950
544k
      if((!skip) && ((flow->src2dst_packets+flow->dst2src_packets) < 100)) {
1951
502k
  if(ndpi_has_human_readable_string((char*)packet, header->caplen,
1952
502k
             human_readeable_string_len,
1953
502k
             flow->human_readeable_string_buffer,
1954
502k
             sizeof(flow->human_readeable_string_buffer)) == 1)
1955
106k
    flow->has_human_readeable_strings = 1;
1956
502k
      }
1957
544k
    } else {
1958
241k
      if(proto == IPPROTO_TCP &&
1959
139k
         (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1960
133k
          is_ndpi_proto(flow, NDPI_PROTOCOL_SSH)))
1961
6.38k
  flow->has_human_readeable_strings = 0;
1962
241k
    }
1963
786k
  } else { // flow is NULL
1964
7.70k
    workflow->stats.total_discarded_bytes += header->len;
1965
7.70k
    return(nproto);
1966
7.70k
  }
1967
1968
786k
  if(!flow->detection_completed) {
1969
581k
    struct ndpi_flow_input_info input_info;
1970
1971
581k
    u_int enough_packets =
1972
581k
      ((proto == IPPROTO_UDP && (max_num_udp_dissected_pkts > 0 && flow->src2dst_packets + flow->dst2src_packets >= max_num_udp_dissected_pkts)) ||
1973
581k
       (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
581k
    if(proto == IPPROTO_TCP)
1980
353k
      workflow->stats.dpi_packet_count[0]++;
1981
227k
    else if(proto == IPPROTO_UDP)
1982
217k
      workflow->stats.dpi_packet_count[1]++;
1983
10.6k
    else
1984
10.6k
      workflow->stats.dpi_packet_count[2]++;
1985
581k
    flow->dpi_packets++;
1986
1987
581k
    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
581k
    input_info.in_pkt_dir = NDPI_IN_PKT_DIR_UNKNOWN;
1990
581k
    input_info.seen_flow_beginning = NDPI_FLOW_BEGINNING_UNKNOWN;
1991
581k
    malloc_size_stats = 1;
1992
581k
    flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow,
1993
581k
                  iph ? (uint8_t *)iph : (uint8_t *)iph6,
1994
581k
                  ipsize, time_ms, &input_info);
1995
581k
    if(monitoring_enabled)
1996
581k
      process_ndpi_monitoring_info(flow);
1997
581k
    if(flow->detected_protocol.state == NDPI_STATE_CLASSIFIED ||
1998
533k
       enough_packets) {
1999
2000
47.9k
      flow->detection_completed = 1;
2001
2002
47.9k
      if(flow->detected_protocol.state != NDPI_STATE_CLASSIFIED) {
2003
0
         flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow);
2004
0
      }
2005
2006
47.9k
      if(flow->ndpi_flow->protocol_was_guessed) workflow->stats.guessed_flow_protocols++;
2007
47.9k
      process_ndpi_collected_info(workflow, flow);
2008
47.9k
    }
2009
2010
    /* Let's try to save client-server direction */
2011
581k
    flow->current_pkt_from_client_to_server = input_info.in_pkt_dir;
2012
2013
581k
    malloc_size_stats = 0;
2014
581k
  } else {
2015
205k
    flow->current_pkt_from_client_to_server = NDPI_IN_PKT_DIR_UNKNOWN; /* Unknown */
2016
205k
  }
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
786k
  *flow_risk = flow->risk;
2030
786k
  *flow_ext = flow;
2031
2032
786k
  return(flow->detected_protocol);
2033
793k
}
2034
2035
/* ****************************************************** */
2036
2037
22.6k
int ndpi_is_datalink_supported(int datalink_type) {
2038
  /* Keep in sync with the similar switch in ndpi_workflow_process_packet */
2039
22.6k
  switch(datalink_type) {
2040
7.53k
  case DLT_NULL:
2041
7.55k
  case DLT_PPP_SERIAL:
2042
7.58k
  case DLT_C_HDLC:
2043
7.71k
  case DLT_PPP:
2044
7.71k
#ifdef DLT_IPV4
2045
9.16k
  case DLT_IPV4:
2046
9.16k
#endif
2047
9.16k
#ifdef DLT_IPV6
2048
9.87k
  case DLT_IPV6:
2049
9.87k
#endif
2050
21.1k
  case DLT_EN10MB:
2051
21.8k
  case DLT_LINUX_SLL:
2052
21.9k
  case DLT_IEEE802_11_RADIO:
2053
22.5k
  case DLT_RAW:
2054
22.5k
  case DLT_PPI:
2055
22.6k
  case LINKTYPE_LINUX_SLL2:
2056
22.6k
    return 1;
2057
36
  default:
2058
36
    return 0;
2059
22.6k
  }
2060
22.6k
}
2061
2062
236k
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
236k
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr)) {
2064
6.33k
    return false;
2065
6.33k
  }
2066
230k
  u_int32_t vxlan_dst_port  = ntohs(4789);
2067
230k
  struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2068
230k
  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
230k
  if((udp->dest == vxlan_dst_port || udp->source == vxlan_dst_port) &&
2094
7.67k
    (packet[offset] == 0x8) &&
2095
5.81k
    (packet[offset + 1] == 0x0) &&
2096
5.59k
    (packet[offset + 2] == 0x0) &&
2097
5.51k
    (packet[offset + 3] == 0x0) &&
2098
5.38k
    (packet[offset + 7] ==  0x0)) {
2099
5.24k
    return true;
2100
5.24k
    }
2101
224k
  return false;
2102
230k
}
2103
2104
5.24k
static inline u_int ndpi_skip_vxlan(u_int16_t ip_offset, u_int16_t ip_len){
2105
5.24k
  return ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr);
2106
5.24k
}
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
3.80k
                const u_int16_t ip_len) {
2111
3.80k
  uint32_t offset = ip_offset + ip_len;
2112
3.80k
  struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[offset];
2113
3.80k
  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
3.80k
  if(NDPI_GRE_IS_FLAGS(grehdr->flags))
2121
274
    return 0;
2122
3.53k
  if(NDPI_GRE_IS_REC(grehdr->flags))
2123
248
    return 0;
2124
  /*GRE rfc 2890 that update 1701*/
2125
3.28k
  if(NDPI_GRE_IS_VERSION_0(grehdr->flags)) {
2126
1.24k
    if(NDPI_GRE_IS_CSUM(grehdr->flags)) {
2127
279
      if(header->caplen < offset + 4)
2128
18
        return 0;
2129
      /*checksum field and offset field*/
2130
261
      offset += 4;
2131
261
    }
2132
1.23k
    if(NDPI_GRE_IS_KEY(grehdr->flags)) {
2133
279
      if(header->caplen < offset + 4)
2134
18
        return 0;
2135
261
      offset += 4;
2136
261
    }
2137
1.21k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2138
305
      if(header->caplen < offset + 4)
2139
18
        return 0;
2140
287
      offset += 4;
2141
287
    }
2142
2.03k
  } else if(NDPI_GRE_IS_VERSION_1(grehdr->flags)) { /*rfc-2637 section 4.1 enhanced gre*/
2143
1.98k
    if(NDPI_GRE_IS_CSUM(grehdr->flags))
2144
13
      return 0;
2145
1.96k
    if(NDPI_GRE_IS_ROUTING(grehdr->flags))
2146
50
      return 0;
2147
1.91k
    if(!NDPI_GRE_IS_KEY(grehdr->flags))
2148
362
      return 0;
2149
1.55k
    if(NDPI_GRE_IS_STRICT(grehdr->flags))
2150
34
      return 0;
2151
1.52k
    if(grehdr->protocol != NDPI_GRE_PROTO_PPP)
2152
92
      return 0;
2153
    /*key field*/
2154
1.43k
    if(header->caplen < offset + 4)
2155
34
      return 0;
2156
1.39k
    offset += 4;
2157
1.39k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2158
39
      if(header->caplen < offset + 4)
2159
18
        return 0;
2160
21
      offset += 4;
2161
21
    }
2162
1.37k
    if(NDPI_GRE_IS_ACK(grehdr->flags)) {
2163
26
      if(header->caplen < offset + 4)
2164
12
        return 0;
2165
14
      offset += 4;
2166
14
    }
2167
1.37k
  } else { /*support only ver 0, 1*/
2168
54
    return 0;
2169
54
  }
2170
2.56k
  return offset;
2171
3.28k
}
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
954k
                 struct ndpi_flow_info **flow) {
2180
  /*
2181
   * Declare pointers to packet headers
2182
   */
2183
  /* --- Ethernet header --- */
2184
954k
  const struct ndpi_ethhdr *ethernet;
2185
  /* --- LLC header --- */
2186
954k
  const struct ndpi_llc_header_snap *llc;
2187
2188
  /* --- Cisco HDLC header --- */
2189
954k
  const struct ndpi_chdlc *chdlc;
2190
2191
  /* --- Radio Tap header --- */
2192
954k
  const struct ndpi_radiotap_header *radiotap;
2193
  /* --- Wifi header --- */
2194
954k
  const struct ndpi_wifi_header *wifi;
2195
2196
  /* --- MPLS header --- */
2197
954k
  union mpls {
2198
954k
    uint32_t u32;
2199
954k
    struct ndpi_mpls_header mpls;
2200
954k
  } mpls;
2201
2202
  /** --- IP header --- **/
2203
954k
  struct ndpi_iphdr *iph;
2204
  /** --- IPv6 header --- **/
2205
954k
  struct ndpi_ipv6hdr *iph6;
2206
2207
954k
  struct ndpi_proto nproto;
2208
954k
  ndpi_packet_tunnel tunnel_type = ndpi_no_tunnel;
2209
2210
  /* lengths and offsets */
2211
954k
  u_int32_t eth_offset = 0, dlt;
2212
954k
  u_int16_t radio_len, header_length;
2213
954k
  u_int16_t fc;
2214
954k
  u_int16_t type = 0;
2215
954k
  int wifi_len = 0;
2216
954k
  int pyld_eth_len = 0;
2217
954k
  int check;
2218
954k
  u_int64_t time_ms;
2219
954k
  u_int16_t ip_offset = 0, ip_len;
2220
954k
  u_int16_t frag_off = 0, vlan_id = 0;
2221
954k
  u_int8_t proto = 0, recheck_type;
2222
954k
  u_int8_t ip_ver, ppp_type;
2223
  /*u_int32_t label;*/
2224
2225
  /* counters */
2226
954k
  u_int8_t vlan_packet = 0;
2227
2228
954k
  *flow_risk = 0 /* NDPI_NO_RISK */;
2229
954k
  *flow = NULL;
2230
2231
954k
  memset(&nproto, '\0', sizeof(nproto));
2232
2233
954k
  if((addr_dump_path != NULL) && (workflow->stats.raw_packet_count == 0)) {
2234
    /* At the first packet flush expired cached addresses */
2235
0
    ndpi_cache_address_flush_expired(workflow->ndpi_struct, header->ts.tv_sec);
2236
0
  }
2237
2238
  /* Increment raw packet counter */
2239
954k
  workflow->stats.raw_packet_count++;
2240
2241
  /* setting time */
2242
954k
  time_ms = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION);
2243
2244
  /* safety check */
2245
954k
  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
954k
    time_ms = workflow->last_time;
2248
954k
  }
2249
  /* update last time value */
2250
954k
  workflow->last_time = time_ms;
2251
2252
  /*** check Data Link type ***/
2253
954k
  int datalink_type;
2254
2255
#ifdef USE_DPDK
2256
  datalink_type = DLT_EN10MB;
2257
#else
2258
954k
  datalink_type = (int)pcap_datalink(workflow->pcap_handle);
2259
954k
#endif
2260
2261
960k
 datalink_check:
2262
  // 20 for min iph and 8 for min UDP
2263
960k
  if(header->caplen < eth_offset + 28)
2264
90.0k
    return(nproto); /* Too short */
2265
2266
  /* Keep in sync with ndpi_is_datalink_supported() */
2267
870k
  switch(datalink_type) {
2268
156k
  case DLT_NULL:
2269
156k
    if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2)
2270
30.9k
      type = ETH_P_IP;
2271
125k
    else
2272
125k
      type = ETH_P_IPV6;
2273
2274
156k
    ip_offset = 4 + eth_offset;
2275
156k
    break;
2276
2277
    /* Cisco PPP in HDLC-like framing - 50 */
2278
199
  case DLT_PPP_SERIAL:
2279
199
    chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2280
199
    ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2281
199
    type = ntohs(chdlc->proto_code);
2282
199
    break;
2283
2284
    /* Cisco PPP - 9 or 104 */
2285
232
  case DLT_C_HDLC:
2286
1.17k
  case DLT_PPP:
2287
1.17k
    if(packet[0] == 0x0f || packet[0] == 0x8f) {
2288
439
      chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2289
439
      ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2290
439
      type = ntohs(chdlc->proto_code);
2291
739
    } else {
2292
739
      ip_offset = eth_offset + 2;
2293
739
      ppp_type = ntohs(*((u_int16_t*)&packet[eth_offset]));
2294
739
      if(ppp_type == 0x0021)
2295
275
        type = ETH_P_IP;
2296
464
      else if(ppp_type == 0x0057)
2297
194
        type = ETH_P_IPV6;
2298
270
      else
2299
270
        return(nproto);
2300
739
    }
2301
908
    break;
2302
2303
908
#ifdef DLT_IPV4
2304
49.1k
  case DLT_IPV4:
2305
49.1k
    type = ETH_P_IP;
2306
49.1k
    ip_offset = eth_offset;
2307
49.1k
    break;
2308
0
#endif
2309
2310
0
#ifdef DLT_IPV6
2311
10.6k
  case DLT_IPV6:
2312
10.6k
    type = ETH_P_IPV6;
2313
10.6k
    ip_offset = eth_offset;
2314
10.6k
    break;
2315
0
#endif
2316
2317
    /* IEEE 802.3 Ethernet - 1 */
2318
629k
  case DLT_EN10MB:
2319
629k
    ethernet = (struct ndpi_ethhdr *) &packet[eth_offset];
2320
629k
    ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset;
2321
629k
    check = ntohs(ethernet->h_proto);
2322
2323
629k
    if(check <= 1500)
2324
17.4k
      pyld_eth_len = check;
2325
611k
    else if(check >= 1536)
2326
611k
      type = check;
2327
2328
629k
    if(pyld_eth_len != 0) {
2329
16.8k
      llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]);
2330
      /* check for LLC layer with SNAP extension */
2331
16.8k
      if(llc->dsap == SNAP || llc->ssap == SNAP) {
2332
244
  type = llc->snap.proto_ID;
2333
244
  ip_offset += + 8;
2334
244
      }
2335
      /* No SNAP extension - Spanning Tree pkt must be discarted */
2336
16.6k
      else if(llc->dsap == BSTP || llc->ssap == BSTP) {
2337
686
  goto v4_warning;
2338
686
      }
2339
16.8k
    }
2340
628k
    break;
2341
2342
    /* Linux Cooked Capture - 113 */
2343
628k
  case DLT_LINUX_SLL:
2344
10.8k
    type = (packet[eth_offset+14] << 8) + packet[eth_offset+15];
2345
10.8k
    ip_offset = 16 + eth_offset;
2346
10.8k
    break;
2347
2348
    /* Linux Cooked Capture v2 - 276 */
2349
194
  case LINKTYPE_LINUX_SLL2:
2350
194
    type = (packet[eth_offset+10] << 8) + packet[eth_offset+11];
2351
194
    ip_offset = 20 + eth_offset;
2352
194
    break;
2353
2354
    /* Radiotap link-layer - 127 */
2355
2.51k
  case DLT_IEEE802_11_RADIO:
2356
2.51k
    radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset];
2357
2.51k
    radio_len = radiotap->len;
2358
2359
    /* Check Bad FCS presence */
2360
2.51k
    if((radiotap->flags & BAD_FCS) == BAD_FCS) {
2361
208
      workflow->stats.total_discarded_bytes +=  header->len;
2362
208
      return(nproto);
2363
208
    }
2364
2365
2.30k
    if(header->caplen < (eth_offset + radio_len + sizeof(struct ndpi_wifi_header)))
2366
446
      return(nproto);
2367
2368
    /* Calculate 802.11 header length (variable) */
2369
1.85k
    wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len);
2370
1.85k
    fc = wifi->fc;
2371
2372
    /* check wifi data presence */
2373
1.85k
    if(FCF_TYPE(fc) == WIFI_DATA) {
2374
1.61k
      if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) ||
2375
997
   (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc)))
2376
1.02k
  wifi_len = 26; /* + 4 byte fcs */
2377
1.61k
    } else   /* no data frames */
2378
246
      return(nproto);
2379
2380
    /* Check ether_type from LLC */
2381
1.61k
    if(header->caplen < (eth_offset + wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap)))
2382
1.01k
      return(nproto);
2383
600
    llc = (struct ndpi_llc_header_snap*)(packet + eth_offset + wifi_len + radio_len);
2384
600
    if(llc->dsap == SNAP)
2385
19
      type = ntohs(llc->snap.proto_ID);
2386
2387
    /* Set IP header offset */
2388
600
    ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset;
2389
600
    break;
2390
2391
9.72k
  case DLT_RAW:
2392
9.72k
    ip_offset = eth_offset;
2393
    /* Heuristic: no explicit field with next protocol */
2394
9.72k
    ip_ver = (packet[ip_offset] & 0xF0) >> 4;
2395
9.72k
    if(ip_ver == 4)
2396
7.09k
      type = ETH_P_IP;
2397
2.62k
    else if(ip_ver == 6)
2398
2.20k
      type = ETH_P_IPV6;
2399
424
    else
2400
424
      return(nproto);
2401
2402
9.29k
    break;
2403
2404
9.29k
  case DLT_PPI:
2405
277
    header_length = le16toh(*(u_int16_t *)&packet[eth_offset + 2]);
2406
277
    dlt = le32toh(*(u_int32_t *)&packet[eth_offset + 4]);
2407
277
    if(dlt != DLT_EN10MB) /* Handle only standard ethernet, for the time being */
2408
206
      return(nproto);
2409
71
    datalink_type = DLT_EN10MB;
2410
71
    eth_offset += header_length;
2411
71
    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
870k
  }
2421
2422
874k
 ether_type_check:
2423
874k
  recheck_type = 0;
2424
2425
  /* check ether type */
2426
874k
  switch(type) {
2427
6.70k
  case ETH_P_VLAN:
2428
6.70k
    if(ip_offset+4 >= (int)header->caplen)
2429
20
      return(nproto);
2430
6.68k
    vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2431
6.68k
    type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2432
6.68k
    ip_offset += 4;
2433
6.68k
    vlan_packet = 1;
2434
2435
    // double tagging for 802.1Q
2436
8.57k
    while((type == 0x8100) && (((bpf_u_int32)ip_offset+4) < header->caplen)) {
2437
1.88k
      vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2438
1.88k
      type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2439
1.88k
      ip_offset += 4;
2440
1.88k
    }
2441
6.68k
    recheck_type = 1;
2442
6.68k
    break;
2443
2444
96
  case ETH_P_MPLS_UNI:
2445
279
  case ETH_P_MPLS_MULTI:
2446
279
    if(ip_offset+4 >= (int)header->caplen)
2447
35
      return(nproto);
2448
244
    mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2449
244
    mpls.u32 = ntohl(mpls.u32);
2450
244
    workflow->stats.mpls_count++;
2451
244
    type = ETH_P_IP, ip_offset += 4;
2452
2453
1.73k
    while(!mpls.mpls.s && (((bpf_u_int32)ip_offset) + 4 < header->caplen)) {
2454
1.48k
      mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2455
1.48k
      mpls.u32 = ntohl(mpls.u32);
2456
1.48k
      ip_offset += 4;
2457
1.48k
    }
2458
244
    recheck_type = 1;
2459
244
    break;
2460
2461
955
  case ETH_P_PPPoE:
2462
955
    workflow->stats.pppoe_count++;
2463
955
    type = ETH_P_IP;
2464
955
    ip_offset += 8;
2465
955
    recheck_type = 1;
2466
955
    break;
2467
2468
667k
  case ETH_P_IP:
2469
835k
  case ETH_P_IPV6:
2470
    /* Good let's keep decoding */
2471
835k
    break;
2472
2473
31.6k
  default:
2474
31.6k
    return(nproto);
2475
874k
  }
2476
2477
843k
  if(recheck_type)
2478
7.88k
    goto ether_type_check;
2479
2480
835k
  workflow->stats.vlan_count += vlan_packet;
2481
2482
838k
 iph_check:
2483
  /* Check and set IP header size and total packet length */
2484
838k
  if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2485
2.19k
    return(nproto); /* Too short for next IP header*/
2486
2487
836k
  iph = (struct ndpi_iphdr *) &packet[ip_offset];
2488
2489
  /* just work on Ethernet packets that contain IP */
2490
836k
  if(type == ETH_P_IP && header->caplen >= ip_offset) {
2491
669k
    frag_off = ntohs(iph->frag_off);
2492
2493
669k
    proto = iph->protocol;
2494
669k
    if(header->caplen < header->len) {
2495
92.1k
      static u_int8_t cap_warning_used = 0;
2496
2497
92.1k
      if(cap_warning_used == 0) {
2498
1
  if(!workflow->prefs.quiet_mode)
2499
1
    LOG(NDPI_LOG_DEBUG,
2500
1
       "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
2501
1
  cap_warning_used = 1;
2502
1
      }
2503
92.1k
    }
2504
669k
  }
2505
2506
836k
  if(iph->version == IPVERSION) {
2507
750k
    ip_len = ((u_int16_t)iph->ihl * 4);
2508
750k
    iph6 = NULL;
2509
2510
750k
    if(iph->protocol == IPPROTO_IPV6
2511
749k
       || iph->protocol == NDPI_IPIP_PROTOCOL_TYPE
2512
750k
       ) {
2513
945
      ip_offset += ip_len;
2514
945
      if(ip_len > 0)
2515
907
        goto iph_check;
2516
945
    }
2517
2518
749k
    if((frag_off & 0x1FFF) != 0) {
2519
14.4k
      static u_int8_t ipv4_frags_warning_used = 0;
2520
14.4k
      workflow->stats.fragmented_count++;
2521
2522
14.4k
      if(ipv4_frags_warning_used == 0) {
2523
1
  if(!workflow->prefs.quiet_mode)
2524
1
    LOG(NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
2525
1
  ipv4_frags_warning_used = 1;
2526
1
      }
2527
2528
14.4k
      workflow->stats.total_discarded_bytes +=  header->len;
2529
14.4k
      return(nproto);
2530
14.4k
    }
2531
749k
  } else if(iph->version == 6) {
2532
75.1k
    if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2533
529
      return(nproto); /* Too short for IPv6 header*/
2534
2535
74.6k
    iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2536
74.6k
    proto = iph6->ip6_hdr.ip6_un1_nxt;
2537
74.6k
    ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
2538
2539
74.6k
    if(header->caplen < (ip_offset + sizeof(struct ndpi_ipv6hdr) + ntohs(iph6->ip6_hdr.ip6_un1_plen)))
2540
1.43k
      return(nproto); /* Too short for IPv6 payload*/
2541
2542
73.2k
    const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
2543
73.2k
    u_int16_t ipsize = header->caplen - ip_offset;
2544
2545
73.2k
    if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &proto) != 0) {
2546
1.59k
      return(nproto);
2547
1.59k
    }
2548
2549
71.6k
    if(proto == IPPROTO_IPV6
2550
71.4k
       || proto == NDPI_IPIP_PROTOCOL_TYPE
2551
71.6k
       ) {
2552
771
      if(l4ptr > packet) { /* Better safe than sorry */
2553
771
        ip_offset = (l4ptr - packet);
2554
771
        goto iph_check;
2555
771
      }
2556
771
    }
2557
2558
70.8k
    iph = NULL;
2559
70.8k
  } else {
2560
11.0k
    static u_int8_t ipv4_warning_used = 0;
2561
2562
13.5k
  v4_warning:
2563
13.5k
    if(ipv4_warning_used == 0) {
2564
1
      if(!workflow->prefs.quiet_mode)
2565
1
        LOG(NDPI_LOG_DEBUG,
2566
1
     "\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
1
      ipv4_warning_used = 1;
2568
1
    }
2569
2570
13.5k
    workflow->stats.total_discarded_bytes +=  header->len;
2571
13.5k
    return(nproto);
2572
11.0k
  }
2573
2574
805k
  if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) {
2575
257k
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr))
2576
216
      return(nproto); /* Too short for UDP header*/
2577
257k
    else {
2578
257k
      struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2579
257k
      u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest);
2580
2581
257k
      if(((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) &&
2582
19.0k
         (ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 8 /* Minimum GTPv1 header len */ < header->caplen)) {
2583
  /* Check if it's GTPv1 */
2584
18.8k
  u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2585
18.8k
  u_int8_t flags = packet[offset];
2586
18.8k
  u_int8_t message_type = packet[offset+1];
2587
18.8k
  u_int8_t exts_parsing_error = 0;
2588
2589
18.8k
  if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) &&
2590
10.6k
     (message_type == 0xFF /* T-PDU */)) {
2591
2592
10.3k
    offset += 8; /* GTPv1 header len */
2593
10.3k
    if(flags & 0x07)
2594
8.48k
      offset += 4; /* sequence_number + pdu_number + next_ext_header fields */
2595
    /* Extensions parsing */
2596
10.3k
    if(flags & 0x04) {
2597
1.20k
      unsigned int ext_length = 0;
2598
2599
2.04k
      while(offset < header->caplen) {
2600
1.30k
        ext_length = packet[offset] << 2;
2601
1.30k
        offset += ext_length;
2602
1.30k
        if(offset >= header->caplen || ext_length == 0) {
2603
207
          exts_parsing_error = 1;
2604
207
          break;
2605
207
        }
2606
1.09k
        if(packet[offset - 1] == 0)
2607
252
          break;
2608
1.09k
      }
2609
1.20k
    }
2610
2611
10.3k
    if(offset < header->caplen && !exts_parsing_error) {
2612
      /* Ok, valid GTP-U */
2613
2.81k
      tunnel_type = ndpi_gtp_tunnel;
2614
2.81k
      ip_offset = offset;
2615
2.81k
      iph = (struct ndpi_iphdr *)&packet[ip_offset];
2616
2.81k
      if(iph->version == 6) {
2617
90
        iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2618
90
        iph = NULL;
2619
90
              if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2620
45
          return(nproto);
2621
2.72k
      } else if(iph->version != IPVERSION) {
2622
        // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count);
2623
1.89k
        goto v4_warning;
2624
1.89k
      } else {
2625
831
              if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2626
178
          return(nproto);
2627
831
      }
2628
2.81k
    }
2629
10.3k
  }
2630
238k
      } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) {
2631
  /* https://en.wikipedia.org/wiki/TZSP */
2632
734
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 4)
2633
41
    return(nproto); /* Too short for TZSP*/
2634
2635
693
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2636
693
  u_int8_t version       = packet[offset];
2637
693
  u_int8_t ts_type       = packet[offset+1];
2638
693
  u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2]));
2639
2640
693
  tunnel_type = ndpi_tzsp_tunnel;
2641
2642
693
  if((version == 1) && (ts_type == 0) && (encapsulates == 1)) {
2643
179
    u_int8_t stop = 0;
2644
2645
179
    offset += 4;
2646
2647
179
    while((!stop) && (offset < header->caplen)) {
2648
155
      u_int8_t tag_type = packet[offset];
2649
155
      u_int8_t tag_len;
2650
2651
155
      switch(tag_type) {
2652
60
      case 0: /* PADDING Tag */
2653
60
        tag_len = 1;
2654
60
        break;
2655
1
      case 1: /* END Tag */
2656
1
        tag_len = 1, stop = 1;
2657
1
        break;
2658
94
      default:
2659
94
        if(offset + 1 >= header->caplen)
2660
18
          return(nproto); /* Invalid packet */
2661
76
        tag_len = packet[offset+1];
2662
76
        break;
2663
155
      }
2664
2665
137
      offset += tag_len;
2666
2667
137
      if(offset >= header->caplen)
2668
18
        return(nproto); /* Invalid packet */
2669
119
      else {
2670
119
        eth_offset = offset;
2671
119
        goto datalink_check;
2672
119
      }
2673
137
    }
2674
179
  }
2675
237k
      } else if((sport == NDPI_CAPWAP_DATA_PORT) || (dport == NDPI_CAPWAP_DATA_PORT)) {
2676
  /* We dissect ONLY CAPWAP traffic */
2677
1.28k
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2678
2679
1.28k
  if((offset+1) < header->caplen) {
2680
1.19k
    uint8_t preamble = packet[offset];
2681
2682
1.19k
    if((preamble & 0x0F) == 0) { /* CAPWAP header */
2683
844
      u_int16_t msg_len = (packet[offset+1] & 0xF8) >> 1;
2684
2685
844
      offset += msg_len;
2686
2687
844
      if((offset + 32 < header->caplen) &&
2688
599
         (packet[offset + 1] == 0x08)) {
2689
        /* IEEE 802.11 Data */
2690
114
        offset += 24;
2691
        /* LLC header is 8 bytes */
2692
114
        type = ntohs((u_int16_t)*((u_int16_t*)&packet[offset+6]));
2693
2694
114
        ip_offset = offset + 8;
2695
2696
114
        tunnel_type = ndpi_capwap_tunnel;
2697
114
        goto iph_check;
2698
114
      }
2699
844
    }
2700
1.19k
  }
2701
236k
      }else if(ndpi_is_valid_vxlan(header, packet, ip_offset, ip_len)){
2702
5.24k
        tunnel_type = ndpi_vxlan_tunnel;
2703
5.24k
        eth_offset = ndpi_skip_vxlan(ip_offset, ip_len);
2704
5.24k
        goto datalink_check;
2705
5.24k
      }
2706
257k
    }
2707
548k
  } else if(workflow->prefs.decode_tunnels && (proto == IPPROTO_GRE)) {
2708
3.91k
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr))
2709
113
      return(nproto); /* Too short for GRE header*/
2710
3.80k
    u_int32_t offset = 0;
2711
3.80k
    if((offset = ndpi_is_valid_gre_tunnel(header, packet, ip_offset, ip_len))) {
2712
2.56k
      tunnel_type = ndpi_gre_tunnel;
2713
2.56k
      struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[ip_offset + ip_len];
2714
2.56k
      if(grehdr->protocol == ntohs(ETH_P_IP) || grehdr->protocol == ntohs(ETH_P_IPV6)) {
2715
329
        ip_offset = offset;
2716
329
        goto iph_check;
2717
2.23k
      } else if(grehdr->protocol ==  NDPI_GRE_PROTO_PPP) {  // ppp protocol
2718
1.36k
        ip_offset = offset + NDPI_PPP_HDRLEN;
2719
1.36k
        goto iph_check;
2720
1.36k
      } else {
2721
865
        eth_offset = offset;
2722
865
        goto datalink_check;
2723
865
      }
2724
2.56k
    } else {
2725
1.24k
      return(nproto);
2726
1.24k
    }
2727
3.80k
  }
2728
2729
  /* process the packet */
2730
793k
  return(packet_processing(workflow, time_ms, vlan_id, tunnel_type, iph, iph6,
2731
793k
         header->caplen - ip_offset,
2732
793k
         header->caplen, header, packet, header->ts,
2733
793k
         flow_risk, flow));
2734
805k
}
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