Coverage Report

Created: 2025-11-02 06:33

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.12M
#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
524k
#define GTP_U_V1_PORT                  2152
67
486k
#define NDPI_CAPWAP_DATA_PORT          5247
68
488k
#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
274k
void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) {
334
274k
  if(flow->ndpi_flow) { ndpi_flow_free(flow->ndpi_flow); flow->ndpi_flow = NULL; }
335
274k
}
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
225k
void ndpi_flow_info_freer(void *node) {
455
225k
  struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node;
456
457
225k
  ndpi_flow_info_free_data(flow);
458
225k
  ndpi_free(flow);
459
225k
}
460
461
/* ***************************************************** */
462
463
225k
static void ndpi_free_flow_tls_data(struct ndpi_flow_info *flow) {
464
225k
  if(flow->dhcp_fingerprint) {
465
237
    ndpi_free(flow->dhcp_fingerprint);
466
237
    flow->dhcp_fingerprint = NULL;
467
237
  }
468
469
225k
  if(flow->dhcp_class_ident) {
470
145
    ndpi_free(flow->dhcp_class_ident);
471
145
    flow->dhcp_class_ident = NULL;
472
145
  }
473
474
225k
  if(flow->server_hostname) {
475
5.94k
    ndpi_free(flow->server_hostname);
476
5.94k
    flow->server_hostname = NULL;
477
5.94k
  }
478
479
225k
  if(flow->bittorent_hash) {
480
114
    ndpi_free(flow->bittorent_hash);
481
114
    flow->bittorent_hash = NULL;
482
114
  }
483
484
225k
  if(flow->telnet.username) {
485
67
    ndpi_free(flow->telnet.username);
486
67
    flow->telnet.username = NULL;
487
67
  }
488
489
225k
  if(flow->telnet.password) {
490
30
    ndpi_free(flow->telnet.password);
491
30
    flow->telnet.password = NULL;
492
30
  }
493
494
225k
  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
225k
  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
225k
  if(flow->ssh_tls.negotiated_alpn) {
505
867
    ndpi_free(flow->ssh_tls.negotiated_alpn);
506
867
    flow->ssh_tls.negotiated_alpn = NULL;
507
867
  }
508
509
225k
  if(flow->ssh_tls.tls_supported_versions) {
510
5.38k
    ndpi_free(flow->ssh_tls.tls_supported_versions);
511
5.38k
    flow->ssh_tls.tls_supported_versions = NULL;
512
5.38k
  }
513
514
225k
  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
225k
  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
225k
  if(flow->ssh_tls.ja4_client_raw) {
525
8.21k
    ndpi_free(flow->ssh_tls.ja4_client_raw);
526
8.21k
    flow->ssh_tls.ja4_client_raw = NULL;
527
8.21k
  }
528
529
225k
  if(flow->ndpi_fingerprint) {
530
8.44k
    ndpi_free(flow->ndpi_fingerprint);
531
8.44k
    flow->ndpi_fingerprint = NULL;
532
8.44k
  }
533
534
225k
  if(flow->stun.mapped_address.aps) {
535
1.70k
    ndpi_free(flow->stun.mapped_address.aps);
536
1.70k
    flow->stun.mapped_address.aps = NULL;
537
1.70k
  }
538
225k
  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
225k
  if(flow->stun.peer_address.aps) {
543
579
    ndpi_free(flow->stun.peer_address.aps);
544
579
    flow->stun.peer_address.aps = NULL;
545
579
  }
546
225k
  if(flow->stun.relayed_address.aps) {
547
717
    ndpi_free(flow->stun.relayed_address.aps);
548
717
    flow->stun.relayed_address.aps = NULL;
549
717
  }
550
225k
  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
225k
}
555
556
/* ***************************************************** */
557
558
225k
static void ndpi_free_flow_data_analysis(struct ndpi_flow_info *flow) {
559
225k
  if(flow->iat_c_to_s) ndpi_free_data_analysis(flow->iat_c_to_s, 1);
560
225k
  if(flow->iat_s_to_c) ndpi_free_data_analysis(flow->iat_s_to_c, 1);
561
562
225k
  if(flow->pktlen_c_to_s) ndpi_free_data_analysis(flow->pktlen_c_to_s, 1);
563
225k
  if(flow->pktlen_s_to_c) ndpi_free_data_analysis(flow->pktlen_s_to_c, 1);
564
565
225k
  if(flow->iat_flow) ndpi_free_data_analysis(flow->iat_flow, 1);
566
567
225k
  if(flow->entropy) ndpi_free(flow->entropy);
568
225k
  if(flow->last_entropy) ndpi_free(flow->last_entropy);
569
225k
}
570
571
/* ***************************************************** */
572
573
225k
void ndpi_flow_info_free_data(struct ndpi_flow_info *flow) {
574
575
225k
  ndpi_free_flow_info_half(flow);
576
225k
  ndpi_term_serializer(&flow->ndpi_flow_serializer);
577
225k
  ndpi_free_flow_data_analysis(flow);
578
225k
  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
225k
  ndpi_free_bin(&flow->payload_len_bin);
585
225k
#endif
586
587
225k
  if(flow->src_name)        ndpi_free(flow->src_name);
588
225k
  if(flow->dst_name)        ndpi_free(flow->dst_name);
589
225k
  if(flow->tcp_fingerprint) ndpi_free(flow->tcp_fingerprint);
590
225k
  if(flow->risk_str)        ndpi_free(flow->risk_str);
591
225k
  if(flow->flow_payload)    ndpi_free(flow->flow_payload);
592
225k
}
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.41M
static inline int cmp_n32(uint32_t a,uint32_t b) {
614
1.41M
  return a == b ? 0 : ntohl(a) < ntohl(b) ? -1:1;
615
1.41M
}
616
1.19M
static inline int cmp_n16(uint16_t a,uint16_t b) {
617
1.19M
  return a == b ? 0 : ntohs(a) < ntohs(b) ? -1:1;
618
1.19M
}
619
620
/* ***************************************************** */
621
622
5.61M
int ndpi_workflow_node_cmp(const void *a, const void *b) {
623
5.61M
  const struct ndpi_flow_info *fa = (const struct ndpi_flow_info*)a;
624
5.61M
  const struct ndpi_flow_info *fb = (const struct ndpi_flow_info*)b;
625
626
5.61M
  if(fa->hashval < fb->hashval) return(-1); else if(fa->hashval > fb->hashval) return(1);
627
628
  /* Flows have the same hash */
629
630
841k
  if(fa->vlan_id   < fb->vlan_id   ) return(-1); else { if(fa->vlan_id    > fb->vlan_id   ) return(1); }
631
839k
  if(fa->protocol  < fb->protocol  ) return(-1); else { if(fa->protocol   > fb->protocol  ) return(1); }
632
633
836k
  int r;
634
836k
  r = cmp_n32(fa->src_ip, fb->src_ip); if(r) return r;
635
617k
  r = cmp_n16(fa->src_port, fb->src_port) ; if(r) return r;
636
577k
  r = cmp_n32(fa->dst_ip, fb->dst_ip); if(r) return r;
637
575k
  r = cmp_n16(fa->dst_port, fb->dst_port);
638
639
575k
  return(r);
640
577k
}
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
801k
                            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
801k
  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
801k
    u_int32_t current_count;
664
665
801k
    if(src_to_dst_direction) {
666
627k
      current_count = flow->entropy->src2dst_l4_bytes - len;
667
627k
    } else {
668
173k
      current_count = flow->entropy->dst2src_l4_bytes - len;
669
173k
    }
670
671
801k
    if(current_count < ETTA_MIN_OCTETS) {
672
754k
      u_int32_t i;
673
754k
      const unsigned char *data = x;
674
675
135M
      for(i=0; i<len; i++) {
676
134M
        if(src_to_dst_direction) {
677
87.7M
          flow->entropy->src2dst_byte_count[data[i]]++;
678
87.7M
        } else {
679
47.0M
          flow->entropy->dst2src_byte_count[data[i]]++;
680
47.0M
        }
681
134M
        current_count++;
682
134M
        if(current_count >= ETTA_MIN_OCTETS) {
683
8.96k
          break;
684
8.96k
        }
685
134M
      }
686
754k
    }
687
801k
  }
688
801k
}
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
801k
                                    unsigned int len, u_int8_t src_to_dst_direction) {
702
801k
  const unsigned char *data = x;
703
704
801k
  if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
705
801k
    unsigned int i;
706
707
166M
    for(i=0; i<len; i++) {
708
165M
      double delta;
709
710
165M
      if(src_to_dst_direction) {
711
103M
        flow->entropy->src2dst_num_bytes += 1;
712
103M
        delta = ((double)data[i] - flow->entropy->src2dst_bd_mean);
713
103M
        flow->entropy->src2dst_bd_mean += delta/((double)flow->entropy->src2dst_num_bytes);
714
103M
        flow->entropy->src2dst_bd_variance += delta*((double)data[i] - flow->entropy->src2dst_bd_mean);
715
103M
      } else {
716
62.4M
        flow->entropy->dst2src_num_bytes += 1;
717
62.4M
        delta = ((double)data[i] - flow->entropy->dst2src_bd_mean);
718
62.4M
        flow->entropy->dst2src_bd_mean += delta/((double)flow->entropy->dst2src_num_bytes);
719
62.4M
        flow->entropy->dst2src_bd_variance += delta*((double)data[i] - flow->entropy->dst2src_bd_mean);
720
62.4M
      }
721
165M
    }
722
801k
  }
723
801k
}
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
809k
                                                 pkt_timeval when) {
744
809k
  u_int32_t idx, hashval;
745
809k
  struct ndpi_flow_info flow;
746
809k
  void *ret;
747
809k
  const u_int8_t *l3, *l4;
748
809k
  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
809k
  if(version == IPVERSION) {
755
735k
    if(ipsize < 20)
756
10
      return NULL;
757
758
735k
    if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len)
759
735k
       /* || (iph->frag_off & htons(0x1FFF)) != 0 */)
760
6.79k
      return NULL;
761
762
729k
    l3 = (const u_int8_t*)iph;
763
729k
  } else {
764
73.1k
    if(l4_offset > ipsize)
765
0
      return NULL;
766
767
73.1k
    l3 = (const u_int8_t*)iph6;
768
73.1k
  }
769
802k
  if(ipsize < l4_offset + l4_packet_len)
770
901
    return NULL;
771
772
801k
  *proto = iph->protocol;
773
774
801k
  if(l4_packet_len < 64)
775
470k
    workflow->stats.packet_len[0]++;
776
331k
  else if(l4_packet_len >= 64 && l4_packet_len < 128)
777
91.8k
    workflow->stats.packet_len[1]++;
778
239k
  else if(l4_packet_len >= 128 && l4_packet_len < 256)
779
90.6k
    workflow->stats.packet_len[2]++;
780
148k
  else if(l4_packet_len >= 256 && l4_packet_len < 1024)
781
82.7k
    workflow->stats.packet_len[3]++;
782
65.9k
  else if(l4_packet_len >= 1024 && l4_packet_len < 1500)
783
61.9k
    workflow->stats.packet_len[4]++;
784
4.02k
  else if(l4_packet_len >= 1500)
785
4.02k
    workflow->stats.packet_len[5]++;
786
787
801k
  if(l4_packet_len > workflow->stats.max_packet_len)
788
237
    workflow->stats.max_packet_len = l4_packet_len;
789
790
801k
  l4 =& ((const u_int8_t *) l3)[l4_offset];
791
792
801k
  if(*proto == IPPROTO_TCP && l4_packet_len >= sizeof(struct ndpi_tcphdr)) {
793
462k
    u_int tcp_len;
794
795
    // TCP
796
462k
    workflow->stats.tcp_count++;
797
462k
    *tcph = (struct ndpi_tcphdr *)l4;
798
462k
    *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest);
799
462k
    tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len);
800
462k
    *payload = (u_int8_t*)&l4[tcp_len];
801
462k
    *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff);
802
462k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_tcphdr);
803
462k
  } else if(*proto == IPPROTO_UDP && l4_packet_len >= sizeof(struct ndpi_udphdr)) {
804
    // UDP
805
305k
    workflow->stats.udp_count++;
806
305k
    *udph = (struct ndpi_udphdr *)l4;
807
305k
    *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest);
