Coverage Report

Created: 2024-02-25 06:37

/src/ntopng/include/Flow.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * (C) 2013-24 - ntop.org
4
 *
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 *
20
 */
21
22
#ifndef _FLOW_H_
23
#define _FLOW_H_
24
25
#include "ntop_includes.h"
26
27
typedef struct {
28
  u_int32_t pktFrag;
29
} IPPacketStats;
30
31
typedef struct {
32
  u_int64_t last, next;
33
} TCPSeqNum;
34
35
class FlowAlert;
36
class FlowCheck;
37
38
class Flow : public GenericHashEntry {
39
 private:
40
  int32_t iface_index; /* Interface index on which this flow has been first observed */
41
  Host *cli_host, *srv_host;
42
  IpAddress *cli_ip_addr, *srv_ip_addr;
43
  ICMPinfo *icmp_info;
44
  ndpi_confidence_t ndpi_confidence;
45
  u_int32_t privateFlowId /* Used to store specific flow info such as DNS
46
                             TransactionId */
47
      ;
48
  u_int8_t cli2srv_tos, srv2cli_tos; /* RFC 2474, 3168 */
49
  u_int16_t cli_port, srv_port;
50
  u_int16_t vlanId;
51
  u_int32_t vrfId;
52
  u_int32_t srcAS, dstAS, prevAdjacentAS, nextAdjacentAS;
53
  u_int32_t protocolErrorCode;
54
  u_int8_t protocol, src2dst_tcp_flags, dst2src_tcp_flags, flow_verdict;
55
  u_int16_t flow_score;
56
  u_int8_t view_cli_mac[6], view_srv_mac[6];
57
  struct ndpi_flow_struct *ndpiFlow;
58
  ndpi_risk ndpi_flow_risk_bitmap;
59
  /* The bitmap of all possible flow alerts set by FlowCheck subclasses.
60
     When no alert is set, the flow is in flow_alert_normal.
61
62
     A flow can have multiple alerts but at most ONE of its alerts is
63
     predominant of a flow, which is written into `predominant_alert`.
64
  */
65
  Bitmap128 alerts_map;
66
  FlowAlertType predominant_alert;   /* This is the predominant alert */
67
  u_int16_t predominant_alert_score; /* The score associated to the predominant alert */
68
  FlowSource flow_source;
69
  
70
  struct {
71
    u_int8_t is_cli_attacker : 1, is_cli_victim : 1, is_srv_attacker : 1,
72
        is_srv_victim : 1, auto_acknowledge : 1;
73
  } predominant_alert_info;
74
75
  char *json_protocol_info, *riskInfo, *end_reason;
76
77
  /* Calculate the entropy on the first MAX_ENTROPY_BYTES bytes */
78
  struct {
79
    struct ndpi_analyze_struct *c2s, *s2c;
80
  } initial_bytes_entropy;
81
82
  u_int32_t hash_entry_id; /* Uniquely identify this Flow inside the flows_hash
83
                              hash table */
84
85
  u_int16_t detection_completed : 1, extra_dissection_completed : 1,
86
      twh_over : 1, twh_ok : 1, dissect_next_http_packet : 1, passVerdict : 1,
87
      flow_dropped_counts_increased : 1, quota_exceeded : 1, swap_done : 1,
88
      swap_requested : 1, has_malicious_cli_signature : 1,
89
      has_malicious_srv_signature : 1, src2dst_tcp_zero_window : 1,
90
      dst2src_tcp_zero_window : 1, non_zero_payload_observed : 1,
91
      is_periodic_flow : 1;
92
93
  ndpi_multimedia_flow_type rtp_stream_type;
94
#ifdef ALERTED_FLOWS_DEBUG
95
  bool iface_alert_inc, iface_alert_dec;
96
#endif
97
#ifdef NTOPNG_PRO
98
  bool ingress2egress_direction;
99
  bool lateral_movement;
100
  PeriodicityStatus periodicity_status;
101
#ifndef HAVE_NEDGE
102
  FlowProfile *trafficProfile;
103
#else
104
  u_int8_t routing_table_id;
105
  u_int16_t cli2srv_in, cli2srv_out, srv2cli_in, srv2cli_out;
106
  L7PolicySource_t cli_quota_source, srv_quota_source;
107
#endif
108
  CounterTrend throughputTrend, goodputTrend, thptRatioTrend;
109
#endif
110
  char *ndpiAddressFamilyProtocol;
111
  ndpi_protocol ndpiDetectedProtocol;
112
  char *ndpiFlowRiskName;
113
  custom_app_t custom_app;
114
115
  struct {
116
    bool alertTriggered;
117
    u_int8_t score;
118
    char *msg;
119
  } customFlowAlert;
120
  json_object *json_info;
121
  ndpi_serializer *tlv_info;
122
  ndpi_confidence_t confidence;
123
  char *host_server_name, *bt_hash;
124
  IEC104Stats *iec104;
125
#ifdef NTOPNG_PRO
126
  ModbusStats *modbus;
127
#endif
128
  char *suspicious_dga_domain; /* Stores the suspicious DGA domain for flows
129
                                  with NDPI_SUSPICIOUS_DGA_DOMAIN */
130
  OSType operating_system;
131
#ifdef HAVE_NEDGE
132
  u_int32_t last_conntrack_update;
133
  u_int32_t marker;
134
#endif
135
  struct {
136
    char *source;
137
    json_object *json;
138
  } external_alert;
139
  bool
140
      trigger_immediate_periodic_update; /* needed to process external alerts */
141
  time_t next_call_periodic_update; /* The time at which the periodic lua script
142
                                       on this flow shall be called */
143
144
  /* Flow payload */
145
  u_int16_t flow_payload_len;
146
  char *flow_payload;
147
148
  union {
149
    struct {
150
      char *last_url, *last_user_agent, *last_server;
151
      ndpi_http_method last_method;
152
      u_int16_t last_return_code;
153
    } http;
154
155
    struct {
156
      char *last_query;
157
      char *last_query_shadow;
158
      time_t
159
          last_query_update_time; /* The time when the last query was updated */
160
      u_int16_t last_query_type;
161
      u_int16_t last_return_code;
162
    } dns;
163
164
    struct {
165
      char *name, *name_txt, *ssid;
166
      char *answer;
167
    } mdns;
168
169
    struct {
170
      char *location;
171
    } ssdp;
172
173
    struct {
174
      char *name;
175
    } netbios;
176
177
    struct {
178
      char *name;
179
    } dhcp;
180
181
    struct {
182
      char *client_signature, *server_signature;
183
      struct {
184
        /* https://engineering.salesforce.com/open-sourcing-hassh-abed3ae5044c
185
         */
186
        char *client_hash, *server_hash;
187
      } hassh;
188
    } ssh;
189
190
    struct {
191
      u_int16_t tls_version;
192
      u_int32_t notBefore, notAfter;
193
      char *client_alpn, *client_tls_supported_versions, *issuerDN, *subjectDN;
194
      char *client_requested_server_name, *server_names;
195
      /* Certificate dissection */
196
      struct {
197
        /* https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
198
         */
199
        char *client_hash, *server_hash;
200
        u_int16_t server_cipher;
201
        ndpi_cipher_weakness server_unsafe_cipher;
202
      } ja3;
203
204
      struct {
205
        char *client_hash;
206
      } ja4;
207
    } tls;
208
209
    struct {
210
      struct {
211
        u_int8_t icmp_type, icmp_code;
212
      } cli2srv, srv2cli;
213
      u_int16_t max_icmp_payload_size;
214
215
      struct {
216
        float min_entropy, max_entropy;
217
      } client_to_server;
218
    } icmp;
219
220
    struct {
221
      char * currency;
222
    } mining;
223
224
    struct {
225
      char * mail_from;
226
      char * rcpt_to;
227
    } smtp;
228
    
229
  } protos;
230
231
  struct {
232
    u_int32_t device_ip;
233
    u_int32_t in_index, out_index;
234
    u_int16_t observation_point_id;
235
  } flow_device;
236
237
  /* eBPF Information */
238
  ParsedeBPF *ebpf;
239
240
  /* Stats */
241
  FlowTrafficStats stats;
242
243
  /* IP stats */
244
  IPPacketStats ip_stats_s2d, ip_stats_d2s;
245
246
  /* TCP stats */
247
  TCPSeqNum tcp_seq_s2d, tcp_seq_d2s;
248
  u_int16_t cli2srv_window, srv2cli_window;
249
250
  struct timeval synTime, synAckTime,
251
      ackTime;                    /* network Latency (3-way handshake) */
252
  struct timeval clientNwLatency; /* The RTT/2 between the client and nprobe */
253
  struct timeval serverNwLatency; /* The RTT/2 between nprobe and the server */
254
  struct timeval c2sFirstGoodputTime;
255
  float rttSec, applLatencyMsec;
256
257
  InterarrivalStats *cli2srvPktTime, *srv2cliPktTime;
258
259
  /* Counter values at last host update */
260
  struct {
261
    PartializableFlowTrafficStats *partial;
262
    PartializableFlowTrafficStats delta;
263
    time_t first_seen, last_seen;
264
    bool in_progress; /* Set to true when the flow is enqueued to be dumped */
265
  } last_db_dump;
266
267
  /* Lazily initialized and used by a possible view interface */
268
  ViewInterfaceFlowStats *viewFlowStats;
269
270
  /* Partial used to periodically update stats out of flows */
271
  PartializableFlowTrafficStats *periodic_stats_update_partial;
272
273
#ifdef HAVE_NEDGE
274
  struct {
275
    struct {
276
      TrafficShaper *ingress, *egress;
277
    } cli2srv;
278
279
    struct {
280
      TrafficShaper *ingress, *egress;
281
    } srv2cli;
282
  } flowShaperIds;
283
#endif
284
  struct timeval last_update_time;
285
286
  float top_bytes_thpt, top_goodput_bytes_thpt, top_pkts_thpt;
287
  float bytes_thpt_cli2srv, goodput_bytes_thpt_cli2srv;
288
  float bytes_thpt_srv2cli, goodput_bytes_thpt_srv2cli;
289
  float pkts_thpt_cli2srv, pkts_thpt_srv2cli;
290
  ValueTrend bytes_thpt_trend, goodput_bytes_thpt_trend, pkts_thpt_trend;
291
292
  /*
293
     IMPORTANT NOTE
294
295
     if you add a new 'directional' field such as cliX and serverX
296
     you need to handle it in the Flow::swap() method
297
  */
298
299
  void deferredInitialization();
300
  char *intoaV4(unsigned int addr, char *buf, u_short bufLen);
301
  void allocDPIMemory();
302
  bool checkTor(char *hostname);
303
  void setBittorrentHash(char *hash);
304
  void updateThroughputStats(float tdiff_msec, u_int32_t diff_sent_packets,
305
                             u_int64_t diff_sent_bytes,
306
                             u_int64_t diff_sent_goodput_bytes,
307
                             u_int32_t diff_rcvd_packets,
308
                             u_int64_t diff_rcvd_bytes,
309
                             u_int64_t diff_rcvd_goodput_bytes);
310
  static void updatePacketStats(InterarrivalStats *stats,
311
                                const struct timeval *when, bool update_iat);
312
  char *printTCPState(char *const buf, u_int buf_len) const;
313
  void update_pools_stats(NetworkInterface *iface, Host *cli_host,
314
                          Host *srv_host, const struct timeval *tv,
315
                          u_int64_t diff_sent_packets,
316
                          u_int64_t diff_sent_bytes,
317
                          u_int64_t diff_rcvd_packets,
318
                          u_int64_t diff_rcvd_bytes) const;
319
  /*
320
    Check (and possibly enqueues) the flow for dump
321
   */
322
  void dumpCheck(time_t t, bool last_dump_before_free);
323
  void updateCliJA3();
324
  void updateCliJA4();
325
  void updateSrvJA3();
326
  void updateHASSH(bool as_client);
327
  void processExtraDissectedInformation();
328
  void processDetectedProtocol(
329
      u_int8_t *payload, u_int16_t payload_len); /* nDPI detected protocol */
330
  void processDetectedProtocolData(); /* nDPI detected protocol data (e.g.,
331
                                         ndpiFlow->host_server_name) */
332
  void setExtraDissectionCompleted();
333
  void setProtocolDetectionCompleted(u_int8_t *payload, u_int16_t payload_len);
334
  void updateProtocol(ndpi_protocol proto_id);
335
  const char *cipher_weakness2str(ndpi_cipher_weakness w) const;
336
  bool get_partial_traffic_stats(PartializableFlowTrafficStats **dst,
337
                                 PartializableFlowTrafficStats *delta,
338
                                 bool *first_partial) const;
339
  void lua_tos(lua_State *vm);
340
  void lua_confidence(lua_State *vm);
341
  void updateEntropy(struct ndpi_analyze_struct *e, u_int8_t *payload,
342
                     u_int payload_len);
343
  void lua_entropy(lua_State *vm);
344
  void luaScore(lua_State *vm);
345
  void luaIEC104(lua_State *vm);
346
  void callFlowUpdate(time_t t);
347
  /*
348
    Method to trigger alerts, synchronous or asynchronous, depending on the last
349
    argument.
350
    - Asynchronous: The alerts bitmap is updated and the predominant alert is
351
    possibly updated. Recipients enqueue is not performed.
352
    - Synchronous:  The alerts bitmap is updated and the predominant alert is
353
    possibly updated. Immediate alert JSON generation and enqueue to the
354
    recipients are performed as well.
355
   */
356
  bool setAlertsBitmap(FlowAlertType alert_type, u_int16_t cli_inc,
357
                       u_int16_t srv_inc, bool async);
358
  void setNormalToAlertedCounters();
359
  /* Decreases scores on both client and server hosts when the flow is being
360
   * destructed */
361
  void decAllFlowScores();
362
  void updateServerPortsStats(Host *server_host, ndpi_protocol *proto);
363
  void updateClientContactedPorts(Host *client, ndpi_protocol *proto);
364
  void updateTCPHostServices(Host *cli_h, Host *srv_h);
365
  void updateUDPHostServices();
366
367
 public:
368
  Flow(NetworkInterface *_iface, int32_t iface_idx,
369
       u_int16_t _vlanId,
370
       u_int16_t _observation_point_id, u_int32_t _private_flow_id,
371
       u_int8_t _protocol, Mac *_cli_mac, IpAddress *_cli_ip,
372
       u_int16_t _cli_port, Mac *_srv_mac, IpAddress *_srv_ip,
373
       u_int16_t _srv_port, const ICMPinfo *const icmp_info, time_t _first_seen,
374
       time_t _last_seen, u_int8_t *_view_cli_mac, u_int8_t *_view_srv_mac);
375
  ~Flow();
376
377
0
  inline Bitmap128 getAlertsBitmap() const { return (alerts_map); }
378
379
  /* Enqueues an alert to all available flow recipients. */
380
  bool enqueueAlertToRecipients(FlowAlert *alert);
381
382
  /*
383
    Called by FlowCheck subclasses to trigger a flow alert. This is an
384
    asynchronous call, faster, but can cause the alert JSON to be generated
385
    after the call. The FlowCheck should implement the buildAlert() method which
386
    is called in the predominant check to actually build the FlowAlert object.
387
   */
388
  bool triggerAlertAsync(FlowAlertType alert_type, u_int16_t cli_score_inc,
389
                         u_int16_t srv_score_inc);
390
391
  /*
392
     Called by FlowCheck subclasses to trigger a flow alert. This is a
393
     syncrhonous call, more expensive, but causes the alert (FlowAlert) to be
394
     immediately enqueued to all recipients.
395
   */
396
  bool triggerAlertSync(FlowAlert *alert, u_int16_t cli_score_inc,
397
                        u_int16_t srv_score_inc);
398
399
  /*
400
    Enqueues the predominant alert of the flow to all available flow recipients.
401
   */
402
  void enqueuePredominantAlert();
403
404
0
  inline void setFlowVerdict(u_int8_t _flow_verdict) {
405
0
    flow_verdict = _flow_verdict;
406
0
  };
407
408
  inline void setPredominantAlert(FlowAlertType alert_type, u_int16_t score);
409
0
  inline FlowAlertType getPredominantAlert() const {
410
0
    return predominant_alert;
411
0
  };
412
0
  inline u_int16_t getPredominantAlertScore() const {
413
0
    return predominant_alert_score;
414
0
  };
415
0
  inline AlertLevel getPredominantAlertSeverity() const {
416
0
    return Utils::mapScoreToSeverity(predominant_alert_score);
417
0
  };
418
5.00k
  inline bool isFlowAlerted() const {
419
5.00k
    return (predominant_alert.id != flow_alert_normal);
420
5.00k
  };
421
422
  void setPredominantAlertInfo(FlowAlert *alert);
423
0
  inline bool isPredominantAlertAutoAck() {
424
0
    return !!predominant_alert_info.auto_acknowledge;
425
0
  };
426
0
  inline u_int8_t isClientAttacker() {
427
0
    return predominant_alert_info.is_cli_attacker;
428
0
  };
429
0
  inline u_int8_t isClientVictim() {
430
0
    return predominant_alert_info.is_cli_victim;
431
0
  };
432
0
  inline u_int8_t isServerAttacker() {
433
0
    return predominant_alert_info.is_srv_attacker;
434
0
  };
435
0
  inline u_int8_t isServerVictim() {
436
0
    return predominant_alert_info.is_srv_victim;
437
0
  };
438
0
  inline char *getProtocolInfo() { return json_protocol_info; };
439
440
  void setProtocolJSONInfo();
441
  void getProtocolJSONInfo(ndpi_serializer *serializer);
442
443
0
  inline char *getJa3CliHash() { return (protos.tls.ja3.client_hash); }
444
0
  inline char *getJa4CliHash() { return (protos.tls.ja4.client_hash); }
445
446
  bool isBlacklistedFlow() const;
447
  bool isBlacklistedClient() const;
448
  bool isBlacklistedServer() const;
449
  struct site_categories *getFlowCategory(bool force_categorization);
450
  void freeDPIMemory();
451
  static const ndpi_protocol ndpiUnknownProtocol;
452
  bool isTiny() const;
453
388k
  inline bool isProto(u_int16_t p) const {
454
388k
    return (((ndpiDetectedProtocol.master_protocol == p) ||
455
388k
             (ndpiDetectedProtocol.app_protocol == p))
456
388k
                ? true
457
388k
                : false);
458
388k
  }
459
  bool isTLS() const;
460
0
  inline bool isEncryptedProto() const {
461
0
    return (ndpi_is_encrypted_proto(iface->get_ndpi_struct(),
462
0
                                    ndpiDetectedProtocol));
463
0
  }
464
12.7k
  inline bool isSSH() const { return (isProto(NDPI_PROTOCOL_SSH)); }
465
12.6k
  inline bool isMining() const { return (isProto(NDPI_PROTOCOL_MINING));}
466
31.4k
  inline bool isDNS() const { return (isProto(NDPI_PROTOCOL_DNS)); }
467
61
  inline bool isZoomRTP() const {
468
61
    return (isProto(NDPI_PROTOCOL_ZOOM) && (isProto(NDPI_PROTOCOL_RTP) || isProto(NDPI_PROTOCOL_SRTP)) );
469
61
  }
470
15.5k
  inline bool isIEC60870() const { return (isProto(NDPI_PROTOCOL_IEC60870)); }
471
0
  inline bool isModbus()   const { return (isProto(NDPI_PROTOCOL_MODBUS));   }
472
13.0k
  inline bool isMDNS() const { return (isProto(NDPI_PROTOCOL_MDNS)); }
473
12.8k
  inline bool isSSDP() const { return (isProto(NDPI_PROTOCOL_SSDP)); }
474
12.8k
  inline bool isNetBIOS() const { return (isProto(NDPI_PROTOCOL_NETBIOS)); }
475
12.6k
  inline bool isDHCP() const { return (isProto(NDPI_PROTOCOL_DHCP)); }
476
0
  inline bool isNTP() const { return (isProto(NDPI_PROTOCOL_NTP)); }
477
0
  inline bool isSMTPorSMTPS() const {
478
0
    return (isSMTP() || isSMTPS());
479
0
  }
480
12.5k
  inline bool isSMTP() const {
481
12.5k
    return (isProto(NDPI_PROTOCOL_MAIL_SMTP));
482
12.5k
  }
483
0
  inline bool isSMTPS() const {
484
0
    return (isProto(NDPI_PROTOCOL_MAIL_SMTPS));
485
0
  }
486
15.0k
  inline bool isHTTP() const { return (isProto(NDPI_PROTOCOL_HTTP)); }
487
14.0k
  inline bool isHTTP_PROXY() const { return (isProto(NDPI_PROTOCOL_HTTP_PROXY)); }
488
9.17k
  inline bool isICMP() const {
489
9.17k
    return (isProto(NDPI_PROTOCOL_IP_ICMP) || isProto(NDPI_PROTOCOL_IP_ICMPV6));
490
9.17k
  }
491
27
  inline bool isBittorrent() const {
492
27
    return (isProto(NDPI_PROTOCOL_BITTORRENT));
493
27
  }
494
495
#if defined(NTOPNG_PRO)
496
  inline bool isLateralMovement() const { return (lateral_movement); }
497
  inline void setLateralMovement(bool change) { lateral_movement = change; }
498
  PeriodicityStatus getPeriodicity() const { return (periodicity_status); }
499
  inline void setPeriodicity(PeriodicityStatus _periodicity_status) {
500
    periodicity_status = _periodicity_status;
501
  }
502
#endif
503
504
0
  inline bool isCliDeviceAllowedProtocol() const {
505
0
    return !cli_host ||
506
0
           cli_host->getDeviceAllowedProtocolStatus(
507
0
               get_detected_protocol(), true) == device_proto_allowed;
508
0
  }
509
0
  inline bool isSrvDeviceAllowedProtocol() const {
510
0
    return !srv_host ||
511
0
           get_bytes_srv2cli() ==
512
0
               0 /* Server must respond to be considered NOT allowed */
513
0
           || srv_host->getDeviceAllowedProtocolStatus(
514
0
                  get_detected_protocol(), false) == device_proto_allowed;
515
0
  }
516
0
  inline bool isDeviceAllowedProtocol() const {
517
0
    return isCliDeviceAllowedProtocol() && isSrvDeviceAllowedProtocol();
518
0
  }
519
0
  inline u_int16_t getCliDeviceDisallowedProtocol() const {
520
0
    DeviceProtoStatus cli_ps =
521
0
        cli_host->getDeviceAllowedProtocolStatus(get_detected_protocol(), true);
522
0
    return (cli_ps == device_proto_forbidden_app)
523
0
               ? ndpiDetectedProtocol.app_protocol
524
0
               : ndpiDetectedProtocol.master_protocol;
525
0
  }
526
0
  inline u_int16_t getSrvDeviceDisallowedProtocol() const {
527
0
    DeviceProtoStatus srv_ps = srv_host->getDeviceAllowedProtocolStatus(
528
0
        get_detected_protocol(), false);
529
0
    return (srv_ps == device_proto_forbidden_app)
530
0
               ? ndpiDetectedProtocol.app_protocol
531
0
               : ndpiDetectedProtocol.master_protocol;
532
0
  }
533
83
  inline bool isMaskedFlow() const {
534
83
    return (Utils::maskHost(get_cli_ip_addr()->isLocalHost()) ||
535
83
            Utils::maskHost(get_srv_ip_addr()->isLocalHost()));
536
83
  };
537
0
  inline const char *getServerCipherClass() const {
538
0
    return (isTLS() ? cipher_weakness2str(protos.tls.ja3.server_unsafe_cipher)
539
0
                    : NULL);
540
0
  }
541
  char *serialize(bool use_labels = false);
542
  /* Prepares an alert JSON and puts int in the resulting `serializer`. */
543
  void alert2JSON(FlowAlert *alert, ndpi_serializer *serializer);
544
  json_object *flow2JSON();
545
  json_object *flow2es(json_object *flow_object);
546
  void formatECSInterface(json_object *my_object);
547
  void formatECSNetwork(json_object *my_object, const IpAddress *addr);
548
  void formatECSHost(json_object *my_object, bool is_client,
549
                     const IpAddress *addr, Host *host);
550
  void formatECSEvent(json_object *my_object);
551
  void formatECSFlow(json_object *my_object);
552
  void formatSyslogFlow(json_object *my_object);
553
  void formatGenericFlow(json_object *my_object);
554
  void formatECSExtraInfo(json_object *my_object);
555
  void formatECSAppProto(json_object *my_object);
556
  void formatECSObserver(json_object *my_object);
557
558
0
  inline u_int16_t getLowerProtocol() {
559
0
    return (ndpi_get_lower_proto(ndpiDetectedProtocol));
560
0
  }
561
562
0
  inline void updateJA3C(char *j) {
563
0
    if (j && (j[0] != '\0') && (protos.tls.ja3.client_hash == NULL))
564
0
      protos.tls.ja3.client_hash = strdup(j);
565
0
    updateCliJA3();
566
0
  }
567
0
  inline void updateJA3S(char *j) {
568
0
    if (j && (j[0] != '\0') && (protos.tls.ja3.server_hash == NULL))
569
0
      protos.tls.ja3.server_hash = strdup(j);
570
0
    updateSrvJA3();
571
0
  }
572
573
0
  inline void updateJA4C(char *j) {
574
0
    if (j && (j[0] != '\0') && (protos.tls.ja4.client_hash == NULL))
575
0
      protos.tls.ja4.client_hash = strdup(j);
576
0
    updateCliJA4();
577
0
  }
578
579
0
  inline u_int8_t getTcpFlags() const {
580
0
    return (src2dst_tcp_flags | dst2src_tcp_flags);
581
0
  };
582
1.17k
  inline u_int8_t getTcpFlagsCli2Srv() const { return (src2dst_tcp_flags); };
583
0
  inline u_int8_t getTcpFlagsSrv2Cli() const { return (dst2src_tcp_flags); };
584
#ifdef HAVE_NEDGE
585
  bool checkPassVerdict(const struct tm *now);
586
  bool isPassVerdict() const;
587
  inline void setConntrackMarker(u_int32_t marker) { this->marker = marker; }
588
  inline u_int32_t getConntrackMarker() { return (marker); }
589
  void incFlowDroppedCounters();
590
#endif
591
  void setDropVerdict();
592
  u_int32_t getPid(bool client);
593
  u_int32_t getFatherPid(bool client);
594
  u_int32_t get_uid(bool client) const;
595
  char *get_proc_name(bool client);
596
  char *get_user_name(bool client);
597
  u_int32_t getNextTcpSeq(u_int8_t tcpFlags, u_int32_t tcpSeqNum,
598
                          u_int32_t payloadLen);
599
  static double toMs(const struct timeval *t);
600
  void timeval_diff(struct timeval *begin, const struct timeval *end,
601
                    struct timeval *result, u_short divide_by_two);
602
  char *getFlowInfo(char *buf, u_int buf_len, bool isLuaRequest);
603
0
  inline char *getFlowServerInfo() {
604
0
    return (isTLS() && protos.tls.client_requested_server_name)
605
0
               ? protos.tls.client_requested_server_name
606
0
               : host_server_name;
607
0
  }
608
309
  inline char *getBitTorrentHash() { return (bt_hash); };
609
0
  inline void setBTHash(char *h) {
610
0
    if (!h) return;
611
0
    if (bt_hash) free(bt_hash);
612
0
    bt_hash = h;
613
0
  }
614
0
  inline void setServerName(char *v) {
615
0
    if (host_server_name) free(host_server_name);
616
0
    host_server_name = v;
617
0
  }
618
  void updateICMPFlood(const struct bpf_timeval *when, bool src2dst_direction);
619
  void updateDNSFlood(const struct bpf_timeval *when, bool src2dst_direction);
620
  void updateSNMPFlood(const struct bpf_timeval *when, bool src2dst_direction);
621
  void updateTcpFlags(const struct bpf_timeval *when, u_int8_t flags,
622
                      bool src2dst_direction);
623
  void updateTcpWindow(u_int16_t window, bool src2dst_direction);
624
  void updateTcpSeqIssues(const ParsedFlow *pf);
625
  void updateTLS(ParsedFlow *zflow);
626
  void updateDNS(ParsedFlow *zflow);
627
  void updateHTTP(ParsedFlow *zflow);
628
  void updateSuspiciousDGADomain();
629
  static void incTcpBadStats(bool src2dst_direction, Host *cli, Host *srv,
630
                             NetworkInterface *iface, u_int32_t ooo_pkts,
631
                             u_int32_t retr_pkts, u_int32_t lost_pkts,
632
                             u_int32_t keep_alive_pkts);
633
634
  void updateTcpSeqNum(const struct bpf_timeval *when, u_int32_t seq_num,
635
                       u_int32_t ack_seq_num, u_int16_t window, u_int8_t flags,
636
                       u_int16_t payload_len, bool src2dst_direction);
637
638
  void updateSeqNum(time_t when, u_int32_t sN, u_int32_t aN);
639
  void setDetectedProtocol(ndpi_protocol proto_id);
640
  void processPacket(const struct pcap_pkthdr *h, const u_char *ip_packet,
641
                     u_int16_t ip_len, u_int64_t packet_time, u_int8_t *payload,
642
                     u_int16_t payload_len, u_int16_t src_port);
643
  void processDNSPacket(const u_char *ip_packet, u_int16_t ip_len,
644
                        u_int64_t packet_time);
645
  void processIEC60870Packet(bool tx_direction, const u_char *payload,
646
                             u_int16_t payload_len,
647
           const struct pcap_pkthdr *h);
648
#ifdef NTOPNG_PRO
649
  void processModbusPacket(bool is_query, const u_char *payload,
650
         u_int16_t payload_len,
651
         const struct pcap_pkthdr *h);
652
#endif
653
  void endProtocolDissection();
654
0
  inline void setCustomApp(custom_app_t ca) {
655
0
    memcpy(&custom_app, &ca, sizeof(custom_app));
656
0
  };
657
0
  inline custom_app_t getCustomApp() const { return custom_app; };
658
  u_int16_t getStatsProtocol() const;
659
  void setJSONInfo(json_object *json);
660
  void setTLVInfo(ndpi_serializer *tlv);
661
  void incStats(bool cli2srv_direction, u_int pkt_len, u_int8_t *payload,
662
                u_int payload_len, u_int8_t l4_proto, u_int8_t is_fragment,
663
                u_int16_t tcp_flags, const struct timeval *when,
664
                u_int16_t fragment_extra_overhead);
665
  void addFlowStats(bool new_flow, bool cli2srv_direction, u_int in_pkts,
666
                    u_int in_bytes, u_int in_goodput_bytes, u_int out_pkts,
667
                    u_int out_bytes, u_int out_goodput_bytes,
668
                    u_int in_fragments, u_int out_fragments, time_t first_seen,
669
                    time_t last_seen);
670
  void check_swap();
671
672
811
  inline bool isThreeWayHandshakeOK() const { return (twh_ok ? true : false); };
673
191k
  inline bool isDetectionCompleted() const {
674
191k
    return (detection_completed ? true : false);
675
191k
  };
676
7.10k
  inline bool isOneWay() const {
677
7.10k
    return (get_packets() &&
678
7.10k
            (!get_packets_cli2srv() || !get_packets_srv2cli()));
679
7.10k
  };
680
107
  inline bool isBidirectional() const {
681
107
    return (get_packets_cli2srv() && get_packets_srv2cli());
682
107
  };
683
0
  inline bool isRemoteToRemote() const {
684
0
    return (cli_host && srv_host && !cli_host->isLocalHost() &&
685
0
            !srv_host->isLocalHost());
686
0
  };
687
0
  inline bool isLocalToRemote() const {
688
0
    return get_cli_ip_addr()->isLocalHost() &&
689
0
           !get_srv_ip_addr()->isLocalHost();
690
0
  };
691
0
  inline bool isRemoteToLocal() const {
692
0
    return !get_cli_ip_addr()->isLocalHost() &&
693
0
           get_srv_ip_addr()->isLocalHost();
694
0
  };
695
0
  inline bool isLocalToLocal() const {
696
0
    return get_cli_ip_addr()->isLocalHost() && get_srv_ip_addr()->isLocalHost();
697
0
  };
698
0
  inline bool isUnicast() const {
699
0
    return (cli_ip_addr && srv_ip_addr &&
700
0
            !cli_ip_addr->isBroadMulticastAddress() &&
701
0
            !srv_ip_addr->isBroadMulticastAddress());
702
0
  };
703
0
  inline u_int32_t get_cli_ipv4() const {
704
0
    return (cli_host->get_ip()->get_ipv4());
705
0
  };
706
0
  inline u_int32_t get_srv_ipv4() const {
707
0
    return (srv_host->get_ip()->get_ipv4());
708
0
  };
709
28.7k
  inline ndpi_protocol get_detected_protocol() const {
710
28.7k
    return (isDetectionCompleted() ? ndpiDetectedProtocol
711
28.7k
                                   : ndpiUnknownProtocol);
712
28.7k
  };
713
61.1k
  inline struct ndpi_flow_struct *get_ndpi_flow() const { return (ndpiFlow); };
714
0
  inline const struct ndpi_in6_addr *get_cli_ipv6() const {
715
0
    return (cli_host->get_ip()->get_ipv6());
716
0
  };
717
0
  inline const struct ndpi_in6_addr *get_srv_ipv6() const {
718
0
    return (srv_host->get_ip()->get_ipv6());
719
0
  };
720
18.1k
  inline u_int16_t get_cli_port() const { return (ntohs(cli_port)); };
721
10.6k
  inline u_int16_t get_srv_port() const { return (ntohs(srv_port)); };
722
22.4k
  inline u_int16_t get_vlan_id() const { return (vlanId); };
723
91.5k
  inline u_int8_t get_protocol() const { return (protocol); };
724
0
  inline u_int64_t get_bytes() const {
725
0
    return (stats.get_cli2srv_bytes() + stats.get_srv2cli_bytes());
726
0
  };
727
47.1k
  inline u_int64_t get_bytes_cli2srv() const {
728
47.1k
    return (stats.get_cli2srv_bytes());
729
47.1k
  };
730
74.1k
  inline u_int64_t get_bytes_srv2cli() const {
731
74.1k
    return (stats.get_srv2cli_bytes());
732
74.1k
  };
733
0
  inline u_int64_t get_goodput_bytes() const {
734
0
    return (stats.get_cli2srv_goodput_bytes() +
735
0
            stats.get_srv2cli_goodput_bytes());
736
0
  };
737
0
  inline u_int64_t get_goodput_bytes_cli2srv() const {
738
0
    return (stats.get_cli2srv_goodput_bytes());
739
0
  };
740
0
  inline u_int64_t get_goodput_bytes_srv2cli() const {
741
0
    return (stats.get_srv2cli_goodput_bytes());
742
0
  };
743
19.8k
  inline u_int64_t get_packets() const {
744
19.8k
    return (stats.get_cli2srv_packets() + stats.get_srv2cli_packets());
745
19.8k
  };
746
7.21k
  inline u_int32_t get_packets_cli2srv() const {
747
7.21k
    return (stats.get_cli2srv_packets());
748
7.21k
  };
749
7.99k
  inline u_int32_t get_packets_srv2cli() const {
750
7.99k
    return (stats.get_srv2cli_packets());
751
7.99k
  };
752
0
  inline u_int64_t get_partial_bytes() const {
753
0
    return get_partial_bytes_cli2srv() + get_partial_bytes_srv2cli();
754
0
  };
755
0
  inline u_int64_t get_partial_packets() const {
756
0
    return get_partial_packets_cli2srv() + get_partial_packets_srv2cli();
757
0
  };
758
0
  inline u_int64_t get_partial_goodput_bytes() const {
759
0
    return last_db_dump.delta.get_cli2srv_goodput_bytes() +
760
0
           last_db_dump.delta.get_srv2cli_goodput_bytes();
761
0
  };
762
0
  inline u_int64_t get_partial_bytes_cli2srv() const {
763
0
    return last_db_dump.delta.get_cli2srv_bytes();
764
0
  };
765
0
  inline u_int64_t get_partial_bytes_srv2cli() const {
766
0
    return last_db_dump.delta.get_srv2cli_bytes();
767
0
  };
768
0
  inline u_int64_t get_partial_packets_cli2srv() const {
769
0
    return last_db_dump.delta.get_cli2srv_packets();
770
0
  };
771
0
  inline u_int64_t get_partial_packets_srv2cli() const {
772
0
    return last_db_dump.delta.get_srv2cli_packets();
773
0
  };
774
0
  inline void set_dump_in_progress() { last_db_dump.in_progress = true; };
775
0
  inline void set_dump_done() { last_db_dump.in_progress = false; };
776
  bool needsExtraDissection();
777
  bool hasDissectedTooManyPackets();
778
  bool get_partial_traffic_stats_view(PartializableFlowTrafficStats *delta,
779
                                      bool *first_partial);
780
  bool update_partial_traffic_stats_db_dump();
781
6.24k
  inline float get_pkts_thpt() const {
782
6.24k
    return (pkts_thpt_cli2srv + pkts_thpt_srv2cli);
783
6.24k
  };
784
6.24k
  inline float get_bytes_thpt() const {
785
6.24k
    return (bytes_thpt_cli2srv + bytes_thpt_srv2cli);
786
6.24k
  };
787
6.24k
  inline float get_goodput_bytes_thpt() const {
788
6.24k
    return (goodput_bytes_thpt_cli2srv + goodput_bytes_thpt_srv2cli);
789
6.24k
  };
790
0
  inline float get_goodput_ratio() const {
791
0
    return ((float)(100 * get_goodput_bytes()) / ((float)get_bytes() + 1));
792
0
  };
793
0
  inline time_t get_partial_first_seen() const {
794
0
    return (last_db_dump.first_seen);
795
0
  };
796
0
  inline time_t get_partial_last_seen() const {
797
0
    return (last_db_dump.last_seen);
798
0
  };
799
0
  inline char *get_protocol_name() const {
800
0
    return (Utils::l4proto2name(protocol));
801
0
  };
802
803
136k
  inline Host *get_cli_host() const { return (cli_host); };
804
136k
  inline Host *get_srv_host() const { return (srv_host); };
805
73.4k
  inline IpAddress *get_cli_ip_addr() const { return (cli_ip_addr); };
806
70.5k
  inline IpAddress *get_srv_ip_addr() const { return (srv_ip_addr); };
807
0
  inline IpAddress *get_dns_srv_ip_addr() const {
808
0
    return ((get_cli_port() == 53) ? get_cli_ip_addr() : get_srv_ip_addr());
809
0
  };
810
0
  inline IpAddress *get_dhcp_srv_ip_addr() const {
811
0
    return ((get_cli_port() == 67) ? get_cli_ip_addr() : get_srv_ip_addr());
812
0
  };
813
814
0
  inline json_object *get_json_info() const { return (json_info); };
815
0
  inline ndpi_serializer *get_tlv_info() const { return (tlv_info); };
816
4.58k
  inline void setICMPPayloadSize(u_int16_t size) {
817
4.58k
    if (isICMP())
818
4.58k
      protos.icmp.max_icmp_payload_size =
819
4.58k
          max(protos.icmp.max_icmp_payload_size, size);
820
4.58k
  };
821
0
  inline u_int16_t getICMPPayloadSize() const {
822
0
    return (isICMP() ? protos.icmp.max_icmp_payload_size : 0);
823
0
  };
824
0
  inline ICMPinfo *getICMPInfo() const { return (isICMP() ? icmp_info : NULL); }
825
0
  inline ndpi_protocol_breed_t get_protocol_breed() const {
826
0
    return (ndpi_get_proto_breed(
827
0
        iface->get_ndpi_struct(),
828
0
        isDetectionCompleted() ? ndpi_get_upper_proto(ndpiDetectedProtocol)
829
0
                               : NDPI_PROTOCOL_UNKNOWN));
830
0
  };
831
0
  inline const char *get_protocol_breed_name() const {
832
0
    return (ndpi_get_proto_breed_name(iface->get_ndpi_struct(),
833
0
                                      get_protocol_breed()));
834
0
  };
835
104k
  inline ndpi_protocol_category_t get_protocol_category() const {
836
104k
    return (ndpi_get_proto_category(
837
104k
        iface->get_ndpi_struct(),
838
104k
        isDetectionCompleted() ? ndpiDetectedProtocol : ndpiUnknownProtocol));
839
104k
  };
840
0
  inline const char *get_protocol_category_name() const {
841
0
    return (ndpi_category_get_name(iface->get_ndpi_struct(),
842
0
                                   get_protocol_category()));
843
0
  };
844
0
  char *get_detected_protocol_name(char *buf, u_int buf_len) const {
845
0
    return (iface->get_ndpi_full_proto_name(
846
0
        isDetectionCompleted() ? ndpiDetectedProtocol : ndpiUnknownProtocol,
847
0
        buf, buf_len));
848
0
  }
849
0
  static inline ndpi_protocol get_ndpi_unknown_protocol() {
850
0
    return ndpiUnknownProtocol;
851
0
  };
852
853
  /* NOTE: the caller must ensure that the hosts returned by these methods are
854
   * not used concurrently by subinterfaces since hosts are shared between all
855
   * the subinterfaces of the same ViewInterface. */
856
19.9k
  inline Host *getViewSharedClient() {
857
19.9k
    return (viewFlowStats ? viewFlowStats->getViewSharedClient()
858
19.9k
                          : get_cli_host());
859
19.9k
  };
860
19.9k
  inline Host *getViewSharedServer() {
861
19.9k
    return (viewFlowStats ? viewFlowStats->getViewSharedServer()
862
19.9k
                          : get_srv_host());
863
19.9k
  };
864
865
  u_int32_t get_packetsLost();
866
  u_int32_t get_packetsRetr();
867
  u_int32_t get_packetsOOO();
868
869
23.1k
  inline const struct timeval *get_current_update_time() const {
870
23.1k
    return &last_update_time;
871
23.1k
  };
872
  u_int64_t get_current_bytes_cli2srv() const;
873
  u_int64_t get_current_bytes_srv2cli() const;
874
  u_int64_t get_current_goodput_bytes_cli2srv() const;
875
  u_int64_t get_current_goodput_bytes_srv2cli() const;
876
  u_int64_t get_current_packets_cli2srv() const;
877
  u_int64_t get_current_packets_srv2cli() const;
878
879
124k
  inline bool is_swap_requested() const {
880
124k
    return (swap_requested ? true : false);
881
124k
  };
882
970
  inline bool is_swap_done() const { return (swap_done ? true : false); };
883
0
  inline void set_swap_done() { swap_done = 1; };
884
  /*
885
    Returns actual client and server, that is the client and server as
886
    determined after the swap heuristic that has taken place.
887
   */
888
  inline void get_actual_peers(Host **actual_client,
889
58.3k
                               Host **actual_server) const {
890
58.3k
    if (is_swap_requested())
891
8.11k
      *actual_client = get_srv_host(), *actual_server = get_cli_host();
892
50.1k
    else
893
50.1k
      *actual_client = get_cli_host(), *actual_server = get_srv_host();
894
58.3k
  };
895
  bool is_hash_entry_state_idle_transition_ready();
896
  void hosts_periodic_stats_update(NetworkInterface *iface, Host *cli_host,
897
                                   Host *srv_host,
898
                                   PartializableFlowTrafficStats *partial,
899
                                   bool first_partial,
900
                                   const struct timeval *tv);
901
  void periodic_stats_update(const struct timeval *tv);
902
  void set_hash_entry_id(u_int32_t assigned_hash_entry_id);
903
  u_int32_t get_hash_entry_id() const;
904
905
  static char *printTCPflags(u_int8_t flags, char *const buf, u_int buf_len);
906
  char *print(char *buf, u_int buf_len, bool full_report = true) const;
907
908
  u_int32_t key();
909
  static u_int32_t key(Host *cli, u_int16_t cli_port, Host *srv,
910
                       u_int16_t srv_port, u_int16_t vlan_id,
911
                       u_int16_t _observation_point_id, u_int16_t protocol);
912
  void lua(lua_State *vm, AddressTree *ptree, DetailsLevel details_level,
913
           bool asListElement);
914
  void lua_get_min_info(lua_State *vm);
915
  void lua_duration_info(lua_State *vm);
916
  void lua_snmp_info(lua_State *vm);
917
  void lua_device_protocol_allowed_info(lua_State *vm);
918
  void lua_get_tcp_stats(lua_State *vm) const;
919
920
  void lua_get_unicast_info(lua_State *vm) const;
921
  void lua_get_status(lua_State *vm) const;
922
  void lua_get_protocols(lua_State *vm) const;
923
  void lua_get_bytes(lua_State *vm) const;
924
  void lua_get_dir_traffic(lua_State *vm, bool cli2srv) const;
925
  void lua_get_dir_iat(lua_State *vm, bool cli2srv) const;
926
  void lua_get_packets(lua_State *vm) const;
927
  void lua_get_throughput(lua_State *vm) const;
928
  void lua_get_time(lua_State *vm) const;
929
  void lua_get_ip(lua_State *vm, bool client) const;
930
  void lua_get_mac(lua_State *vm, bool client) const;
931
  void lua_get_info(lua_State *vm, bool client) const;
932
  void lua_get_tls_info(lua_State *vm) const;
933
  void lua_get_ssh_info(lua_State *vm) const;
934
  void lua_get_http_info(lua_State *vm) const;
935
  void lua_get_dns_info(lua_State *vm) const;
936
  void lua_get_tcp_info(lua_State *vm) const;
937
  void lua_get_port(lua_State *vm, bool client) const;
938
  void lua_get_geoloc(lua_State *vm, bool client, bool coords,
939
                      bool country_city) const;
940
  void lua_get_risk_info(lua_State *vm);
941
942
  void getInfo(ndpi_serializer *serializer);
943
  void getHTTPInfo(ndpi_serializer *serializer) const;
944
  void getDNSInfo(ndpi_serializer *serializer) const;
945
  void getICMPInfo(ndpi_serializer *serializer) const;
946
  void getTLSInfo(ndpi_serializer *serializer) const;
947
  void getMDNSInfo(ndpi_serializer *serializer) const;
948
  void getNetBiosInfo(ndpi_serializer *serializer) const;
949
  void getSSHInfo(ndpi_serializer *serializer) const;
950
951
  bool equal(const Mac *src_mac, const Mac *dst_mac, const IpAddress *_cli_ip,
952
             const IpAddress *_srv_ip, u_int16_t _cli_port, u_int16_t _srv_port,
953
             u_int16_t _u_int16_t, u_int16_t _observation_point_id,
954
             u_int32_t _private_flow_id, u_int8_t _protocol,
955
             const ICMPinfo *const icmp_info, bool *src2srv_direction) const;
956
  void sumStats(nDPIStats *ndpi_stats, FlowStats *stats);
957
  bool dump(time_t t, bool last_dump_before_free);
958
  bool match(AddressTree *ptree);
959
  bool matchFlowIP(IpAddress *ip, u_int16_t vlan_id);
960
  bool matchFlowVLAN(u_int16_t vlan_id);
961
  bool matchFlowDeviceIP(u_int32_t flow_device_ip);
962
  void dissectHTTP(bool src2dst_direction, char *payload,
963
                   u_int16_t payload_len);
964
  void dissectDNS(bool src2dst_direction, char *payload, u_int16_t payload_len);
965
  void dissectTLS(char *payload, u_int16_t payload_len);
966
  void dissectSSDP(bool src2dst_direction, char *payload,
967
                   u_int16_t payload_len);
968
  void dissectMDNS(u_int8_t *payload, u_int16_t payload_len);
969
  void dissectNetBIOS(u_int8_t *payload, u_int16_t payload_len);
970
  void dissectBittorrent(char *payload, u_int16_t payload_len);
971
  void fillZMQFlowCategory(ndpi_protocol *res);
972
  void setDHCPHostName(const char* name);
973
  inline void setICMP(bool src2dst_direction, u_int8_t icmp_type,
974
4.58k
                      u_int8_t icmp_code, u_int8_t *icmpdata) {
975
4.58k
    if (isICMP()) {
976
4.58k
      if (src2dst_direction)
977
4.50k
        protos.icmp.cli2srv.icmp_type = icmp_type,
978
4.50k
        protos.icmp.cli2srv.icmp_code = icmp_code;
979
83
      else
980
83
        protos.icmp.srv2cli.icmp_type = icmp_type,
981
83
        protos.icmp.srv2cli.icmp_code = icmp_code;
982
      // if(get_cli_host()) get_cli_host()->incICMP(icmp_type, icmp_code,
983
      // src2dst_direction ? true : false, get_srv_host()); if(get_srv_host())
984
      // get_srv_host()->incICMP(icmp_type, icmp_code, src2dst_direction ? false
985
      // : true, get_cli_host());
986
4.58k
    }
987
4.58k
  }
988
0
  inline void getICMP(u_int8_t *_icmp_type, u_int8_t *_icmp_code) {
989
0
    if (isBidirectional())
990
0
      *_icmp_type = protos.icmp.srv2cli.icmp_type,
991
0
      *_icmp_code = protos.icmp.srv2cli.icmp_code;
992
0
    else
993
0
      *_icmp_type = protos.icmp.cli2srv.icmp_type,
994
0
      *_icmp_code = protos.icmp.cli2srv.icmp_code;
995
0
  }
996
0
  inline u_int8_t getICMPType() {
997
0
    if (isICMP()) {
998
0
      return isBidirectional() ? protos.icmp.srv2cli.icmp_type
999
0
                               : protos.icmp.cli2srv.icmp_type;
1000
0
    }
1001
0
1002
0
    return 0;
1003
0
  }
1004
1005
0
  inline bool hasInvalidDNSQueryChars() const {
1006
0
    return (isDNS() && hasRisk(NDPI_INVALID_CHARACTERS));
1007
0
  }
1008
0
  inline bool hasMaliciousSignature(bool as_client) const {
1009
0
    return as_client ? has_malicious_cli_signature
1010
0
                     : has_malicious_srv_signature;
1011
0
  }
1012
1013
  void setRisk(ndpi_risk r);
1014
  void addRisk(ndpi_risk r);
1015
0
  inline ndpi_risk getRiskBitmap() const { return ndpi_flow_risk_bitmap; }
1016
  bool hasRisk(ndpi_risk_enum r) const;
1017
  bool hasRisks() const;
1018
  void clearRisks();
1019
0
  inline void setDGADomain(char *name) {
1020
0
    if (name) {
1021
0
      if (suspicious_dga_domain) free(suspicious_dga_domain);
1022
0
      suspicious_dga_domain = strdup(name);
1023
0
    }
1024
0
  }
1025
0
  inline char *getDGADomain() const {
1026
0
    return (hasRisk(NDPI_SUSPICIOUS_DGA_DOMAIN) && suspicious_dga_domain
1027
0
                ? suspicious_dga_domain
1028
0
                : (char *)"");
1029
0
  }
1030
0
  inline char *getDNSQuery() const {
1031
0
    return (isDNS() ? protos.dns.last_query : (char *)"");
1032
0
  }
1033
  bool setDNSQuery(char *v, bool copy_memory);
1034
0
  inline void setDNSQueryType(u_int16_t t) {
1035
0
    if (isDNS()) {
1036
0
      protos.dns.last_query_type = t;
1037
0
    }
1038
0
  }
1039
0
  inline void setDNSRetCode(u_int16_t c) {
1040
0
    if (isDNS()) {
1041
0
      protos.dns.last_return_code = c;
1042
0
    }
1043
0
  }
1044
1.45k
  inline u_int16_t getLastQueryType() {
1045
1.45k
    return (isDNS() ? protos.dns.last_query_type : 0);
1046
1.45k
  }
1047
403
  inline u_int16_t getDNSRetCode() {
1048
403
    return (isDNS() ? protos.dns.last_return_code : 0);
1049
403
  }
1050
0
  inline char *getHTTPURL() {
1051
0
    return (isHTTP() ? protos.http.last_url : (char *)"");
1052
0
  }
1053
0
  inline void setHTTPURL(char *v) {
1054
0
    if (isHTTP()) {
1055
0
      if (!protos.http.last_url)
1056
0
  protos.http.last_url = v;
1057
0
      else
1058
0
  free(v);
1059
0
    } else {
1060
0
      if (v) free(v);
1061
0
    }
1062
0
  }
1063
0
  inline char *getHTTPUserAgent() {
1064
0
    return (isHTTP() ? protos.http.last_user_agent : (char *)"");
1065
0
  }
1066
0
  inline void setHTTPUserAgent(char *v) {
1067
0
    if (isHTTP()) {
1068
0
      if (!protos.http.last_user_agent)
1069
0
  protos.http.last_user_agent = v;
1070
0
      else
1071
0
  free(v);
1072
0
    } else {
1073
0
      if (v) free(v);
1074
0
    }
1075
0
  }
1076
  void setHTTPMethod(const char *method, ssize_t method_len);
1077
  void setHTTPMethod(ndpi_http_method m);
1078
0
  inline void setHTTPRetCode(u_int16_t c) {
1079
0
    if (isHTTP()) {
1080
0
      protos.http.last_return_code = c;
1081
0
    }
1082
0
  }
1083
0
  inline u_int16_t getHTTPRetCode() const {
1084
0
    return isHTTP() ? protos.http.last_return_code : 0;
1085
0
  };
1086
0
  inline const char *getHTTPMethod() const {
1087
0
    return isHTTP() ? ndpi_http_method2str(protos.http.last_method)
1088
0
                    : (char *)"";
1089
0
  };
1090
1091
  void setExternalAlert(json_object *a);
1092
0
  inline bool hasExternalAlert() const { return external_alert.json != NULL; };
1093
0
  inline json_object *getExternalAlert() { return external_alert.json; };
1094
0
  inline char *getExternalSource() { return external_alert.source; };
1095
  void luaRetrieveExternalAlert(lua_State *vm);
1096
1097
  u_int32_t getSrvTcpIssues();
1098
  u_int32_t getCliTcpIssues();
1099
  double getCliRetrPercentage();
1100
  double getSrvRetrPercentage();
1101
1102
#if defined(NTOPNG_PRO)
1103
#if !defined(HAVE_NEDGE)
1104
  inline void updateProfile() { trafficProfile = iface->getFlowProfile(this); }
1105
#endif
1106
  inline char *get_profile_name() {
1107
    return (
1108
#if !defined(HAVE_NEDGE)
1109
      trafficProfile ? trafficProfile->getName() : 
1110
#endif
1111
      (char *)""
1112
    );
1113
  }
1114
#endif
1115
  /* http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/
1116
   */
1117
0
  inline float getCli2SrvMaxThpt() const {
1118
0
    return (rttSec ? ((float)(cli2srv_window * 8) / rttSec) : 0);
1119
0
  }
1120
0
  inline float getSrv2CliMaxThpt() const {
1121
0
    return (rttSec ? ((float)(srv2cli_window * 8) / rttSec) : 0);
1122
0
  }
1123
1124
26.6k
  inline InterarrivalStats *getCli2SrvIATStats() const {
1125
26.6k
    return cli2srvPktTime;
1126
26.6k
  }
1127
2.38k
  inline InterarrivalStats *getSrv2CliIATStats() const {
1128
2.38k
    return srv2cliPktTime;
1129
2.38k
  }
1130
1131
0
  inline bool isTCP() const { return protocol == IPPROTO_TCP; };
1132
0
  inline bool isTCPEstablished() const {
1133
0
    return (!isTCPClosed() && !isTCPReset() && isThreeWayHandshakeOK());
1134
0
  }
1135
0
  inline bool isTCPConnecting() const {
1136
0
    return (src2dst_tcp_flags == TH_SYN &&
1137
0
            (!dst2src_tcp_flags || (dst2src_tcp_flags == (TH_SYN | TH_ACK))));
1138
0
  }
1139
0
  inline bool isTCPClosed() const {
1140
0
    return (((src2dst_tcp_flags & (TH_SYN | TH_ACK | TH_FIN)) ==
1141
0
             (TH_SYN | TH_ACK | TH_FIN)) &&
1142
0
            ((dst2src_tcp_flags & (TH_SYN | TH_ACK | TH_FIN)) ==
1143
0
             (TH_SYN | TH_ACK | TH_FIN)));
1144
0
  }
1145
0
  inline bool isTCPReset() const {
1146
0
    return (!isTCPClosed() &&
1147
0
            ((src2dst_tcp_flags & TH_RST) || (dst2src_tcp_flags & TH_RST)));
1148
0
  };
1149
0
  inline bool isTCPRefused() const {
1150
0
    return (!isThreeWayHandshakeOK() && (dst2src_tcp_flags & TH_RST) == TH_RST);
1151
0
  };
1152
0
  inline bool isTCPZeroWindow() const {
1153
0
    return (src2dst_tcp_zero_window || dst2src_tcp_zero_window);
1154
0
  };
1155
0
  inline void setVRFid(u_int32_t v) { vrfId = v; }
1156
0
  inline void setSrcAS(u_int32_t v) { srcAS = v; }
1157
0
  inline void setDstAS(u_int32_t v) { dstAS = v; }
1158
0
  inline void setPrevAdjacentAS(u_int32_t v) { prevAdjacentAS = v; }
1159
0
  inline void setNextAdjacentAS(u_int32_t v) { nextAdjacentAS = v; }
1160
1161
10.0k
  inline ViewInterfaceFlowStats *getViewInterfaceFlowStats() {
1162
10.0k
    return (viewFlowStats);
1163
10.0k
  }
1164
1165
0
  inline double getFlowNwLatency(bool client) const {
1166
0
    return client ? Utils::timeval2ms(&clientNwLatency)
1167
0
                  : Utils::timeval2ms(&serverNwLatency);
1168
0
  };
1169
0
  inline void setFlowNwLatency(const struct timeval *const tv, bool client) {
1170
0
    if (client) {
1171
0
      memcpy(&clientNwLatency, tv, sizeof(*tv));
1172
0
      if (cli_host)
1173
0
        cli_host->updateRoundTripTime(Utils::timeval2ms(&clientNwLatency));
1174
0
    } else {
1175
0
      memcpy(&serverNwLatency, tv, sizeof(*tv));
1176
0
      if (srv_host)
1177
0
        srv_host->updateRoundTripTime(Utils::timeval2ms(&serverNwLatency));
1178
0
    }
1179
0
  }
1180
0
  inline void setFlowTcpWindow(u_int16_t window_val, bool client) {
1181
0
    if (client)
1182
0
      cli2srv_window = window_val;
1183
0
    else
1184
0
      srv2cli_window = window_val;
1185
0
  }
1186
14
  inline void setRtt() {
1187
14
    rttSec = ((float)(serverNwLatency.tv_sec + clientNwLatency.tv_sec)) +
1188
14
             ((float)(serverNwLatency.tv_usec + clientNwLatency.tv_usec)) /
1189
14
                 (float)1000000;
1190
14
  }
1191
0
  inline void setFlowApplLatency(float latency_msecs) {
1192
0
    applLatencyMsec = latency_msecs;
1193
0
  }
1194
  inline void setFlowDevice(u_int32_t device_ip, u_int16_t observation_point_id,
1195
0
                            u_int32_t inidx, u_int32_t outidx) {
1196
0
    ObservationPoint *obs_point;
1197
1198
0
    flow_device.device_ip = device_ip,
1199
0
    flow_device.observation_point_id = observation_point_id;
1200
0
    flow_device.in_index = inidx, flow_device.out_index = outidx;
1201
0
    if (cli_host) cli_host->setLastDeviceIp(device_ip);
1202
0
    if (srv_host) srv_host->setLastDeviceIp(device_ip);
1203
1204
0
    if ((obs_point = iface->getObsPoint(observation_point_id, true, true)) !=
1205
0
        NULL)
1206
0
      obs_point->addProbeIp(device_ip);
1207
0
  }
1208
0
  inline u_int32_t getFlowDeviceIP() { return flow_device.device_ip; };
1209
0
  inline u_int16_t getFlowObservationPointId() {
1210
0
    return flow_device.observation_point_id;
1211
0
  };
1212
0
  inline u_int16_t get_observation_point_id() {
1213
0
    return (getFlowObservationPointId());
1214
0
  };
1215
0
  inline u_int32_t getFlowDeviceInIndex() { return flow_device.in_index; };
1216
0
  inline u_int32_t getFlowDeviceOutIndex() { return flow_device.out_index; };
1217
1218
0
  inline const u_int16_t getScore() const { return (flow_score); };
1219
1220
#ifdef HAVE_NEDGE
1221
  inline void setLastConntrackUpdate(u_int32_t when) {
1222
    last_conntrack_update = when;
1223
  }
1224
  bool isNetfilterIdleFlow() const;
1225
1226
  void setPacketsBytes(time_t now, u_int32_t s2d_pkts, u_int32_t d2s_pkts,
1227
                       u_int64_t s2d_bytes, u_int64_t d2s_bytes);
1228
  void getFlowShapers(bool src2dst_direction, TrafficShaper **shaper_ingress,
1229
                      TrafficShaper **shaper_egress) {
1230
    if (src2dst_direction) {
1231
      *shaper_ingress = flowShaperIds.cli2srv.ingress,
1232
      *shaper_egress = flowShaperIds.cli2srv.egress;
1233
    } else {
1234
      *shaper_ingress = flowShaperIds.srv2cli.ingress,
1235
      *shaper_egress = flowShaperIds.srv2cli.egress;
1236
    }
1237
  }
1238
  bool updateDirectionShapers(bool src2dst_direction,
1239
                              TrafficShaper **ingress_shaper,
1240
                              TrafficShaper **egress_shaper);
1241
  void updateFlowShapers(bool first_update = false);
1242
  void recheckQuota(const struct tm *now);
1243
  inline u_int8_t getFlowRoutingTableId() { return (routing_table_id); }
1244
  inline void setIngress2EgressDirection(bool _ingress2egress) {
1245
    ingress2egress_direction = _ingress2egress;
1246
  }
1247
  inline bool isIngress2EgressDirection() { return (ingress2egress_direction); }
1248
#endif
1249
  void housekeep(time_t t);
1250
  void setParsedeBPFInfo(const ParsedeBPF *const _ebpf, bool swap_directions);
1251
0
  inline const ContainerInfo *getClientContainerInfo() const {
1252
0
    return ebpf && ebpf->container_info_set ? &ebpf->src_container_info : NULL;
1253
0
  }
1254
0
  inline const ContainerInfo *getServerContainerInfo() const {
1255
0
    return ebpf && ebpf->container_info_set ? &ebpf->dst_container_info : NULL;
1256
0
  }
1257
0
  inline const ProcessInfo *getClientProcessInfo() const {
1258
0
    return ebpf && ebpf->process_info_set ? &ebpf->src_process_info : NULL;
1259
0
  }
1260
0
  inline const ProcessInfo *getServerProcessInfo() const {
1261
0
    return ebpf && ebpf->process_info_set ? &ebpf->dst_process_info : NULL;
1262
0
  }
1263
0
  inline const TcpInfo *getClientTcpInfo() const {
1264
0
    return ebpf && ebpf->tcp_info_set ? &ebpf->src_tcp_info : NULL;
1265
0
  }
1266
0
  inline const TcpInfo *getServerTcpInfo() const {
1267
0
    return ebpf && ebpf->tcp_info_set ? &ebpf->dst_tcp_info : NULL;
1268
0
  }
1269
1270
0
  inline bool isNotPurged() {
1271
0
    return (getInterface()->isPacketInterface() &&
1272
0
            getInterface()->is_purge_idle_interface() && (!idle()) &&
1273
0
            is_active_entry_now_idle(10 * getInterface()->getFlowMaxIdle()));
1274
0
  }
1275
1276
0
  inline u_int16_t getTLSVersion() {
1277
0
    return (isTLS() ? protos.tls.tls_version : 0);
1278
0
  }
1279
0
  inline u_int32_t getTLSNotBefore() {
1280
0
    return (isTLS() ? protos.tls.notBefore : 0);
1281
0
  };
1282
0
  inline u_int32_t getTLSNotAfter() {
1283
0
    return (isTLS() ? protos.tls.notAfter : 0);
1284
0
  };
1285
0
  inline char *getTLSCertificateIssuerDN() {
1286
0
    return (isTLS() ? protos.tls.issuerDN : NULL);
1287
0
  }
1288
0
  inline char *getTLSCertificateSubjectDN() {
1289
0
    return (isTLS() ? protos.tls.subjectDN : NULL);
1290
0
  }
1291
0
  inline void setTLSCertificateIssuerDN(char *issuer) {
1292
0
    if (protos.tls.issuerDN) free(protos.tls.issuerDN);
1293
0
    protos.tls.issuerDN = strdup(issuer);
1294
0
  }
1295
29.0k
  inline void setTOS(u_int8_t tos, bool is_cli_tos) {
1296
29.0k
    if (is_cli_tos) cli2srv_tos = tos;
1297
29.0k
    srv2cli_tos = tos;
1298
29.0k
  }
1299
0
  inline u_int8_t getTOS(bool is_cli_tos) const {
1300
0
    return (is_cli_tos ? cli2srv_tos : srv2cli_tos);
1301
0
  }
1302
1303
59.7k
  inline u_int8_t getCli2SrvDSCP() const { return (cli2srv_tos & 0xFC) >> 2; }
1304
29.8k
  inline u_int8_t getSrv2CliDSCP() const { return (srv2cli_tos & 0xFC) >> 2; }
1305
1306
0
  inline u_int8_t getCli2SrvECN() { return (cli2srv_tos & 0x3); }
1307
0
  inline u_int8_t getSrv2CliECN() { return (srv2cli_tos & 0x3); }
1308
1309
0
  inline float getEntropy(bool src2dst_direction) {
1310
0
    struct ndpi_analyze_struct *e = src2dst_direction
1311
0
                                        ? initial_bytes_entropy.c2s
1312
0
                                        : initial_bytes_entropy.s2c;
1313
1314
0
    return (e ? ndpi_data_entropy(e) : 0);
1315
0
  }
1316
1317
0
  inline float getICMPPacketsEntropy() {
1318
0
    return (protos.icmp.client_to_server.max_entropy -
1319
0
            protos.icmp.client_to_server.min_entropy);
1320
0
  }
1321
1322
0
  inline bool timeToPeriodicDump(u_int sec) {
1323
0
    return ((sec - get_first_seen() >= CONST_DB_DUMP_FREQUENCY) &&
1324
0
            (sec - get_partial_last_seen() >= CONST_DB_DUMP_FREQUENCY));
1325
0
  }
1326
1327
  u_char *getCommunityId(u_char *community_id, u_int community_id_len);
1328
  void setJSONRiskInfo(char *r);
1329
  char *getJSONRiskInfo();
1330
  void setEndReason(char *r);
1331
  char *getEndReason();
1332
  void setSMTPMailFrom(char *r);
1333
  char *getSMTPMailFrom();
1334
  void setSMTPRcptTo(char *r);
1335
  char *getSMTPRcptTo();
1336
  void setFlowRiskName(char *r);
1337
  char *getFlowRiskName();
1338
  void getJSONRiskInfo(ndpi_serializer *serializer);
1339
1340
0
  inline FlowTrafficStats *getTrafficStats() { return (&stats); };
1341
5.72k
  inline char *get_custom_category_file() const {
1342
5.72k
    return ((char *)ndpiDetectedProtocol.custom_category_userdata);
1343
5.72k
  }
1344
1345
0
  inline u_int8_t *getViewCliMac() { return (view_cli_mac); };
1346
0
  inline u_int8_t *getViewSrvMac() { return (view_srv_mac); };
1347
1348
0
  inline u_int32_t getErrorCode() { return (protocolErrorCode); }
1349
7.51k
  inline void setErrorCode(u_int32_t rc) { protocolErrorCode = rc; }
1350
1351
0
  inline char *getAddressFamilyProtocol() const {
1352
0
    return (ndpiAddressFamilyProtocol);
1353
0
  }
1354
66
  inline void setAddressFamilyProtocol(char *proto) {
1355
66
    ndpiAddressFamilyProtocol = strdup(proto);
1356
66
  }
1357
1358
0
  inline ndpi_confidence_t getConfidence() { return (confidence); }
1359
0
  inline void setConfidence(ndpi_confidence_t rc) { confidence = rc; }
1360
0
  inline void setNdpiConfidence(ndpi_confidence_t rc) { ndpi_confidence = rc; }
1361
1362
0
  inline u_int8_t getCliLocation() {
1363
0
    if ((cli_host && cli_host->isMulticastHost()) ||
1364
0
        (cli_ip_addr && cli_ip_addr->isMulticastAddress()))
1365
0
      return 2;  // Multicast host
1366
0
    else if ((cli_host && cli_host->isLocalHost()) ||
1367
0
            (cli_ip_addr && cli_ip_addr->isLocalHost()))
1368
0
      return 1;  // Local host
1369
0
    else
1370
0
      return 0;  // Remote host
1371
0
  }
1372
0
  inline u_int8_t getSrvLocation() {
1373
0
    if ((srv_host && srv_host->isMulticastHost()) ||
1374
0
        (srv_ip_addr && srv_ip_addr->isMulticastAddress()))
1375
0
      return 2;  // Multicast host
1376
0
    else if ((srv_host && srv_host->isLocalHost()) ||
1377
0
            (srv_ip_addr && srv_ip_addr->isLocalHost()))
1378
0
      return 1;  // Local host
1379
0
    else
1380
0
      return 0;  // Remote host
1381
0
  }
1382
1383
22.6k
  inline u_int32_t getPrivateFlowId() const { return (privateFlowId); }
1384
1385
0
  inline bool isCustomFlowAlertTriggered() {
1386
0
    return (customFlowAlert.alertTriggered);
1387
0
  }
1388
0
  inline u_int8_t getCustomFlowAlertScore() { return (customFlowAlert.score); }
1389
0
  inline char *getCustomFlowAlertMessage() { return (customFlowAlert.msg); }
1390
  void triggerCustomFlowAlert(u_int8_t score, char *msg);
1391
0
  inline void setRTPStreamType(ndpi_multimedia_flow_type s) {
1392
0
    rtp_stream_type = s;
1393
0
  }
1394
61
  inline ndpi_multimedia_flow_type getRTPStreamType() {
1395
61
    return (rtp_stream_type);
1396
61
  }
1397
0
  inline void setPeriodicFlow() { is_periodic_flow = 1; }
1398
0
  inline bool isPeriodicFlow() { return (is_periodic_flow ? true : false); }
1399
  void swap();
1400
  bool isDPIDetectedFlow();
1401
  void updateHostBlacklists();
1402
0
  inline int32_t getInterfaceIndex()      { return(iface_index); };
1403
0
  inline void setFlowSource(FlowSource n) { flow_source = n;     }
1404
29.8k
  inline FlowSource getFlowSource()       { return(flow_source); }
1405
};
1406
1407
#endif /* _FLOW_H_ */