808
305k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_udphdr)];
809
305k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_udphdr)) ? l4_packet_len-sizeof(struct ndpi_udphdr) : 0;
810
305k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_udphdr);
811
305k
  } else if(*proto == IPPROTO_ICMP) {
812
8.24k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmphdr )];
813
8.24k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmphdr)) ? l4_packet_len-sizeof(struct ndpi_icmphdr) : 0;
814
8.24k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmphdr);
815
8.24k
    *sport = *dport = 0;
816
25.2k
  } else if(*proto == IPPROTO_ICMPV6) {
817
5.39k
    *payload = (u_int8_t*)&l4[sizeof(struct ndpi_icmp6hdr)];
818
5.39k
    *payload_len = (l4_packet_len > sizeof(struct ndpi_icmp6hdr)) ? l4_packet_len-sizeof(struct ndpi_icmp6hdr) : 0;
819
5.39k
    l4_data_len = l4_packet_len - sizeof(struct ndpi_icmp6hdr);
820
5.39k
    *sport = *dport = 0;
821
19.8k
  } else {
822
    // non tcp/udp protocols
823
19.8k
    *sport = *dport = 0;
824
19.8k
    l4_data_len = 0;
825
19.8k
  }
826
827
801k
  flow.protocol = iph->protocol, flow.vlan_id = vlan_id;
828
801k
  flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr;
829
801k
  flow.src_port = htons(*sport), flow.dst_port = htons(*dport);
830
801k
  flow.hashval = hashval = flow.protocol + ntohl(flow.src_ip) + ntohl(flow.dst_ip)
831
801k
    + 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
801k
  idx = hashval % workflow->prefs.num_roots;
844
801k
  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
801k
  int is_changed = 0;
848
801k
  if(ret == NULL) {
849
399k
    u_int32_t orig_src_ip = flow.src_ip;
850
399k
    u_int16_t orig_src_port = flow.src_port;
851
399k
    u_int32_t orig_dst_ip = flow.dst_ip;
852
399k
    u_int16_t orig_dst_port = flow.dst_port;
853
854
399k
    flow.src_ip = orig_dst_ip;
855
399k
    flow.src_port = orig_dst_port;
856
399k
    flow.dst_ip = orig_src_ip;
857
399k
    flow.dst_port = orig_src_port;
858
859
399k
    is_changed = 1;
860
861
399k
    ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
862
399k
  }
863
864
801k
  if(ret == NULL) {
865
225k
    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
225k
    } else {
871
225k
      struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)ndpi_malloc(sizeof(struct ndpi_flow_info));
872
873
225k
      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
225k
        workflow->num_allocated_flows++;
878
879
225k
      memset(newflow, 0, sizeof(struct ndpi_flow_info));
880
225k
      newflow->flow_id = flow_id++;
881
225k
      newflow->hashval = hashval;
882
225k
      newflow->tunnel_type = tunnel_type;
883
225k
      newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id;
884
225k
      newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr;
885
225k
      newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport);
886
225k
      newflow->ip_version = version;
887
225k
      newflow->iat_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
888
225k
  newflow->iat_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW);
889
225k
      newflow->pktlen_c_to_s = ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
890
225k
  newflow->pktlen_s_to_c =  ndpi_alloc_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW),
891
225k
  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
225k
      ndpi_init_bin(&newflow->payload_len_bin, ndpi_bin_family8, PLEN_NUM_BINS);
898
225k
#endif
899
900
225k
      if (version == 4 || version == 6) {
901
225k
        uint16_t inet_addrlen = (version == 4) ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
902
225k
        newflow->src_name = ndpi_malloc(inet_addrlen);
903
225k
        newflow->dst_name = ndpi_malloc(inet_addrlen);
904
905
225k
        if(version == 4) {
906
206k
          if (newflow->src_name)
907
206k
            inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, inet_addrlen);
908
206k
          if (newflow->dst_name)
909
206k
            inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, inet_addrlen);
910
206k
        } else if (version == 6) {
911
19.0k
          newflow->src_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_src;
912
19.0k
          newflow->dst_ip6 = *(struct ndpi_in6_addr *)&iph6->ip6_dst;
913
914
19.0k
          if (newflow->src_name)
915
19.0k
            inet_ntop(AF_INET6, &newflow->src_ip6, newflow->src_name, inet_addrlen);
916
19.0k
          if (newflow->dst_name)
917
19.0k
            inet_ntop(AF_INET6, &newflow->dst_ip6, newflow->dst_name, inet_addrlen);
918
919
          /* For consistency across platforms replace :0: with :: */
920
19.0k
          if (newflow->src_name) ndpi_patchIPv6Address(newflow->src_name);
921
19.0k
          if (newflow->dst_name) ndpi_patchIPv6Address(newflow->dst_name);
922
19.0k
        }
923
225k
      }
924
925
225k
      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
225k
  memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT);
932
933
225k
    if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown)
934
225k
    {
935
225k
      if (ndpi_init_serializer(&newflow->ndpi_flow_serializer,
936
225k
                               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
225k
    }
944
945
225k
      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
225k
      workflow->stats.ndpi_flow_count++;
951
225k
      if(*proto == IPPROTO_TCP)
952
133k
        workflow->stats.flow_count[0]++;
953
91.8k
      else if(*proto == IPPROTO_UDP)
954
84.1k
        workflow->stats.flow_count[1]++;
955
7.76k
      else
956
7.76k
        workflow->stats.flow_count[2]++;
957
958
225k
      if(enable_flow_stats) {
959
225k
        newflow->entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
960
225k
        newflow->last_entropy = ndpi_calloc(1, sizeof(struct ndpi_entropy));
961
225k
        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
225k
        newflow->entropy->src2dst_pkt_len[newflow->entropy->src2dst_pkt_count] = l4_data_len;
968
225k
        newflow->entropy->src2dst_pkt_time[newflow->entropy->src2dst_pkt_count] = when;
969
225k
        if(newflow->entropy->src2dst_pkt_count == 0) {
970
225k
          newflow->entropy->src2dst_start = when;
971
225k
        }
972
225k
        newflow->entropy->src2dst_pkt_count++;
973
        // Non zero app data.
974
225k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
975
217k
          newflow->entropy->src2dst_opackets++;
976
217k
          newflow->entropy->src2dst_l4_bytes += l4_data_len;
977
217k
        }
978
225k
      }
979
225k
      return newflow;
980
225k
    }
981
575k
  } else {
982
575k
    struct ndpi_flow_info *rflow = *(struct ndpi_flow_info**)ret;
983
984
575k
    if(is_changed) {
985
173k
  *src_to_dst_direction = 0, rflow->bidirectional |= 1;
986
173k
    }
987
401k
    else {
988
401k
  *src_to_dst_direction = 1;
989
401k
    }
990
575k
    if(enable_flow_stats) {
991
575k
      if(*src_to_dst_direction) {
992
401k
        if(rflow->entropy->src2dst_pkt_count < max_num_packets_per_flow) {
993
401k
          rflow->entropy->src2dst_pkt_len[rflow->entropy->src2dst_pkt_count] = l4_data_len;
994
401k
          rflow->entropy->src2dst_pkt_time[rflow->entropy->src2dst_pkt_count] = when;
995
401k
          rflow->entropy->src2dst_l4_bytes += l4_data_len;
996
401k
          rflow->entropy->src2dst_pkt_count++;
997
401k
        }
998
        // Non zero app data.
999
401k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1000
360k
          rflow->entropy->src2dst_opackets++;
1001
360k
        }
1002
401k
      } else {
1003
173k
        if(rflow->entropy->dst2src_pkt_count < max_num_packets_per_flow) {
1004
173k
          rflow->entropy->dst2src_pkt_len[rflow->entropy->dst2src_pkt_count] = l4_data_len;
1005
173k
          rflow->entropy->dst2src_pkt_time[rflow->entropy->dst2src_pkt_count] = when;
1006
173k
          if(rflow->entropy->dst2src_pkt_count == 0) {
1007
51.7k
            rflow->entropy->dst2src_start = when;
1008
51.7k
          }
1009
173k
          rflow->entropy->dst2src_l4_bytes += l4_data_len;
1010
173k
          rflow->entropy->dst2src_pkt_count++;
1011
173k
        }
1012
        // Non zero app data.
1013
173k
        if(l4_data_len != 0XFEEDFACE && l4_data_len != 0) {
1014
153k
          rflow->entropy->dst2src_opackets++;
1015
153k
        }
1016
173k
      }
1017
575k
    }
1018
1019
575k
    return(rflow);
1020
575k
  }
1021
801k
}
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
73.2k
                                                  pkt_timeval when) {
1038
73.2k
  struct ndpi_iphdr iph;
1039
1040
73.2k
  if(ipsize < 40)
1041
10
    return(NULL);
1042
73.2k
  memset(&iph, 0, sizeof(iph));
1043
73.2k
  iph.version = IPVERSION;
1044
73.2k
  iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3];
1045
73.2k
  iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3];
1046
73.2k
  u_int8_t l4proto = iph6->ip6_hdr.ip6_un1_nxt;
1047
73.2k
  u_int16_t ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
1048
73.2k
  const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
1049
73.2k
  if(ipsize < sizeof(struct ndpi_ipv6hdr) + ip_len)
1050
12
    return(NULL);
1051
73.2k
  if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &l4proto) != 0) {
1052
26
    return(NULL);
1053
26
  }
1054
73.1k
  iph.protocol = l4proto;
1055
1056
73.1k
  return(get_ndpi_flow_info(workflow, 6, vlan_id, tunnel_type,
1057
73.1k
          &iph, iph6, ipsize,
1058
73.1k
          ip_len, l4ptr - (const u_int8_t *)iph6,
1059
73.1k
          tcph, udph, sport, dport,
1060
73.1k
          proto, payload,
1061
73.1k
          payload_len, src_to_dst_direction, when));
1062
73.2k
}
1063
1064
/* ****************************************************** */
1065
1066
855k
u_int8_t is_ndpi_proto(struct ndpi_flow_info *flow, u_int16_t id) {
1067
855k
  if((flow->detected_protocol.proto.master_protocol == id)
1068
803k
     || (flow->detected_protocol.proto.app_protocol == id))
1069
73.0k
    return(1);
1070
782k
  else
1071
782k
    return(0);
1072
855k
}
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
624k
u_int8_t plen2slot(u_int16_t plen) {
1085
  /*
1086
     Slots [32 bytes lenght]
1087
     0..31, 32..63 ...
1088
  */
1089
1090
624k
  if(plen > PLEN_MAX)
1091
3.72k
    return(PLEN_NUM_BINS-1);
1092
620k
  else
1093
620k
    return(plen/PLEN_BIN_LEN);
1094
624k
}
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,
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
233k
{
1137
233k
  int new_num;
1138
233k
  void *new_buf;
1139
233k
  unsigned int i;
1140
1141
233k
  if(ap->port == 0)
1142
221k
    return;
1143
1144
  /* Avoid saving duplicates */
1145
18.3k
  for(i = 0; i < list->num_aps; i++)
1146
13.7k
    if(memcmp(&list->aps[i], ap, sizeof(*ap)) == 0)
1147
7.23k
      return;
1148
1149
4.54k
  if(list->num_aps == list->num_aps_allocated) {
1150
4.11k
    new_num = 1 + list->num_aps_allocated * 2;
1151
4.11k
    new_buf = ndpi_realloc(list->aps, list->num_aps_allocated * sizeof(ndpi_address_port),
1152
4.11k
                     new_num * sizeof(ndpi_address_port));
1153
4.11k
    if(!new_buf)
1154
0
      return;
1155
4.11k
    list->aps = new_buf;
1156
4.11k
    list->num_aps_allocated = new_num;
1157
4.11k
  }
1158
4.54k
  memcpy(&list->aps[list->num_aps++], ap, sizeof(ndpi_address_port));
1159
4.54k
}
1160
1161
/* ****************************************************** */
1162
1163
595k
static void process_ndpi_monitoring_info(struct ndpi_flow_info *flow) {
1164
595k
  if(!flow->ndpi_flow || !flow->ndpi_flow->monit)
1165
547k
    return;
1166
1167
47.4k
  if(flow->monitoring_state == 0 &&
1168
26.7k
     flow->ndpi_flow->monitoring) {
1169
    /* We just moved to monitoring state */
1170
273
    flow->monitoring_state = 1;
1171
273
    flow->num_packets_before_monitoring = flow->ndpi_flow->packet_direction_complete_counter[0] + flow->ndpi_flow->packet_direction_complete_counter[1];
1172
273
  }
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
47.4k
  if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_STUN ||
1181
44.6k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_STUN ||
1182
21.2k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_DTLS ||
1183
21.1k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_DTLS ||
1184
16.0k
     flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_SRTP ||
1185
46.6k
     flow->detected_protocol.proto.master_protocol == NDPI_PROTOCOL_SRTP) {
1186
1187
46.6k
    add_to_address_port_list(&flow->stun.mapped_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.mapped_address);
1188
46.6k
    add_to_address_port_list(&flow->stun.other_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.other_address);
1189
46.6k
    add_to_address_port_list(&flow->stun.peer_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.peer_address);
1190
46.6k
    add_to_address_port_list(&flow->stun.relayed_address, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.relayed_address);
1191
46.6k
    add_to_address_port_list(&flow->stun.response_origin, &flow->ndpi_flow->monit->protos.dtls_stun_rtp.response_origin);
1192
46.6k
    flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1193
1194
46.6k
    flow->stun.rtp_counters[0] = flow->ndpi_flow->stun.rtp_counters[0];
1195
46.6k
    flow->stun.rtp_counters[1] = flow->ndpi_flow->stun.rtp_counters[1];
1196
46.6k
  }
1197
47.4k
}
1198
1199
/* ****************************************************** */
1200
1201
static void serialize_monitoring_metadata(struct ndpi_flow_info *flow)
1202
325
{
1203
325
  unsigned int i;
1204
325
  char buf[64];
1205
1206
325
  if(!flow->ndpi_flow->monit)
1207
52
    return;
1208
1209
273
  ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "monitoring");
1210
1211
273
  switch(flow->detected_protocol.proto.master_protocol ? flow->detected_protocol.proto.master_protocol : flow->detected_protocol.proto.app_protocol) {
1212
93
    case NDPI_PROTOCOL_STUN:
1213
153
    case NDPI_PROTOCOL_DTLS:
1214
266
    case NDPI_PROTOCOL_SRTP:
1215
266
      ndpi_serialize_start_of_block(&flow->ndpi_flow_serializer, "stun");
1216
1217
266
      if(flow->stun.mapped_address.num_aps > 0) {
1218
221
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "mapped_address");
1219
689
        for(i = 0; i < flow->stun.mapped_address.num_aps; i++) {
1220
468
          if(flow->stun.mapped_address.aps[i].port > 0) {
1221
468
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "mapped_address",
1222
468
                                         print_ndpi_address_port(&flow->stun.mapped_address.aps[i], buf, sizeof(buf)));
1223
468
          }
1224
468
        }
1225
221
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1226
221
      }
1227
1228
266
      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
266
      if(flow->stun.peer_address.num_aps > 0) {
1240
97
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "peer_address");
1241
441
        for(i = 0; i < flow->stun.peer_address.num_aps; i++) {
1242
344
          if(flow->stun.peer_address.aps[i].port > 0) {
1243
344
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "peer_address",
1244
344
                                         print_ndpi_address_port(&flow->stun.peer_address.aps[i], buf, sizeof(buf)));
1245
344
          }
1246
344
        }
1247
97
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1248
97
      }
1249
1250
266
      if(flow->stun.relayed_address.num_aps > 0) {
1251
132
        ndpi_serialize_start_of_list(&flow->ndpi_flow_serializer, "relayed_address");
1252
297
        for(i = 0; i < flow->stun.relayed_address.num_aps; i++) {
1253
165
          if(flow->stun.relayed_address.aps[i].port > 0) {
1254
165
            ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "relayed_address",
1255
165
                                         print_ndpi_address_port(&flow->stun.relayed_address.aps[i], buf, sizeof(buf)));
1256
165
          }
1257
165
        }
1258
132
        ndpi_serialize_end_of_list(&flow->ndpi_flow_serializer);
1259
132
      }
1260
1261
266
      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
266
      ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer); /* stun */
1273
1274
266
      break;
1275
273
  }
1276
1277
273
  ndpi_serialize_end_of_block(&flow->ndpi_flow_serializer);
1278
273
}
1279
1280
/* ****************************************************** */
1281
1282
274k
void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) {
1283
274k
  u_int i;
1284
274k
  char out[128], *s;
1285
1286
274k
  if(!flow->ndpi_flow) return;
1287
1288
225k
  flow->info_type = INFO_INVALID;
1289
1290
225k
  s = ndpi_get_flow_risk_info(flow->ndpi_flow, out, sizeof(out), 0 /* text */);
1291
1292
225k
  if(s != NULL)
1293
191k
    flow->risk_str = ndpi_strdup(s);
1294
1295
225k
  flow->confidence = flow->ndpi_flow->confidence;
1296
1297
225k
  flow->num_dissector_calls = flow->ndpi_flow->num_dissector_calls;
1298
1299
225k
  ndpi_snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s",
1300
225k
    flow->ndpi_flow->host_server_name);
1301
1302
225k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MINING)) {
1303
88
    ndpi_snprintf(flow->mining.currency, sizeof(flow->mining.currency), "%s",
1304
88
      flow->ndpi_flow->protos.mining.currency);
1305
88
  }
1306
1307
225k
  flow->risk = flow->ndpi_flow->risk;
1308
1309
225k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DHCP)) {
1310
635
    if(flow->ndpi_flow->protos.dhcp.fingerprint[0] != '\0')
1311
237
      flow->dhcp_fingerprint = ndpi_strdup(flow->ndpi_flow->protos.dhcp.fingerprint);
1312
1313
635
    if(flow->ndpi_flow->protos.dhcp.class_ident[0] != '\0')
1314
145
      flow->dhcp_class_ident = ndpi_strdup(flow->ndpi_flow->protos.dhcp.class_ident);
1315
225k
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_BITTORRENT) &&
1316
10.9k
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS) &&
1317
10.9k
            !ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TLS)) {
1318
10.9k
    u_int j;
1319
1320
10.9k
    if(flow->ndpi_flow->protos.bittorrent.hash[0] != '\0') {
1321
114
      u_int avail = sizeof(flow->ndpi_flow->protos.bittorrent.hash) * 2 + 1;
1322
114
      flow->bittorent_hash = ndpi_malloc(avail);
1323
1324
114
      if(flow->bittorent_hash) {
1325
2.39k
        for(i=0, j = 0; i < sizeof(flow->ndpi_flow->protos.bittorrent.hash); i++) {
1326
2.28k
          snprintf(&flow->bittorent_hash[j], avail-j, "%02x",
1327
2.28k
            flow->ndpi_flow->protos.bittorrent.hash[i]);
1328
1329
2.28k
          j += 2;
1330
2.28k
        }
1331
1332
114
        flow->bittorent_hash[j] = '\0';
1333
114
      }
1334
114
    }
1335
10.9k
  }
1336
  /* TIVOCONNECT */
1337
214k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TIVOCONNECT)) {
1338
186
    flow->info_type = INFO_TIVOCONNECT;
1339
186
    ndpi_snprintf(flow->tivoconnect.identity_uuid, sizeof(flow->tivoconnect.identity_uuid),
1340
186
                  "%s", flow->ndpi_flow->protos.tivoconnect.identity_uuid);
1341
186
    ndpi_snprintf(flow->tivoconnect.machine, sizeof(flow->tivoconnect.machine),
1342
186
                  "%s", flow->ndpi_flow->protos.tivoconnect.machine);
1343
186
    ndpi_snprintf(flow->tivoconnect.platform, sizeof(flow->tivoconnect.platform),
1344
186
                  "%s", flow->ndpi_flow->protos.tivoconnect.platform);
1345
186
    ndpi_snprintf(flow->tivoconnect.services, sizeof(flow->tivoconnect.services),
1346
186
                  "%s", flow->ndpi_flow->protos.tivoconnect.services);
1347
186
  }
1348
  /* SOFTETHER */
1349
213k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SOFTETHER) &&
1350
260
      !ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_HTTP)) {
1351
236
    flow->info_type = INFO_SOFTETHER;
1352
236
    ndpi_snprintf(flow->softether.ip, sizeof(flow->softether.ip), "%s",
1353
236
                  flow->ndpi_flow->protos.softether.ip);
1354
236
    ndpi_snprintf(flow->softether.port, sizeof(flow->softether.port), "%s",
1355
236
                  flow->ndpi_flow->protos.softether.port);
1356
236
    ndpi_snprintf(flow->softether.hostname, sizeof(flow->softether.hostname), "%s",
1357
236
                  flow->ndpi_flow->protos.softether.hostname);
1358
236
    ndpi_snprintf(flow->softether.fqdn, sizeof(flow->softether.fqdn), "%s",
1359
236
                  flow->ndpi_flow->protos.softether.fqdn);
1360
236
  }
1361
  /* SERVICE_LOCATION */
1362
213k
  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
209k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_NATPMP)) {
1383
342
    flow->info_type = INFO_NATPMP;
1384
342
    flow->natpmp.result_code = flow->ndpi_flow->protos.natpmp.result_code;
1385
342
    flow->natpmp.internal_port = flow->ndpi_flow->protos.natpmp.internal_port;
1386
342
    flow->natpmp.external_port = flow->ndpi_flow->protos.natpmp.external_port;
1387
342
    inet_ntop(AF_INET, &flow->ndpi_flow->protos.natpmp.external_address.ipv4, &flow->natpmp.ip[0], sizeof(flow->natpmp.ip));
1388
342
  }
1389
  /* DISCORD */
1390
209k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DISCORD) &&
1391
903
          !ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1392
872
          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
209k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_DNS)) {
1399
7.24k
    if(flow->ndpi_flow->protos.dns.is_rsp_addr_ipv6[0] == 0)
1400
7.12k
    {
1401
7.12k
      flow->info_type = INFO_GENERIC;
1402
7.12k
      inet_ntop(AF_INET, &flow->ndpi_flow->protos.dns.rsp_addr[0].ipv4, flow->info, sizeof(flow->info));
1403
7.12k
    } else {
1404
118
      flow->info_type = INFO_GENERIC;
1405
118
      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
118
      ndpi_patchIPv6Address(flow->info);
1409
118
    }
1410
1411
7.24k
    if(flow->ndpi_flow->protos.dns.geolocation_iata_code[0] != '\0')
1412
18
      strcpy(flow->dns.geolocation_iata_code, flow->ndpi_flow->protos.dns.geolocation_iata_code);
1413
1414
7.24k
    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.24k
    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.24k
  }
1437
  /* MDNS */
1438
202k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MDNS)) {
1439
998
    flow->info_type = INFO_GENERIC;
1440
998
    ndpi_snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->host_server_name);
1441
998
  }
1442
  /* UBNTAC2 */
1443
201k
  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
201k
  else if(!ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack) &&
1449
180k
          (ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_FTP_CONTROL) ||
1450
179k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack,  NDPI_PROTOCOL_MAIL_IMAP) ||
1451
179k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_POP) ||
1452
179k
     ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_MAIL_SMTP))) {
1453
2.88k
    flow->info_type = INFO_FTP_IMAP_POP_SMTP;
1454
2.88k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.username,
1455
2.88k
                  sizeof(flow->ftp_imap_pop_smtp.username),
1456
2.88k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.username);
1457
2.88k
    ndpi_snprintf(flow->ftp_imap_pop_smtp.password,
1458
2.88k
                  sizeof(flow->ftp_imap_pop_smtp.password),
1459
2.88k
                  "%s", flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.password);
1460
2.88k
    flow->ftp_imap_pop_smtp.auth_failed =
1461
2.88k
      flow->ndpi_flow->l4.tcp.ftp_imap_pop_smtp.auth_failed;
1462
2.88k
  }
1463
  /* TFTP */
1464
198k
  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
197k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_KERBEROS)) {
1472
1.90k
    flow->info_type = INFO_KERBEROS;
1473
1.90k
    ndpi_snprintf(flow->kerberos.domain,
1474
1.90k
                  sizeof(flow->kerberos.domain),
1475
1.90k
                  "%s", flow->ndpi_flow->protos.kerberos.domain);
1476
1.90k
    ndpi_snprintf(flow->kerberos.hostname,
1477
1.90k
                  sizeof(flow->kerberos.hostname),
1478
1.90k
                  "%s", flow->ndpi_flow->protos.kerberos.hostname);
1479
1.90k
    ndpi_snprintf(flow->kerberos.username,
1480
1.90k
                  sizeof(flow->kerberos.username),
1481
1.90k
                  "%s", flow->ndpi_flow->protos.kerberos.username);
1482
  /* COLLECTD */
1483
195k
  } 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
195k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SIP)) {
1491
494
    flow->info_type = INFO_SIP;
1492
494
    if(flow->ndpi_flow->protos.sip.from)
1493
281
      ndpi_snprintf(flow->sip.from, sizeof(flow->sip.from), "%s", flow->ndpi_flow->protos.sip.from);
1494
494
    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
494
    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
494
    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
494
  }
1501
  /* BFCP */
1502
195k
  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
195k
  else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_TELNET)) {
1509
606
    if(flow->ndpi_flow->protos.telnet.username[0] != '\0')
1510
67
      flow->telnet.username = ndpi_strdup(flow->ndpi_flow->protos.telnet.username);
1511
606
    if(flow->ndpi_flow->protos.telnet.password[0] != '\0')
1512
30
      flow->telnet.password = ndpi_strdup(flow->ndpi_flow->protos.telnet.password);
1513
194k
  } else if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_SSH)) {
1514
842
    ndpi_snprintf(flow->host_server_name,
1515
842
       sizeof(flow->host_server_name), "%s",
1516
842
       flow->ndpi_flow->protos.ssh.client_signature);
1517
842
    ndpi_snprintf(flow->ssh_tls.server_info, sizeof(flow->ssh_tls.server_info), "%s",
1518
842
       flow->ndpi_flow->protos.ssh.server_signature);
1519
842
    ndpi_snprintf(flow->ssh_tls.client_hassh, sizeof(flow->ssh_tls.client_hassh), "%s",
1520
842
       flow->ndpi_flow->protos.ssh.hassh_client);
1521
842
    ndpi_snprintf(flow->ssh_tls.server_hassh, sizeof(flow->ssh_tls.server_hassh), "%s",
1522
842
       flow->ndpi_flow->protos.ssh.hassh_server);
1523
842
  }
1524
  /* TLS/QUIC/DTLS/MAIL_S/FTPS */
1525
193k
  else if(ndpi_stack_is_tls_like(&flow->detected_protocol.protocol_stack)) {
1526
20.6k
    flow->ssh_tls.ssl_version = flow->ndpi_flow->protos.tls_quic.ssl_version;
1527
20.6k
    flow->ssh_tls.quic_version = flow->ndpi_flow->protos.tls_quic.quic_version;
1528
1529
20.6k
    if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_QUIC))
1530
6.97k
      flow->idle_timeout_sec = flow->ndpi_flow->protos.tls_quic.quic_idle_timeout_sec;
1531
1532
20.6k
    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.6k
    flow->ssh_tls.notBefore = flow->ndpi_flow->protos.tls_quic.notBefore;
1536
20.6k
    flow->ssh_tls.notAfter = flow->ndpi_flow->protos.tls_quic.notAfter;
1537
20.6k
    ndpi_snprintf(flow->ssh_tls.ja4_client, sizeof(flow->ssh_tls.ja4_client), "%s",
1538
20.6k
       flow->ndpi_flow->protos.tls_quic.ja4_client);
1539
1540
20.6k
    if(flow->ndpi_flow->ndpi.fingerprint)
1541
8.44k
      flow->ndpi_fingerprint = ndpi_strdup(flow->ndpi_flow->ndpi.fingerprint);
1542
1543
20.6k
    if(flow->ndpi_flow->protos.tls_quic.ja4_client_raw)
1544
8.21k
      flow->ssh_tls.ja4_client_raw = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.ja4_client_raw);
1545
1546
20.6k
    ndpi_snprintf(flow->ssh_tls.ja3_server, sizeof(flow->ssh_tls.ja3_server), "%s",
1547
20.6k
            flow->ndpi_flow->protos.tls_quic.ja3_server);
1548
20.6k
    flow->ssh_tls.server_unsafe_cipher = flow->ndpi_flow->protos.tls_quic.server_unsafe_cipher;
1549
20.6k
    flow->ssh_tls.server_cipher = flow->ndpi_flow->protos.tls_quic.server_cipher;
1550
1551
20.6k
    if(flow->ndpi_flow->protos.tls_quic.fingerprint_set) {
1552
1.84k
      memcpy(flow->ssh_tls.sha1_cert_fingerprint,
1553
1.84k
       flow->ndpi_flow->protos.tls_quic.sha1_certificate_fingerprint, 20);
1554
1.84k
      flow->ssh_tls.sha1_cert_fingerprint_set = 1;
1555
1.84k
    }
1556
1557
20.6k
    flow->ssh_tls.browser_heuristics = flow->ndpi_flow->protos.tls_quic.browser_heuristics;
1558
1559
20.6k
    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.6k
    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.6k
    flow->ssh_tls.encrypted_ch.version = flow->ndpi_flow->protos.tls_quic.encrypted_ch.version;
1566
1567
20.6k
    if(flow->ndpi_flow->protos.tls_quic.tls_supported_versions) {
1568
5.38k
      if((flow->ssh_tls.tls_supported_versions = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.tls_supported_versions)) != NULL)
1569
5.38k
  correct_csv_data_field(flow->ssh_tls.tls_supported_versions);
1570
5.38k
    }
1571
1572
20.6k
    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.6k
    if(flow->ndpi_flow->protos.tls_quic.negotiated_alpn) {
1578
867
      if((flow->ssh_tls.negotiated_alpn = ndpi_strdup(flow->ndpi_flow->protos.tls_quic.negotiated_alpn)) != NULL)
1579
867
  correct_csv_data_field(flow->ssh_tls.negotiated_alpn);
1580
867
    }
1581
1582
20.6k
    if(flow->protocol == IPPROTO_TCP) {
1583
12.7k
      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.7k
      flow->ssh_tls.num_blocks = flow->ndpi_flow->l4.tcp.tls.num_tls_blocks;
1596
12.7k
      memcpy(flow->ssh_tls.blocks, flow->ndpi_flow->l4.tcp.tls.tls_blocks, sizeof(flow->ndpi_flow->l4.tcp.tls.tls_blocks));
1597
12.7k
    }
1598
20.6k
  }
1599
  /* FASTCGI */
1600
172k
  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
225k
  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
225k
  flow->multimedia_flow_types |= flow->ndpi_flow->flow_multimedia_types;
1616
1617
225k
  if(flow->ndpi_flow->tcp.fingerprint) {
1618
57.1k
    char buf[128];
1619
1620
57.1k
    snprintf(buf, sizeof(buf), "%s/%s", flow->ndpi_flow->tcp.fingerprint,
1621
57.1k
       ndpi_print_os_hint(flow->ndpi_flow->tcp.os_hint));
1622
57.1k
    flow->tcp_fingerprint = ndpi_strdup(buf);
1623
57.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
225k
  if(ndpi_stack_is_http_like(&flow->detected_protocol.protocol_stack)) { /* HTTP, HTTP_PROXY, HTTP_CONNECT */
1628
38.6k
    if(flow->ndpi_flow->http.url != NULL) {
1629
24.7k
      ndpi_snprintf(flow->http.url, sizeof(flow->http.url), "%s", flow->ndpi_flow->http.url);
1630
24.7k
    }
1631
1632
38.6k
    flow->http.response_status_code = flow->ndpi_flow->http.response_status_code;
1633
38.6k
    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
38.6k
    ndpi_snprintf(flow->http.server, sizeof(flow->http.server), "%s", flow->ndpi_flow->http.server ? flow->ndpi_flow->http.server : "");
1635
38.6k
    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
38.6k
    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
38.6k
    ndpi_snprintf(flow->http.filename, sizeof(flow->http.filename), "%s", flow->ndpi_flow->http.filename ? flow->ndpi_flow->http.filename : "");
1638
38.6k
    ndpi_snprintf(flow->http.username, sizeof(flow->http.username), "%s", flow->ndpi_flow->http.username ? flow->ndpi_flow->http.username : "");
1639
38.6k
    ndpi_snprintf(flow->http.password, sizeof(flow->http.password), "%s", flow->ndpi_flow->http.password ? flow->ndpi_flow->http.password : "");
1640
38.6k
  }
1641
1642
225k
  if(ndpi_stack_contains(&flow->detected_protocol.protocol_stack, NDPI_PROTOCOL_RTP))
1643
433
    memcpy(&flow->rtp, &flow->ndpi_flow->rtp, sizeof(flow->rtp));
1644
1645
225k
  ndpi_snprintf(flow->http.user_agent,
1646
225k
                sizeof(flow->http.user_agent),
1647
225k
                "%s", (flow->ndpi_flow->http.user_agent ? flow->ndpi_flow->http.user_agent : ""));
1648
1649
225k
  {
1650
225k
    ndpi_ip_addr_t ip_addr;
1651
225k
    struct ndpi_address_cache_item *c;
1652
1653
225k
    memset(&ip_addr, 0, sizeof(ip_addr));
1654
1655
225k
    if(flow->ip_version == 4)
1656
206k
      ip_addr.ipv4 = flow->dst_ip;
1657
19.0k
    else
1658
19.0k
      memcpy(&ip_addr.ipv6, &flow->dst_ip6, sizeof(struct ndpi_in6_addr));
1659
1660
225k
    c = ndpi_cache_address_find(workflow->ndpi_struct, ip_addr);
1661
1662
225k
    if(c) {
1663
5.94k
      flow->server_hostname = ndpi_strdup(c->hostname);
1664
5.94k
    }
1665
225k
  }
1666
1667
225k
  if (workflow->ndpi_serialization_format != ndpi_serialization_format_unknown) {
1668
225k
    if (ndpi_flow2json(workflow->ndpi_struct, flow->ndpi_flow,
1669
225k
                       flow->ip_version, flow->protocol,
1670
225k
           flow->vlan_id,
1671
225k
                       flow->src_ip, flow->dst_ip,
1672
225k
                       &flow->src_ip6, &flow->dst_ip6,
1673
225k
                       flow->src_port, flow->dst_port,
1674
225k
                       flow->detected_protocol,
1675
225k
                       &flow->ndpi_flow_serializer) != 0) {
1676
0
      LOG(NDPI_LOG_ERROR, "flow2json failed\n");
1677
0
      return;
1678
0
    }
1679
1680
225k
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed);
1681
225k
    ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "check_extra_packets", flow->check_extra_packets);
1682
1683
225k
    if(flow->ndpi_flow->monitoring) {
1684
325
      serialize_monitoring_metadata(flow);
1685
325
    }
1686
1687
225k
    if(flow->server_hostname)
1688
5.94k
      ndpi_serialize_string_string(&flow->ndpi_flow_serializer, "server_hostname", flow->server_hostname);
1689
225k
  }
1690
1691
225k
  if(flow->detection_completed && (!flow->check_extra_packets)) {
1692
48.7k
    flow->flow_payload = flow->ndpi_flow->flow_payload, flow->flow_payload_len = flow->ndpi_flow->flow_payload_len;
1693
48.7k
    flow->ndpi_flow->flow_payload = NULL; /* We'll free the memory */
1694
1695
48.7k
    if(workflow->flow_callback != NULL)
1696
0
      workflow->flow_callback(workflow, flow, workflow->flow_callback_userdata);
1697
1698
48.7k
    if(fingerprint_fp)
1699
0
      dump_flow_fingerprint(workflow, flow);
1700
1701
48.7k
    ndpi_free_flow_info_half(flow);
1702
48.7k
  }
1703
225k
}
1704
1705
/* ****************************************************** */
1706
1707
/**
1708
 * @brief Clear entropy stats if it meets prereq.
1709
 */
1710
static void
1711
801k
ndpi_clear_entropy_stats(struct ndpi_flow_info *flow) {
1712
801k
  if(enable_flow_stats) {
1713
801k
    if(flow->entropy->src2dst_pkt_count + flow->entropy->dst2src_pkt_count == max_num_packets_per_flow) {
1714
36.1k
      memcpy(flow->last_entropy, flow->entropy,  sizeof(struct ndpi_entropy));
1715
36.1k
      memset(flow->entropy, 0x00, sizeof(struct ndpi_entropy));
1716
36.1k
    }
1717
801k
  }
1718
801k
}
1719
1720
462k
void update_tcp_flags_count(struct ndpi_flow_info* flow, struct ndpi_tcphdr* tcp, u_int8_t src_to_dst_direction){
1721
462k
  if(tcp->cwr){
1722
20.6k
    flow->cwr_count++;
1723
20.6k
    src_to_dst_direction ? flow->src2dst_cwr_count++ : flow->dst2src_cwr_count++;
1724
20.6k
  }
1725
462k
  if(tcp->ece){
1726
40.6k
    flow->ece_count++;
1727
40.6k
    src_to_dst_direction ? flow->src2dst_ece_count++ : flow->dst2src_ece_count++;
1728
40.6k
  }
1729
462k
  if(tcp->rst){
1730
54.8k
    flow->rst_count++;
1731
54.8k
    src_to_dst_direction ? flow->src2dst_rst_count++ : flow->dst2src_rst_count++;
1732
54.8k
  }
1733
462k
  if(tcp->ack){
1734
343k
    flow->ack_count++;
1735
343k
    src_to_dst_direction ? flow->src2dst_ack_count++ : flow->dst2src_ack_count++;
1736
343k
  }
1737
462k
  if(tcp->fin){
1738
52.5k
    flow->fin_count++;
1739
52.5k
    src_to_dst_direction ? flow->src2dst_fin_count++ : flow->dst2src_fin_count++;
1740
52.5k
  }
1741
462k
  if(tcp->syn){
1742
133k
    flow->syn_count++;
1743
133k
    src_to_dst_direction ? flow->src2dst_syn_count++ : flow->dst2src_syn_count++;
1744
133k
  }
1745
462k
  if(tcp->psh){
1746
194k
    flow->psh_count++;
1747
194k
    src_to_dst_direction ? flow->src2dst_psh_count++ : flow->dst2src_psh_count++;
1748
194k
  }
1749
462k
  if(tcp->urg){
1750
51.7k
    flow->urg_count++;
1751
51.7k
    src_to_dst_direction ? flow->src2dst_urg_count++ : flow->dst2src_urg_count++;
1752
51.7k
  }
1753
462k
}
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
809k
             struct ndpi_flow_info **flow_ext) {
1776
809k
  struct ndpi_flow_info *flow = NULL;
1777
809k
  struct ndpi_flow_struct *ndpi_flow = NULL;
1778
809k
  u_int8_t proto;
1779
809k
  struct ndpi_tcphdr *tcph = NULL;
1780
809k
  struct ndpi_udphdr *udph = NULL;
1781
809k
  u_int16_t sport, dport, payload_len = 0;
1782
809k
  u_int8_t *payload;
1783
809k
  u_int8_t src_to_dst_direction = 1;
1784
809k
  u_int8_t begin_or_end_tcp = 0;
1785
809k
  struct ndpi_proto nproto;
1786
1787
809k
  memset(&nproto, '\0', sizeof(nproto));
1788
1789
809k
  if(workflow->prefs.ignore_vlanid)
1790
0
    vlan_id = 0;
1791
1792
809k
  if(iph)
1793
735k
    flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id,
1794
735k
            tunnel_type, iph, NULL,
1795
735k
            ipsize,
1796
735k
            ntohs(iph->tot_len) ? (ntohs(iph->tot_len) - (iph->ihl * 4)) : ipsize - (iph->ihl * 4) /* TSO */,
1797
735k
            iph->ihl * 4,
1798
735k
            &tcph, &udph, &sport, &dport,
1799
735k
            &proto,
1800
735k
            &payload, &payload_len, &src_to_dst_direction, when);
1801
73.2k
  else
1802
73.2k
    flow = get_ndpi_flow_info6(workflow, vlan_id,
1803
73.2k
             tunnel_type, iph6, ipsize,
1804
73.2k
             &tcph, &udph, &sport, &dport,
1805
73.2k
             &proto,
1806
73.2k
             &payload, &payload_len, &src_to_dst_direction, when);
1807
1808
809k
  if(flow != NULL) {
1809
801k
    pkt_timeval tdiff;
1810
1811
801k
    workflow->stats.ip_packet_count++;
1812
801k
    workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */,
1813
801k
      workflow->stats.total_ip_bytes += rawsize;
1814
801k
    ndpi_flow = flow->ndpi_flow;
1815
1816
801k
    if(tcph != NULL){
1817
462k
      update_tcp_flags_count(flow, tcph, src_to_dst_direction);
1818
462k
      if(tcph->syn && !flow->src2dst_bytes){
1819
67.2k
  flow->c_to_s_init_win = rawsize;
1820
395k
      }else if(tcph->syn && tcph->ack && flow->src2dst_bytes == flow->c_to_s_init_win){
1821
12.8k
  flow->s_to_c_init_win = rawsize;
1822
12.8k
      }
1823
462k
    }
1824
1825
801k
    if((tcph != NULL) && (tcph->fin || tcph->rst || tcph->syn))
1826
175k
      begin_or_end_tcp = 1;
1827
1828
801k
    if(flow->flow_last_pkt_time.tv_sec) {
1829
529k
      ndpi_timer_sub(&when, &flow->flow_last_pkt_time, &tdiff);
1830
1831
529k
      if(flow->iat_flow
1832
529k
   && (tdiff.tv_sec >= 0) /* Discard backward time */
1833
529k
   ) {
1834
512k
  u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1835
1836
512k
  if(ms > 0)
1837
216k
    ndpi_data_add_value(flow->iat_flow, ms);
1838
512k
      }
1839
529k
    }
1840
1841
801k
    memcpy(&flow->flow_last_pkt_time, &when, sizeof(when));
1842
1843
801k
    if(src_to_dst_direction) {
1844
627k
      if(flow->src2dst_last_pkt_time.tv_sec) {
1845
357k
  ndpi_timer_sub(&when, &flow->src2dst_last_pkt_time, &tdiff);
1846
1847
357k
  if(flow->iat_c_to_s
1848
357k
     && (tdiff.tv_sec >= 0) /* Discard backward time */
1849
357k
     ) {
1850
343k
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1851
1852
343k
    ndpi_data_add_value(flow->iat_c_to_s, ms);
1853
343k
  }
1854
357k
      }
1855
1856
627k
      ndpi_data_add_value(flow->pktlen_c_to_s, rawsize);
1857
627k
      flow->src2dst_packets++, flow->src2dst_bytes += rawsize, flow->src2dst_goodput_bytes += payload_len;
1858
627k
      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
627k
    } else {
1865
173k
      if(flow->dst2src_last_pkt_time.tv_sec && (!begin_or_end_tcp)) {
1866
113k
  ndpi_timer_sub(&when, &flow->dst2src_last_pkt_time, &tdiff);
1867
1868
113k
  if(flow->iat_s_to_c) {
1869
113k
    u_int64_t ms = ndpi_timeval_to_milliseconds(tdiff);
1870
1871
113k
    ndpi_data_add_value(flow->iat_s_to_c, ms);
1872
113k
  }
1873
113k
      }
1874
173k
      ndpi_data_add_value(flow->pktlen_s_to_c, rawsize);
1875
173k
      flow->dst2src_packets++, flow->dst2src_bytes += rawsize, flow->dst2src_goodput_bytes += payload_len;
1876
173k
      flow->risk &= ~(1ULL << NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */
1877
173k
      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
173k
    }
1884
1885
801k
#ifndef DIRECTION_BINS
1886
801k
    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
624k
  ndpi_inc_bin(&flow->payload_len_bin, plen2slot(payload_len), 1);
1892
624k
    }
1893
801k
#endif
1894
1895
801k
    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
801k
    if(enable_flow_stats) {
1901
      /* Update BD, distribution and mean. */
1902
801k
      ndpi_flow_update_byte_count(flow, payload, payload_len, src_to_dst_direction);
1903
801k
      ndpi_flow_update_byte_dist_mean_var(flow, payload, payload_len, src_to_dst_direction);
1904
      /* Update SPLT scores for first 32 packets. */
1905
801k
      if((flow->entropy->src2dst_pkt_count+flow->entropy->dst2src_pkt_count) <= max_num_packets_per_flow) {
1906
801k
        if(flow->bidirectional)
1907
339k
          flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1908
339k
                flow->entropy->dst2src_pkt_len, flow->entropy->dst2src_pkt_time,
1909
339k
                flow->entropy->src2dst_start, flow->entropy->dst2src_start,
1910
339k
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1911
339k
                flow->src2dst_packets, flow->dst2src_packets,
1912
339k
                flow->entropy->src2dst_opackets, flow->entropy->dst2src_opackets,
1913
339k
                flow->entropy->src2dst_l4_bytes, flow->entropy->dst2src_l4_bytes, 1,
1914
339k
                flow->entropy->src2dst_byte_count, flow->entropy->dst2src_byte_count);
1915
462k
  else
1916
462k
    flow->entropy->score = ndpi_classify(flow->entropy->src2dst_pkt_len, flow->entropy->src2dst_pkt_time,
1917
462k
                NULL, NULL, flow->entropy->src2dst_start, flow->entropy->src2dst_start,
1918
462k
                max_num_packets_per_flow, ntohs(flow->src_port), ntohs(flow->dst_port),
1919
462k
                flow->src2dst_packets, 0,
1920
462k
                flow->entropy->src2dst_opackets, 0,
1921
462k
                flow->entropy->src2dst_l4_bytes, 0, 1,
1922
462k
                flow->entropy->src2dst_byte_count, NULL);
1923
801k
      }
1924
801k
    }
1925
1926
801k
    if(flow->first_seen_ms == 0)
1927
225k
      flow->first_seen_ms = time_ms;
1928
1929
801k
    flow->last_seen_ms = time_ms;
1930
1931
    /* Copy packets entropy if num packets count == 10 */
1932
801k
    ndpi_clear_entropy_stats(flow);
1933
    /* Reset IAT reeference times (see https://github.com/ntop/nDPI/pull/1316) */
1934
801k
    if(((flow->src2dst_packets + flow->dst2src_packets) % max_num_packets_per_flow) == 0) {
1935
36.1k
      memset(&flow->src2dst_last_pkt_time, '\0', sizeof(flow->src2dst_last_pkt_time));
1936
36.1k
      memset(&flow->dst2src_last_pkt_time, '\0', sizeof(flow->dst2src_last_pkt_time));
1937
36.1k
      memset(&flow->flow_last_pkt_time, '\0', sizeof(flow->flow_last_pkt_time));
1938
36.1k
    }
1939
1940
801k
    if((human_readeable_string_len != 0) && (!flow->has_human_readeable_strings)) {
1941
555k
      u_int8_t skip = 0;
1942
1943
555k
      if(proto == IPPROTO_TCP &&
1944
321k
   (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1945
257k
    is_ndpi_proto(flow, NDPI_PROTOCOL_SSH))) {
1946
66.5k
  if((flow->src2dst_packets+flow->dst2src_packets) < 10 /* MIN_NUM_ENCRYPT_SKIP_PACKETS */)
1947
17.5k
    skip = 1; /* Skip initial negotiation packets */
1948
66.5k
      }
1949
1950
555k
      if((!skip) && ((flow->src2dst_packets+flow->dst2src_packets) < 100)) {
1951
513k
  if(ndpi_has_human_readable_string((char*)packet, header->caplen,
1952
513k
             human_readeable_string_len,
1953
513k
             flow->human_readeable_string_buffer,
1954
513k
             sizeof(flow->human_readeable_string_buffer)) == 1)
1955
109k
    flow->has_human_readeable_strings = 1;
1956
513k
      }
1957
555k
    } else {
1958
245k
      if(proto == IPPROTO_TCP &&
1959
141k
         (is_ndpi_proto(flow, NDPI_PROTOCOL_TLS) ||
1960
135k
          is_ndpi_proto(flow, NDPI_PROTOCOL_SSH)))
1961
6.42k
  flow->has_human_readeable_strings = 0;
1962
245k
    }
1963
801k
  } else { // flow is NULL
1964
7.75k
    workflow->stats.total_discarded_bytes += header->len;
1965
7.75k
    return(nproto);
1966
7.75k
  }
1967
1968
801k
  if(!flow->detection_completed) {
1969
595k
    struct ndpi_flow_input_info input_info;
1970
1971
595k
    u_int enough_packets =
1972
595k
      ((proto == IPPROTO_UDP && (max_num_udp_dissected_pkts > 0 && flow->src2dst_packets + flow->dst2src_packets >= max_num_udp_dissected_pkts)) ||
1973
595k
       (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
595k
    if(proto == IPPROTO_TCP)
1980
362k
      workflow->stats.dpi_packet_count[0]++;
1981
232k
    else if(proto == IPPROTO_UDP)
1982
221k
      workflow->stats.dpi_packet_count[1]++;
1983
10.7k
    else
1984
10.7k
      workflow->stats.dpi_packet_count[2]++;
1985
595k
    flow->dpi_packets++;
1986
1987
595k
    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
595k
    input_info.in_pkt_dir = NDPI_IN_PKT_DIR_UNKNOWN;
1990
595k
    input_info.seen_flow_beginning = NDPI_FLOW_BEGINNING_UNKNOWN;
1991
595k
    malloc_size_stats = 1;
1992
595k
    flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow,
1993
595k
                  iph ? (uint8_t *)iph : (uint8_t *)iph6,
1994
595k
                  ipsize, time_ms, &input_info);
1995
595k
    if(monitoring_enabled)
1996
595k
      process_ndpi_monitoring_info(flow);
1997
595k
    enough_packets |= ndpi_flow->fail_with_unknown;
1998
595k
    if(enough_packets || (flow->detected_protocol.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)) {
1999
252k
      if((!enough_packets)
2000
249k
   && ndpi_extra_dissection_possible(workflow->ndpi_struct, ndpi_flow))
2001
203k
  ; /* Wait for further metadata */
2002
48.7k
      else {
2003
  /* New protocol detected or give up */
2004
48.7k
  flow->detection_completed = 1;
2005
2006
48.7k
  if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN) {
2007
2.90k
    u_int8_t proto_guessed;
2008
2009
2.90k
    flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow,
2010
2.90k
                &proto_guessed);
2011
2.90k
    if(proto_guessed) workflow->stats.guessed_flow_protocols++;
2012
2.90k
  }
2013
2014
48.7k
  process_ndpi_collected_info(workflow, flow);
2015
48.7k
      }
2016
252k
    }
2017
    /* Let's try to save client-server direction */
2018
595k
    flow->current_pkt_from_client_to_server = input_info.in_pkt_dir;
2019
2020
595k
    malloc_size_stats = 0;
2021
595k
  } else {
2022
206k
    flow->current_pkt_from_client_to_server = NDPI_IN_PKT_DIR_UNKNOWN; /* Unknown */
2023
206k
  }
2024
2025
#if 0
2026
  if(flow->risk != 0) {
2027
    FILE *r = fopen("/tmp/e", "a");
2028
2029
    if(r) {
2030
      fprintf(r, "->>> %u [%08X]\n", flow->risk, flow->risk);
2031
      fclose(r);
2032
    }
2033
  }
2034
#endif
2035
2036
801k
  *flow_risk = flow->risk;
2037
801k
  *flow_ext = flow;
2038
2039
801k
  return(flow->detected_protocol);
2040
809k
}
2041
2042
/* ****************************************************** */
2043
2044
22.8k
int ndpi_is_datalink_supported(int datalink_type) {
2045
  /* Keep in sync with the similar switch in ndpi_workflow_process_packet */
2046
22.8k
  switch(datalink_type) {
2047
7.67k
  case DLT_NULL:
2048
7.68k
  case DLT_PPP_SERIAL:
2049
7.72k
  case DLT_C_HDLC:
2050
7.85k
  case DLT_PPP:
2051
7.85k
#ifdef DLT_IPV4
2052
9.31k
  case DLT_IPV4:
2053
9.31k
#endif
2054
9.31k
#ifdef DLT_IPV6
2055
10.0k
  case DLT_IPV6:
2056
10.0k
#endif
2057
21.4k
  case DLT_EN10MB:
2058
22.1k
  case DLT_LINUX_SLL:
2059
22.2k
  case DLT_IEEE802_11_RADIO:
2060
22.8k
  case DLT_RAW:
2061
22.8k
  case DLT_PPI:
2062
22.8k
  case LINKTYPE_LINUX_SLL2:
2063
22.8k
    return 1;
2064
36
  default:
2065
36
    return 0;
2066
22.8k
  }
2067
22.8k
}
2068
2069
242k
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){
2070
242k
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr)) {
2071
6.35k
    return false;
2072
6.35k
  }
2073
235k
  u_int32_t vxlan_dst_port  = ntohs(4789);
2074
235k
  struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2075
235k
  u_int offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr);
2076
  /**
2077
   * rfc-7348
2078
   *    VXLAN Header:  This is an 8-byte field that has:
2079
2080
    - Flags (8 bits): where the I flag MUST be set to 1 for a valid
2081
      VXLAN Network ID (VNI).  The other 7 bits (designated "R") are
2082
      reserved fields and MUST be set to zero on transmission and
2083
      ignored on receipt.
2084
2085
    - VXLAN Segment ID/VXLAN Network Identifier (VNI): this is a
2086
      24-bit value used to designate the individual VXLAN overlay
2087
      network on which the communicating VMs are situated.  VMs in
2088
      different VXLAN overlay networks cannot communicate with each
2089
      other.
2090
2091
    - Reserved fields (24 bits and 8 bits): MUST be set to zero on
2092
      transmission and ignored on receipt.
2093
         VXLAN Header:
2094
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2095
    |R|R|R|R|I|R|R|R|            Reserved                           |
2096
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2097
    |                VXLAN Network Identifier (VNI) |   Reserved    |
2098
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2099
  */
2100
235k
  if((udp->dest == vxlan_dst_port || udp->source == vxlan_dst_port) &&
2101
7.67k
    (packet[offset] == 0x8) &&
2102
5.81k
    (packet[offset + 1] == 0x0) &&
2103
5.59k
    (packet[offset + 2] == 0x0) &&
2104
5.51k
    (packet[offset + 3] == 0x0) &&
2105
5.38k
    (packet[offset + 7] ==  0x0)) {
2106
5.24k
    return true;
2107
5.24k
    }
2108
230k
  return false;
2109
235k
}
2110
2111
5.24k
static inline u_int ndpi_skip_vxlan(u_int16_t ip_offset, u_int16_t ip_len){
2112
5.24k
  return ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr);
2113
5.24k
}
2114
2115
static uint32_t ndpi_is_valid_gre_tunnel(const struct pcap_pkthdr *header,
2116
                const u_char *packet, const u_int16_t ip_offset,
2117
3.80k
                const u_int16_t ip_len) {
2118
3.80k
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr))
2119
0
    return 0; /* Too short for GRE header*/
2120
3.80k
  uint32_t offset = ip_offset + ip_len;
2121
3.80k
  struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[offset];
2122
3.80k
  offset += sizeof(struct ndpi_gre_basehdr);
2123
  /*
2124
    The GRE flags are encoded in the first two octets.  Bit 0 is the
2125
    most significant bit, bit 15 is the least significant bit.  Bits
2126
    13 through 15 are reserved for the Version field.  Bits 9 through
2127
    12 are reserved for future use and MUST be transmitted as zero.
2128
  */
2129
3.80k
  if(NDPI_GRE_IS_FLAGS(grehdr->flags))
2130
274
    return 0;
2131
3.53k
  if(NDPI_GRE_IS_REC(grehdr->flags))
2132
248
    return 0;
2133
  /*GRE rfc 2890 that update 1701*/
2134
3.28k
  if(NDPI_GRE_IS_VERSION_0(grehdr->flags)) {
2135
1.24k
    if(NDPI_GRE_IS_CSUM(grehdr->flags)) {
2136
279
      if(header->caplen < offset + 4)
2137
18
        return 0;
2138
      /*checksum field and offset field*/
2139
261
      offset += 4;
2140
261
    }
2141
1.23k
    if(NDPI_GRE_IS_KEY(grehdr->flags)) {
2142
279
      if(header->caplen < offset + 4)
2143
18
        return 0;
2144
261
      offset += 4;
2145
261
    }
2146
1.21k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2147
305
      if(header->caplen < offset + 4)
2148
18
        return 0;
2149
287
      offset += 4;
2150
287
    }
2151
2.03k
  } else if(NDPI_GRE_IS_VERSION_1(grehdr->flags)) { /*rfc-2637 section 4.1 enhanced gre*/
2152
1.98k
    if(NDPI_GRE_IS_CSUM(grehdr->flags))
2153
13
      return 0;
2154
1.96k
    if(NDPI_GRE_IS_ROUTING(grehdr->flags))
2155
50
      return 0;
2156
1.91k
    if(!NDPI_GRE_IS_KEY(grehdr->flags))
2157
362
      return 0;
2158
1.55k
    if(NDPI_GRE_IS_STRICT(grehdr->flags))
2159
34
      return 0;
2160
1.52k
    if(grehdr->protocol != NDPI_GRE_PROTO_PPP)
2161
92
      return 0;
2162
    /*key field*/
2163
1.43k
    if(header->caplen < offset + 4)
2164
34
      return 0;
2165
1.39k
    offset += 4;
2166
1.39k
    if(NDPI_GRE_IS_SEQ(grehdr->flags)) {
2167
40
      if(header->caplen < offset + 4)
2168
18
        return 0;
2169
22
      offset += 4;
2170
22
    }
2171
1.37k
    if(NDPI_GRE_IS_ACK(grehdr->flags)) {
2172
27
      if(header->caplen < offset + 4)
2173
12
        return 0;
2174
15
      offset += 4;
2175
15
    }
2176
1.37k
  } else { /*support only ver 0, 1*/
2177
54
    return 0;
2178
54
  }
2179
2.56k
  return offset;
2180
3.28k
}
2181
2182
/* ****************************************************** */
2183
2184
struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow,
2185
                 const struct pcap_pkthdr *header,
2186
                 const u_char *packet,
2187
                 ndpi_risk *flow_risk,
2188
971k
                 struct ndpi_flow_info **flow) {
2189
  /*
2190
   * Declare pointers to packet headers
2191
   */
2192
  /* --- Ethernet header --- */
2193
971k
  const struct ndpi_ethhdr *ethernet;
2194
  /* --- LLC header --- */
2195
971k
  const struct ndpi_llc_header_snap *llc;
2196
2197
  /* --- Cisco HDLC header --- */
2198
971k
  const struct ndpi_chdlc *chdlc;
2199
2200
  /* --- Radio Tap header --- */
2201
971k
  const struct ndpi_radiotap_header *radiotap;
2202
  /* --- Wifi header --- */
2203
971k
  const struct ndpi_wifi_header *wifi;
2204
2205
  /* --- MPLS header --- */
2206
971k
  union mpls {
2207
971k
    uint32_t u32;
2208
971k
    struct ndpi_mpls_header mpls;
2209
971k
  } mpls;
2210
2211
  /** --- IP header --- **/
2212
971k
  struct ndpi_iphdr *iph;
2213
  /** --- IPv6 header --- **/
2214
971k
  struct ndpi_ipv6hdr *iph6;
2215
2216
971k
  struct ndpi_proto nproto;
2217
971k
  ndpi_packet_tunnel tunnel_type = ndpi_no_tunnel;
2218
2219
  /* lengths and offsets */
2220
971k
  u_int32_t eth_offset = 0, dlt;
2221
971k
  u_int16_t radio_len, header_length;
2222
971k
  u_int16_t fc;
2223
971k
  u_int16_t type = 0;
2224
971k
  int wifi_len = 0;
2225
971k
  int pyld_eth_len = 0;
2226
971k
  int check;
2227
971k
  u_int64_t time_ms;
2228
971k
  u_int16_t ip_offset = 0, ip_len;
2229
971k
  u_int16_t frag_off = 0, vlan_id = 0;
2230
971k
  u_int8_t proto = 0, recheck_type;
2231
971k
  u_int8_t ip_ver, ppp_type;
2232
  /*u_int32_t label;*/
2233
2234
  /* counters */
2235
971k
  u_int8_t vlan_packet = 0;
2236
2237
971k
  *flow_risk = 0 /* NDPI_NO_RISK */;
2238
971k
  *flow = NULL;
2239
2240
971k
  memset(&nproto, '\0', sizeof(nproto));
2241
2242
971k
  if((addr_dump_path != NULL) && (workflow->stats.raw_packet_count == 0)) {
2243
    /* At the first packet flush expired cached addresses */
2244
0
    ndpi_cache_address_flush_expired(workflow->ndpi_struct, header->ts.tv_sec);
2245
0
  }
2246
2247
  /* Increment raw packet counter */
2248
971k
  workflow->stats.raw_packet_count++;
2249
2250
  /* setting time */
2251
971k
  time_ms = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION);
2252
2253
  /* safety check */
2254
971k
  if(workflow->last_time > time_ms) {
2255
    /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */
2256
971k
    time_ms = workflow->last_time;
2257
971k
  }
2258
  /* update last time value */
2259
971k
  workflow->last_time = time_ms;
2260
2261
  /*** check Data Link type ***/
2262
971k
  int datalink_type;
2263
2264
#ifdef USE_DPDK
2265
  datalink_type = DLT_EN10MB;
2266
#else
2267
971k
  datalink_type = (int)pcap_datalink(workflow->pcap_handle);
2268
971k
#endif
2269
2270
978k
 datalink_check:
2271
  // 20 for min iph and 8 for min UDP
2272
978k
  if(header->caplen < eth_offset + 28)
2273
91.8k
    return(nproto); /* Too short */
2274
2275
  /* Keep in sync with ndpi_is_datalink_supported() */
2276
886k
  switch(datalink_type) {
2277
158k
  case DLT_NULL:
2278
158k
    if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2)
2279
30.9k
      type = ETH_P_IP;
2280
127k
    else
2281
127k
      type = ETH_P_IPV6;
2282
2283
158k
    ip_offset = 4 + eth_offset;
2284
158k
    break;
2285
2286
    /* Cisco PPP in HDLC-like framing - 50 */
2287
199
  case DLT_PPP_SERIAL:
2288
199
    chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2289
199
    ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2290
199
    type = ntohs(chdlc->proto_code);
2291
199
    break;
2292
2293
    /* Cisco PPP - 9 or 104 */
2294
233
  case DLT_C_HDLC:
2295
1.18k
  case DLT_PPP:
2296
1.18k
    if(packet[0] == 0x0f || packet[0] == 0x8f) {
2297
441
      chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
2298
441
      ip_offset = eth_offset + sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
2299
441
      type = ntohs(chdlc->proto_code);
2300
739
    } else {
2301
739
      ip_offset = eth_offset + 2;
2302
739
      ppp_type = ntohs(*((u_int16_t*)&packet[eth_offset]));
2303
739
      if(ppp_type == 0x0021)
2304
276
        type = ETH_P_IP;
2305
463
      else if(ppp_type == 0x0057)
2306
194
        type = ETH_P_IPV6;
2307
269
      else
2308
269
        return(nproto);
2309
739
    }
2310
911
    break;
2311
2312
911
#ifdef DLT_IPV4
2313
51.2k
  case DLT_IPV4:
2314
51.2k
    type = ETH_P_IP;
2315
51.2k
    ip_offset = eth_offset;
2316
51.2k
    break;
2317
0
#endif
2318
2319
0
#ifdef DLT_IPV6
2320
10.6k
  case DLT_IPV6:
2321
10.6k
    type = ETH_P_IPV6;
2322
10.6k
    ip_offset = eth_offset;
2323
10.6k
    break;
2324
0
#endif
2325
2326
    /* IEEE 802.3 Ethernet - 1 */
2327
642k
  case DLT_EN10MB:
2328
642k
    ethernet = (struct ndpi_ethhdr *) &packet[eth_offset];
2329
642k
    ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset;
2330
642k
    check = ntohs(ethernet->h_proto);
2331
2332
642k
    if(check <= 1500)
2333
17.4k
      pyld_eth_len = check;
2334
624k
    else if(check >= 1536)
2335
624k
      type = check;
2336
2337
642k
    if(pyld_eth_len != 0) {
2338
16.8k
      llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]);
2339
      /* check for LLC layer with SNAP extension */
2340
16.8k
      if(llc->dsap == SNAP || llc->ssap == SNAP) {
2341
244
  type = llc->snap.proto_ID;
2342
244
  ip_offset += + 8;
2343
244
      }
2344
      /* No SNAP extension - Spanning Tree pkt must be discarted */
2345
16.6k
      else if(llc->dsap == BSTP || llc->ssap == BSTP) {
2346
686
  goto v4_warning;
2347
686
      }
2348
16.8k
    }
2349
641k
    break;
2350
2351
    /* Linux Cooked Capture - 113 */
2352
641k
  case DLT_LINUX_SLL:
2353
10.8k
    type = (packet[eth_offset+14] << 8) + packet[eth_offset+15];
2354
10.8k
    ip_offset = 16 + eth_offset;
2355
10.8k
    break;
2356
2357
    /* Linux Cooked Capture v2 - 276 */
2358
194
  case LINKTYPE_LINUX_SLL2:
2359
194
    type = (packet[eth_offset+10] << 8) + packet[eth_offset+11];
2360
194
    ip_offset = 20 + eth_offset;
2361
194
    break;
2362
2363
    /* Radiotap link-layer - 127 */
2364
2.51k
  case DLT_IEEE802_11_RADIO:
2365
2.51k
    radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset];
2366
2.51k
    radio_len = radiotap->len;
2367
2368
    /* Check Bad FCS presence */
2369
2.51k
    if((radiotap->flags & BAD_FCS) == BAD_FCS) {
2370
208
      workflow->stats.total_discarded_bytes +=  header->len;
2371
208
      return(nproto);
2372
208
    }
2373
2374
2.30k
    if(header->caplen < (eth_offset + radio_len + sizeof(struct ndpi_wifi_header)))
2375
446
      return(nproto);
2376
2377
    /* Calculate 802.11 header length (variable) */
2378
1.85k
    wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len);
2379
1.85k
    fc = wifi->fc;
2380
2381
    /* check wifi data presence */
2382
1.85k
    if(FCF_TYPE(fc) == WIFI_DATA) {
2383
1.61k
      if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) ||
2384
996
   (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc)))
2385
1.02k
  wifi_len = 26; /* + 4 byte fcs */
2386
1.61k
    } else   /* no data frames */
2387
246
      return(nproto);
2388
2389
    /* Check ether_type from LLC */
2390
1.61k
    if(header->caplen < (eth_offset + wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap)))
2391
1.01k
      return(nproto);
2392
600
    llc = (struct ndpi_llc_header_snap*)(packet + eth_offset + wifi_len + radio_len);
2393
600
    if(llc->dsap == SNAP)
2394
19
      type = ntohs(llc->snap.proto_ID);
2395
2396
    /* Set IP header offset */
2397
600
    ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset;
2398
600
    break;
2399
2400
8.77k
  case DLT_RAW:
2401
8.77k
    ip_offset = eth_offset;
2402
    /* Heuristic: no explicit field with next protocol */
2403
8.77k
    ip_ver = (packet[ip_offset] & 0xF0) >> 4;
2404
8.77k
    if(ip_ver == 4)
2405
6.14k
      type = ETH_P_IP;
2406
2.62k
    else if(ip_ver == 6)
2407
2.20k
      type = ETH_P_IPV6;
2408
424
    else
2409
424
      return(nproto);
2410
2411
8.35k
    break;
2412
2413
8.35k
  case DLT_PPI:
2414
277
    header_length = le16toh(*(u_int16_t *)&packet[eth_offset + 2]);
2415
277
    dlt = le32toh(*(u_int32_t *)&packet[eth_offset + 4]);
2416
277
    if(dlt != DLT_EN10MB) /* Handle only standard ethernet, for the time being */
2417
206
      return(nproto);
2418
71
    datalink_type = DLT_EN10MB;
2419
71
    eth_offset += header_length;
2420
71
    goto datalink_check;
2421
2422
0
  default:
2423
    /*
2424
     * We shoudn't be here, because we already checked that this datalink is supported.
2425
     * Should ndpi_is_datalink_supported() be updated?
2426
     */
2427
0
    printf("Unknown datalink %d\n", datalink_type);
2428
0
    return(nproto);
2429
886k
  }
2430
2431
890k
 ether_type_check:
2432
890k
  recheck_type = 0;
2433
2434
  /* check ether type */
2435
890k
  switch(type) {
2436
6.76k
  case ETH_P_VLAN:
2437
6.76k
    if(ip_offset+4 >= (int)header->caplen)
2438
20
      return(nproto);
2439
6.74k
    vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2440
6.74k
    type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2441
6.74k
    ip_offset += 4;
2442
6.74k
    vlan_packet = 1;
2443
2444
    // double tagging for 802.1Q
2445
8.59k
    while((type == 0x8100) && (((bpf_u_int32)ip_offset+4) < header->caplen)) {
2446
1.85k
      vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
2447
1.85k
      type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
2448
1.85k
      ip_offset += 4;
2449
1.85k
    }
2450
6.74k
    recheck_type = 1;
2451
6.74k
    break;
2452
2453
97
  case ETH_P_MPLS_UNI:
2454
280
  case ETH_P_MPLS_MULTI:
2455
280
    if(ip_offset+4 >= (int)header->caplen)
2456
35
      return(nproto);
2457
245
    mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2458
245
    mpls.u32 = ntohl(mpls.u32);
2459
245
    workflow->stats.mpls_count++;
2460
245
    type = ETH_P_IP, ip_offset += 4;
2461
2462
1.73k
    while(!mpls.mpls.s && (((bpf_u_int32)ip_offset) + 4 < header->caplen)) {
2463
1.48k
      mpls.u32 = *((uint32_t *) &packet[ip_offset]);
2464
1.48k
      mpls.u32 = ntohl(mpls.u32);
2465
1.48k
      ip_offset += 4;
2466
1.48k
    }
2467
245
    recheck_type = 1;
2468
245
    break;
2469
2470
913
  case ETH_P_PPPoE:
2471
913
    workflow->stats.pppoe_count++;
2472
913
    type = ETH_P_IP;
2473
913
    ip_offset += 8;
2474
913
    recheck_type = 1;
2475
913
    break;
2476
2477
681k
  case ETH_P_IP:
2478
850k
  case ETH_P_IPV6:
2479
    /* Good let's keep decoding */
2480
850k
    break;
2481
2482
31.8k
  default:
2483
31.8k
    return(nproto);
2484
890k
  }
2485
2486
858k
  if(recheck_type)
2487
7.90k
    goto ether_type_check;
2488
2489
850k
  workflow->stats.vlan_count += vlan_packet;
2490
2491
854k
 iph_check:
2492
  /* Check and set IP header size and total packet length */
2493
854k
  if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2494
2.19k
    return(nproto); /* Too short for next IP header*/
2495
2496
852k
  iph = (struct ndpi_iphdr *) &packet[ip_offset];
2497
2498
  /* just work on Ethernet packets that contain IP */
2499
852k
  if(type == ETH_P_IP && header->caplen >= ip_offset) {
2500
682k
    frag_off = ntohs(iph->frag_off);
2501
2502
682k
    proto = iph->protocol;
2503
682k
    if(header->caplen < header->len) {
2504
94.3k
      static u_int8_t cap_warning_used = 0;
2505
2506
94.3k
      if(cap_warning_used == 0) {
2507
1
  if(!workflow->prefs.quiet_mode)
2508
1
    LOG(NDPI_LOG_DEBUG,
2509
1
       "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
2510
1
  cap_warning_used = 1;
2511
1
      }
2512
94.3k
    }
2513
682k
  }
2514
2515
852k
  if(iph->version == IPVERSION) {
2516
763k
    ip_len = ((u_int16_t)iph->ihl * 4);
2517
763k
    iph6 = NULL;
2518
2519
763k
    if(iph->protocol == IPPROTO_IPV6
2520
762k
       || iph->protocol == NDPI_IPIP_PROTOCOL_TYPE
2521
763k
       ) {
2522
947
      ip_offset += ip_len;
2523
947
      if(ip_len > 0)
2524
909
        goto iph_check;
2525
947
    }
2526
2527
762k
    if((frag_off & 0x1FFF) != 0) {
2528
14.7k
      static u_int8_t ipv4_frags_warning_used = 0;
2529
14.7k
      workflow->stats.fragmented_count++;
2530
2531
14.7k
      if(ipv4_frags_warning_used == 0) {
2532
1
  if(!workflow->prefs.quiet_mode)
2533
1
    LOG(NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
2534
1
  ipv4_frags_warning_used = 1;
2535
1
      }
2536
2537
14.7k
      workflow->stats.total_discarded_bytes +=  header->len;
2538
14.7k
      return(nproto);
2539
14.7k
    }
2540
762k
  } else if(iph->version == 6) {
2541
77.8k
    if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2542
529
      return(nproto); /* Too short for IPv6 header*/
2543
2544
77.3k
    iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2545
77.3k
    proto = iph6->ip6_hdr.ip6_un1_nxt;
2546
77.3k
    ip_len = ntohs(iph6->ip6_hdr.ip6_un1_plen);
2547
2548
77.3k
    if(header->caplen < (ip_offset + sizeof(struct ndpi_ipv6hdr) + ntohs(iph6->ip6_hdr.ip6_un1_plen)))
2549
1.46k
      return(nproto); /* Too short for IPv6 payload*/
2550
2551
75.8k
    const u_int8_t *l4ptr = (((const u_int8_t *) iph6) + sizeof(struct ndpi_ipv6hdr));
2552
75.8k
    u_int16_t ipsize = header->caplen - ip_offset;
2553
2554
75.8k
    if(ndpi_handle_ipv6_extension_headers(ipsize - sizeof(struct ndpi_ipv6hdr), &l4ptr, &ip_len, &proto) != 0) {
2555
1.60k
      return(nproto);
2556
1.60k
    }
2557
2558
74.2k
    if(proto == IPPROTO_IPV6
2559
74.0k
       || proto == NDPI_IPIP_PROTOCOL_TYPE
2560
74.2k
       ) {
2561
798
      if(l4ptr > packet) { /* Better safe than sorry */
2562
798
        ip_offset = (l4ptr - packet);
2563
798
        goto iph_check;
2564
798
      }
2565
798
    }
2566
2567
73.4k
    iph = NULL;
2568
73.4k
  } else {
2569
11.1k
    static u_int8_t ipv4_warning_used = 0;
2570
2571
13.6k
  v4_warning:
2572
13.6k
    if(ipv4_warning_used == 0) {
2573
1
      if(!workflow->prefs.quiet_mode)
2574
1
        LOG(NDPI_LOG_DEBUG,
2575
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");
2576
1
      ipv4_warning_used = 1;
2577
1
    }
2578
2579
13.6k
    workflow->stats.total_discarded_bytes +=  header->len;
2580
13.6k
    return(nproto);
2581
11.1k
  }
2582
2583
821k
  if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) {
2584
263k
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr))
2585
216
      return(nproto); /* Too short for UDP header*/
2586
263k
    else {
2587
263k
      struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
2588
263k
      u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest);
2589
2590
263k
      if(((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) &&
2591
19.0k
         (ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 8 /* Minimum GTPv1 header len */ < header->caplen)) {
2592
  /* Check if it's GTPv1 */
2593
18.8k
  u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2594
18.8k
  u_int8_t flags = packet[offset];
2595
18.8k
  u_int8_t message_type = packet[offset+1];
2596
18.8k
  u_int8_t exts_parsing_error = 0;
2597
2598
18.8k
  if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) &&
2599
10.6k
     (message_type == 0xFF /* T-PDU */)) {
2600
2601
10.3k
    offset += 8; /* GTPv1 header len */
2602
10.3k
    if(flags & 0x07)
2603
8.48k
      offset += 4; /* sequence_number + pdu_number + next_ext_header fields */
2604
    /* Extensions parsing */
2605
10.3k
    if(flags & 0x04) {
2606
1.20k
      unsigned int ext_length = 0;
2607
2608
2.04k
      while(offset < header->caplen) {
2609
1.30k
        ext_length = packet[offset] << 2;
2610
1.30k
        offset += ext_length;
2611
1.30k
        if(offset >= header->caplen || ext_length == 0) {
2612
207
          exts_parsing_error = 1;
2613
207
          break;
2614
207
        }
2615
1.09k
        if(packet[offset - 1] == 0)
2616
252
          break;
2617
1.09k
      }
2618
1.20k
    }
2619
2620
10.3k
    if(offset < header->caplen && !exts_parsing_error) {
2621
      /* Ok, valid GTP-U */
2622
2.81k
      tunnel_type = ndpi_gtp_tunnel;
2623
2.81k
      ip_offset = offset;
2624
2.81k
      iph = (struct ndpi_iphdr *)&packet[ip_offset];
2625
2.81k
      if(iph->version == 6) {
2626
90
        iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
2627
90
        iph = NULL;
2628
90
              if(header->caplen < ip_offset + sizeof(struct ndpi_ipv6hdr))
2629
45
          return(nproto);
2630
2.72k
      } else if(iph->version != IPVERSION) {
2631
        // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count);
2632
1.89k
        goto v4_warning;
2633
1.89k
      } else {
2634
831
              if(header->caplen < ip_offset + sizeof(struct ndpi_iphdr))
2635
178
          return(nproto);
2636
831
      }
2637
2.81k
    }
2638
10.3k
  }
2639
244k
      } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) {
2640
  /* https://en.wikipedia.org/wiki/TZSP */
2641
734
  if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 4)
2642
41
    return(nproto); /* Too short for TZSP*/
2643
2644
693
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2645
693
  u_int8_t version       = packet[offset];
2646
693
  u_int8_t ts_type       = packet[offset+1];
2647
693
  u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2]));
2648
2649
693
  tunnel_type = ndpi_tzsp_tunnel;
2650
2651
693
  if((version == 1) && (ts_type == 0) && (encapsulates == 1)) {
2652
179
    u_int8_t stop = 0;
2653
2654
179
    offset += 4;
2655
2656
179
    while((!stop) && (offset < header->caplen)) {
2657
155
      u_int8_t tag_type = packet[offset];
2658
155
      u_int8_t tag_len;
2659
2660
155
      switch(tag_type) {
2661
60
      case 0: /* PADDING Tag */
2662
60
        tag_len = 1;
2663
60
        break;
2664
1
      case 1: /* END Tag */
2665
1
        tag_len = 1, stop = 1;
2666
1
        break;
2667
94
      default:
2668
94
        if(offset + 1 >= header->caplen)
2669
18
          return(nproto); /* Invalid packet */
2670
76
        tag_len = packet[offset+1];
2671
76
        break;
2672
155
      }
2673
2674
137
      offset += tag_len;
2675
2676
137
      if(offset >= header->caplen)
2677
18
        return(nproto); /* Invalid packet */
2678
119
      else {
2679
119
        eth_offset = offset;
2680
119
        goto datalink_check;
2681
119
      }
2682
137
    }
2683
179
  }
2684
243k
      } else if((sport == NDPI_CAPWAP_DATA_PORT) || (dport == NDPI_CAPWAP_DATA_PORT)) {
2685
  /* We dissect ONLY CAPWAP traffic */
2686
1.28k
  u_int offset           = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
2687
2688
1.28k
  if((offset+1) < header->caplen) {
2689
1.19k
    uint8_t preamble = packet[offset];
2690
2691
1.19k
    if((preamble & 0x0F) == 0) { /* CAPWAP header */
2692
844
      u_int16_t msg_len = (packet[offset+1] & 0xF8) >> 1;
2693
2694
844
      offset += msg_len;
2695
2696
844
      if((offset + 32 < header->caplen) &&
2697
599
         (packet[offset + 1] == 0x08)) {
2698
        /* IEEE 802.11 Data */
2699
114
        offset += 24;
2700
        /* LLC header is 8 bytes */
2701
114
        type = ntohs((u_int16_t)*((u_int16_t*)&packet[offset+6]));
2702
2703
114
        ip_offset = offset + 8;
2704
2705
114
        tunnel_type = ndpi_capwap_tunnel;
2706
114
        goto iph_check;
2707
114
      }
2708
844
    }
2709
1.19k
  }
2710
242k
      }else if(ndpi_is_valid_vxlan(header, packet, ip_offset, ip_len)){
2711
5.24k
        tunnel_type = ndpi_vxlan_tunnel;
2712
5.24k
        eth_offset = ndpi_skip_vxlan(ip_offset, ip_len);
2713
5.24k
        goto datalink_check;
2714
5.24k
      }
2715
263k
    }
2716
557k
  } else if(workflow->prefs.decode_tunnels && (proto == IPPROTO_GRE)) {
2717
3.91k
    if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr))
2718
113
      return(nproto); /* Too short for GRE header*/
2719
3.80k
    u_int32_t offset = 0;
2720
3.80k
    if((offset = ndpi_is_valid_gre_tunnel(header, packet, ip_offset, ip_len))) {
2721
2.56k
      tunnel_type = ndpi_gre_tunnel;
2722
2.56k
      struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[ip_offset + ip_len];
2723
2.56k
      if(grehdr->protocol == ntohs(ETH_P_IP) || grehdr->protocol == ntohs(ETH_P_IPV6)) {
2724
329
        ip_offset = offset;
2725
329
        goto iph_check;
2726
2.23k
      } else if(grehdr->protocol ==  NDPI_GRE_PROTO_PPP) {  // ppp protocol
2727
1.36k
        ip_offset = offset + NDPI_PPP_HDRLEN;
2728
1.36k
        goto iph_check;
2729
1.36k
      } else {
2730
865
        eth_offset = offset;
2731
865
        goto datalink_check;
2732
865
      }
2733
2.56k
    } else {
2734
1.24k
      return(nproto);
2735
1.24k
    }
2736
3.80k
  }
2737
2738
  /* process the packet */
2739
809k
  return(packet_processing(workflow, time_ms, vlan_id, tunnel_type, iph, iph6,
2740
809k
         header->caplen - ip_offset,
2741
809k
         header->caplen, header, packet, header->ts,
2742
809k
         flow_risk, flow));
2743
821k
}
2744
2745
/* *********************************************** */
2746
2747
#ifdef USE_DPDK
2748
2749
#include <rte_version.h>
2750
#include <rte_ether.h>
2751
2752
static const struct rte_eth_conf port_conf_default = {
2753
#if(RTE_VERSION < RTE_VERSION_NUM(19, 8, 0, 0))
2754
                  .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
2755
#else
2756
                  .rxmode = { .max_rx_pkt_len = RTE_ETHER_MAX_LEN }
2757
#endif
2758
};
2759
2760
/* ************************************ */
2761
2762
int dpdk_port_init(int port, struct rte_mempool *mbuf_pool) {
2763
  struct rte_eth_conf port_conf = port_conf_default;
2764
  const u_int16_t rx_rings = 1, tx_rings = 1;
2765
  int retval;
2766
  u_int16_t q;
2767
2768
  /* 1 RX queue */
2769
  retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
2770
2771
  if(retval != 0)
2772
    return retval;
2773
2774
  for(q = 0; q < rx_rings; q++) {
2775
    retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL, mbuf_pool);
2776
    if(retval < 0)
2777
      return retval;
2778
  }
2779
2780
  for(q = 0; q < tx_rings; q++) {
2781
    retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, rte_eth_dev_socket_id(port), NULL);
2782
    if(retval < 0)
2783
      return retval;
2784
  }
2785
2786
  retval = rte_eth_dev_start(port);
2787
2788
  if(retval < 0)
2789
    return retval;
2790
2791
  rte_eth_promiscuous_enable(port);
2792
2793
  return 0;
2794
}
2795
2796
int dpdk_port_deinit(int port) {
2797
  rte_eth_dev_stop(port);
2798
  rte_eth_dev_close(port);
2799
  return 0;
2800
}
2801
2802
#endif