/src/ntopng/include/Flow.h
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * (C) 2013-26 - 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 | | typedef struct { |
36 | | /* 0...254, 255 means more events */ |
37 | | u_int8_t num_syn, num_rst, num_fin, num_zero_window; |
38 | | } TCPStats; |
39 | | |
40 | | typedef struct { |
41 | | /* TCP stats */ |
42 | | TCPSeqNum tcp_seq_s2d, tcp_seq_d2s; |
43 | | u_int16_t cli2srv_window, srv2cli_window; |
44 | | struct timeval synTime, synAckTime, |
45 | | ackTime; /* network Latency (3-way handshake) */ |
46 | | float clientRTT3WH, serverRTT3WH; /* Computed at 3WH (msec) */ |
47 | | time_t last_network_issues; /* last time retr/ooo/lost has been observed */ |
48 | | struct { |
49 | | struct ndpi_analyze_struct cli_to_srv, srv_to_cli; |
50 | | u_int8_t cli_to_srv_winscale, srv_to_cli_winscale; |
51 | | } tcpWin; |
52 | | |
53 | | struct { |
54 | | u_int32_t last_cli_ack, last_srv_ack; |
55 | | struct bpf_timeval last_cli_ts, last_srv_ts; |
56 | | struct ndpi_analyze_struct cli_to_srv, srv_to_cli; |
57 | | } rtt; /* Computed continuously */ |
58 | | } FlowTCP; |
59 | | |
60 | | typedef struct { |
61 | | struct timeval first_cli_to_srv, first_srv_to_cli, |
62 | | second_cli_to_srv; /* Time of the first packet in each direction */ |
63 | | float clientRTT3WH, serverRTT3WH; /* Computed at 3WH (msec) */ |
64 | | struct { |
65 | | bool last_spin_set; |
66 | | struct timeval last_ts; |
67 | | struct ndpi_analyze_struct cli_min_rtt /* cli <-> ntopng RTT */, |
68 | | srv_min_rtt /* ntopng <-> dst RTT */; |
69 | | } rtt; |
70 | | } FlowUDP; |
71 | | |
72 | | typedef struct { |
73 | | struct ndpi_in6_addr exporter_ip; /* IPv4 stored as IPv4-mapped IPv6 (original IP) */ |
74 | | struct ndpi_in6_addr mapped_exporter_ip; /* IPv4 stored as IPv4-mapped IPv6 (after SNMP mapping) */ |
75 | | struct ndpi_in6_addr next_hop, mapped_next_hop; /* Same as for exporter_ip */ |
76 | | u_int16_t exporter_site_id, next_hop_site_id; |
77 | | u_int32_t in_index, out_index; |
78 | | SNMPInterfaceRole in_role, out_role; |
79 | | FlowSource source; /* sFlow / NetFlow */ |
80 | | bool return_path; |
81 | | } ExporterFlowInfo; |
82 | | |
83 | | typedef struct { |
84 | | struct ndpi_in6_addr exporter_ip, next_hop; |
85 | | } ExporterFlowInfoKey; |
86 | | |
87 | | |
88 | | // Define the equality operator |
89 | 0 | inline bool operator==(const ExporterFlowInfoKey& lhs, const ExporterFlowInfoKey& rhs) { |
90 | 0 | return std::memcmp(&lhs.exporter_ip, &rhs.exporter_ip, sizeof(ndpi_in6_addr)) == 0 && |
91 | 0 | std::memcmp(&lhs.next_hop, &rhs.next_hop, sizeof(ndpi_in6_addr)) == 0; |
92 | 0 | } |
93 | | |
94 | | // Hash functor |
95 | | struct ExporterFlowInfoKeyHash { |
96 | 0 | std::size_t operator()(const ExporterFlowInfoKey &k) const noexcept { |
97 | | // FNV-1a over the raw bytes of both addresses |
98 | 0 | const unsigned char *p = reinterpret_cast<const unsigned char *>(&k); |
99 | 0 | std::size_t h = 1469598103934665603ULL; // FNV offset basis |
100 | 0 | for (size_t i = 0; i < sizeof(ExporterFlowInfoKey); i++) { |
101 | 0 | h ^= p[i]; |
102 | 0 | h *= 1099511628211ULL; // FNV prime |
103 | 0 | } |
104 | 0 | return h; |
105 | 0 | } |
106 | | }; |
107 | | |
108 | | typedef struct { |
109 | | u_int32_t prevAdjacentAS, nextAdjacentAS; |
110 | | u_int32_t vrfId; |
111 | | |
112 | | struct { |
113 | | char *src, *dst; |
114 | | } bgp; |
115 | | |
116 | | struct { |
117 | | char* wlan_ssid; |
118 | | u_int8_t wtp_mac_address[6]; |
119 | | } wifi; |
120 | | |
121 | | struct { |
122 | | /* IPv4 only, so a int32 bit is only needed */ |
123 | | u_int32_t src_ip_addr_post_nat, dst_ip_addr_post_nat; |
124 | | u_int16_t src_port_post_nat, dst_port_post_nat; |
125 | | } nat; |
126 | | } FlowCollectionInfo; |
127 | | |
128 | | /* ******************************************************** */ |
129 | | |
130 | | class FlowAlert; |
131 | | class FlowCheck; |
132 | | |
133 | | class Flow : public GenericHashEntry { |
134 | | private: |
135 | | time_t creation_time; /*** Epoch of the flow creation */ |
136 | | int32_t iface_index; /* Interface index on which this flow has been first |
137 | | observed */ |
138 | | Host *cli_host, *srv_host; /* They are ALWAYS NULL on ViewInterfaces. For |
139 | | shared hosts see below viewFlowStats */ |
140 | | IpAddress *cli_ip_addr, *srv_ip_addr; |
141 | | u_int8_t src2dst_tcp_flags, dst2src_tcp_flags; |
142 | | FlowTCP* tcp; |
143 | | #ifdef NTOPNG_PRO |
144 | | FlowUDP* udp; |
145 | | FlowRTP* rtp; |
146 | | #endif |
147 | | u_int32_t flow_key; |
148 | | FlowCollectionInfo* collection; |
149 | | |
150 | | /* Data collected from nProbe */ |
151 | | std::string l7_json; |
152 | | std::vector<uint64_t> hr_src2dst_bytes, hr_dst2src_bytes; |
153 | | /* Time (wall-clock) of slot 0 of HR counters (hr_src2dst_bytes, etc) |
154 | | set by the first HR merge after a reset */ |
155 | | time_t hr_base_first_seen = 0; |
156 | | ICMPinfo* icmp_info; |
157 | | char* category_list_name_shared_pointer; /* NOTE: this is a pointer handled by |
158 | | Ntop::getPersistentCustomListNameById() |
159 | | and it MUST NOT BE FREED */ |
160 | | ndpi_confidence_t ndpi_confidence; |
161 | | ndpi_protocol_category_t flow_category; |
162 | | ndpi_protocol_breed_t flow_breed; |
163 | | u_int32_t privateFlowId; /* Used to store specific flow info such as DNS |
164 | | TransactionId or SIP CallId */ |
165 | | u_int8_t cli2srv_tos, srv2cli_tos; /* RFC 2474, 3168 */ |
166 | | u_int16_t cli_port, srv_port; |
167 | | u_int16_t vlanId; |
168 | | u_int32_t srcAS, dstAS; /* Calculated via GeoIP */ |
169 | | u_int32_t transitAS; |
170 | | u_int16_t observation_point_id; |
171 | | char *srcASName, *dstASName, *_srcASNameBuf, *_dstASNameBuf; |
172 | | char searched_field[64]; |
173 | | u_int32_t srcPeerAS, dstPeerAS; /* Collected via NetFLow/IPFIX */ |
174 | | u_int32_t protocolErrorCode; |
175 | | u_int8_t protocol, flow_verdict; |
176 | | u_int16_t flow_score; |
177 | | bool twh_over_view : 1 /* This flag is used for view interfaces */, |
178 | | shapers_profile_set : 1, iface_flow_accounted : 1, _notused : 5; |
179 | | u_int8_t cli_mac[6], srv_mac[6]; |
180 | | Mac *c_mac, *s_mac; /* Real flow MACs (hosts can have floating MACs when |
181 | | load-balancers are in use) Calculated using cli_mac and |
182 | | srv_mac[6] */ |
183 | | bool c_mac_updated, s_mac_updated; |
184 | | struct ndpi_flow_struct* ndpiFlow; |
185 | | ndpi_risk ndpi_flow_risk_bitmap; |
186 | | /* The bitmap of all possible flow alerts set by FlowCheck subclasses. |
187 | | When no alert is set, the flow is in flow_alert_normal. |
188 | | |
189 | | A flow can have multiple alerts but at most ONE of its alerts is |
190 | | predominant of a flow, which is written into `predominant_alert`. |
191 | | */ |
192 | | Bitmap128 alerts_map; |
193 | | |
194 | | std::unordered_map<ExporterFlowInfoKey, ExporterFlowInfo, ExporterFlowInfoKeyHash> exporterStats; |
195 | | std::map<FlowAlertTypeEnum, FlowAlert*> triggered_alerts; |
196 | | FlowAlertType predominant_alert; /* This is the predominant alert */ |
197 | | u_int16_t predominant_alert_score; /* The score associated to the predominant |
198 | | alert */ |
199 | | bool pending_alerts; /* alerts triggered with triggerAlert but waiting to be |
200 | | enqueued */ |
201 | | bool refresh_triggered_alerts; /* updated alerts previously triggered */ |
202 | | bool flow_end_housekeeping_done; /* used by pcap file processing to run flow-end housekeeping |
203 | | (including flow-end checks) before shutting down and purging */ |
204 | | FlowSource flow_source; |
205 | | |
206 | | struct { |
207 | | u_int8_t is_cli_attacker : 1, is_cli_victim : 1, is_srv_attacker : 1, |
208 | | is_srv_victim : 1, auto_acknowledge : 1; |
209 | | } alert_info; |
210 | | |
211 | | char *json_protocol_info, *alerts_json, *alerts_json_shadow, *riskInfo, |
212 | | *end_reason; |
213 | | |
214 | | u_int32_t hash_entry_id; /* Uniquely identify this flow inside the flows_hash |
215 | | hash table */ |
216 | | u_int32_t periodicity; /* When is_periodic_flow is set, specifies how periodic |
217 | | (seconds) is this flow */ |
218 | | u_int16_t detection_completed : 1, extra_dissection_completed : 1, |
219 | | twh_over : 1, dissect_next_http_packet : 1, passVerdict : 1, |
220 | | flow_dropped_counts_increased : 1, quota_exceeded : 1, swap_done : 1, |
221 | | swap_requested : 1, has_malicious_cli_signature : 1, |
222 | | has_malicious_srv_signature : 1, src2dst_tcp_zero_window : 1, |
223 | | dst2src_tcp_zero_window : 1, non_zero_payload_observed : 1, |
224 | | is_periodic_flow : 1, has_collected_qoe : 1; |
225 | | |
226 | | struct { |
227 | | u_int8_t src_to_dst, dst_to_src; |
228 | | } collected_qoe; |
229 | | |
230 | | DropReason dropVerdictReason; |
231 | | |
232 | | u_int8_t rtp_stream_type; |
233 | | #ifdef ALERTED_FLOWS_DEBUG |
234 | | bool iface_alert_inc, iface_alert_dec; |
235 | | #endif |
236 | | #ifdef NTOPNG_PRO |
237 | | bool ingress2egress_direction; |
238 | | bool lateral_movement; |
239 | | PeriodicityStatus periodicity_status; |
240 | | #ifndef HAVE_NEDGE |
241 | | #ifdef HAVE_NBPF |
242 | | FlowProfile* trafficProfile; |
243 | | #endif |
244 | | #else |
245 | | u_int32_t numFlowProcessedPkts, numPktsMarkerSet; |
246 | | u_int8_t routing_table_id; |
247 | | L7PolicySource_t cli_quota_source, srv_quota_source; |
248 | | #endif |
249 | | CounterTrend throughputTrend, goodputTrend, thptRatioTrend; |
250 | | #endif |
251 | | char* ndpiAddressFamilyProtocol; |
252 | | ndpi_protocol ndpiDetectedProtocol; |
253 | | char* ndpiFlowRiskName; |
254 | | custom_app_t custom_app; |
255 | | |
256 | | struct { |
257 | | bool alertTriggered; |
258 | | u_int8_t score; |
259 | | char* msg; |
260 | | } customFlowAlert; |
261 | | json_object* json_info; |
262 | | ndpi_serializer* tlv_info; |
263 | | ndpi_confidence_t confidence; |
264 | | char *host_server_name, *client_info, *bt_hash, *stun_mapped_address; |
265 | | IEC104Stats* iec104; |
266 | | #ifdef NTOPNG_PRO |
267 | | ModbusStats* modbus; |
268 | | S7CommStats* s7comm; |
269 | | ProfinetStats* profinet; |
270 | | #endif |
271 | | char* suspicious_dga_domain; /* Stores the suspicious DGA domain for flows |
272 | | with NDPI_SUSPICIOUS_DGA_DOMAIN */ |
273 | | ndpi_os operating_system; |
274 | | #ifdef HAVE_NEDGE |
275 | | u_int32_t last_conntrack_update; |
276 | | u_int32_t marker; |
277 | | #endif |
278 | | struct { |
279 | | char* source; |
280 | | json_object* json; |
281 | | } external_alert; |
282 | | |
283 | | char *tcp_fingerprint, *ndpi_fingerprint, *tls_blocks; |
284 | | struct { |
285 | | TCPStats cli2srv, srv2cli; |
286 | | } tcp_stats; |
287 | | |
288 | | bool |
289 | | trigger_immediate_periodic_update; /* needed to process external alerts */ |
290 | | time_t next_call_periodic_update; /* The time at which the periodic lua script |
291 | | on this flow shall be called */ |
292 | | |
293 | | /* Flow payload */ |
294 | | u_int16_t flow_payload_len; |
295 | | char* flow_payload; |
296 | | |
297 | | union { |
298 | | struct { |
299 | | char *last_url, *last_user_agent, *last_server; |
300 | | ndpi_http_method last_method; |
301 | | u_int16_t last_return_code; |
302 | | } http; |
303 | | |
304 | | struct { |
305 | | char *last_query, *last_query_shadow; |
306 | | char *last_rsp, *last_rsp_shadow; |
307 | | time_t |
308 | | last_query_update_time; /* The time when the last query was updated */ |
309 | | u_int16_t last_query_type; |
310 | | u_int16_t last_return_code; |
311 | | } dns; |
312 | | |
313 | | struct { |
314 | | char *name, *name_txt, *ssid; |
315 | | char* answer; |
316 | | } mdns; |
317 | | |
318 | | struct { |
319 | | char* location; |
320 | | } ssdp; |
321 | | |
322 | | struct { |
323 | | char* name; |
324 | | } netbios; |
325 | | |
326 | | struct { |
327 | | char* name; |
328 | | } dhcp; |
329 | | |
330 | | struct { |
331 | | char* call_id; |
332 | | } sip; |
333 | | |
334 | | struct { |
335 | | char *client_signature, *server_signature; |
336 | | struct { |
337 | | /* https://engineering.salesforce.com/open-sourcing-hassh-abed3ae5044c |
338 | | */ |
339 | | char *client_hash, *server_hash; |
340 | | } hassh; |
341 | | } ssh; |
342 | | |
343 | | struct { |
344 | | u_int16_t tls_version; |
345 | | u_int32_t notBefore, notAfter; |
346 | | char *client_alpn, *client_tls_supported_versions, *issuerDN, *subjectDN; |
347 | | char *client_requested_server_name, *server_names; |
348 | | /* Certificate dissection */ |
349 | | struct { |
350 | | char* client_hash; |
351 | | } ja4; |
352 | | } tls; |
353 | | |
354 | | struct { |
355 | | u_int8_t igmp_type; |
356 | | } igmp; |
357 | | |
358 | | struct { |
359 | | struct { |
360 | | u_int8_t icmp_type, icmp_code; |
361 | | } cli2srv, srv2cli; |
362 | | u_int16_t max_icmp_payload_size; |
363 | | |
364 | | struct { |
365 | | float min_entropy, max_entropy; |
366 | | } client_to_server; |
367 | | } icmp; |
368 | | |
369 | | struct { |
370 | | char* currency; |
371 | | } mining; |
372 | | |
373 | | struct { |
374 | | char* mail_from; |
375 | | char* rcpt_to; |
376 | | } smtp; |
377 | | } protos; |
378 | | |
379 | | /* eBPF Information */ |
380 | | ParsedeBPF* ebpf; |
381 | | |
382 | | /* Stats */ |
383 | | FlowTrafficStats stats; |
384 | | |
385 | | /* IP stats */ |
386 | | IPPacketStats ip_stats_s2d, ip_stats_d2s; |
387 | | |
388 | | struct timeval c2sFirstGoodputTime; |
389 | | float rttSec, applLatencyMsec; |
390 | | |
391 | | InterarrivalStats *cli2srvPktTime, *srv2cliPktTime; |
392 | | |
393 | | /* Counter values at last host update */ |
394 | | struct { |
395 | | PartializableFlowTrafficStats* partial; |
396 | | PartializableFlowTrafficStats delta; |
397 | | time_t first_seen, last_seen; |
398 | | bool in_progress, /* Set to true when the flow is enqueued to be dumped */ |
399 | | is_first_dump; |
400 | | } last_db_dump; |
401 | | |
402 | | #ifdef NTOPNG_PRO |
403 | | /* Lazily initialized and used by a possible view interface */ |
404 | | ViewInterfaceFlowStats* viewFlowStats; |
405 | | #endif |
406 | | |
407 | | /* Stats base updated periodically (get_partial_traffic_stats) |
408 | | * used to compute partial stats */ |
409 | | PartializableFlowTrafficStats* periodic_stats_base; |
410 | | |
411 | | #ifdef HAVE_NEDGE |
412 | | struct { |
413 | | TrafficShaper* cli; |
414 | | TrafficShaper* srv; |
415 | | } flowShapers; |
416 | | u_int16_t cli_shaper_id, srv_shaper_id; |
417 | | #endif |
418 | | struct timeval last_update_time; |
419 | | |
420 | | float top_bytes_thpt, top_goodput_bytes_thpt, top_pkts_thpt; |
421 | | float bytes_thpt, goodput_bytes_thpt; |
422 | | float pkts_thpt; |
423 | | ValueTrend bytes_thpt_trend, goodput_bytes_thpt_trend, pkts_thpt_trend; |
424 | | |
425 | | MinorConnectionStates current_c_state; |
426 | | u_int counter = 0; |
427 | | /* |
428 | | IMPORTANT NOTE |
429 | | |
430 | | if you add a new 'directional' field such as cliX and serverX |
431 | | you need to handle it in the Flow::swap() method |
432 | | */ |
433 | | |
434 | | void deferredInitialization(); |
435 | | char* intoaV4(unsigned int addr, char* buf, u_short bufLen); |
436 | | void allocDPIMemory(); |
437 | | bool checkTor(char* hostname); |
438 | | void updateThroughputStats(float tdiff_msec, u_int32_t diff_sent_packets, |
439 | | u_int64_t diff_sent_bytes, |
440 | | u_int64_t diff_sent_goodput_bytes, |
441 | | u_int32_t diff_rcvd_packets, |
442 | | u_int64_t diff_rcvd_bytes, |
443 | | u_int64_t diff_rcvd_goodput_bytes); |
444 | | void updatePacketStats(InterarrivalStats* stats, const struct timeval* when, |
445 | | bool update_iat); |
446 | | char* printTCPState(char* const buf, u_int buf_len) const; |
447 | | void update_pools_stats(NetworkInterface* iface, Host* cli_host, |
448 | | Host* srv_host, const struct timeval* tv, |
449 | | u_int64_t diff_sent_packets, |
450 | | u_int64_t diff_sent_bytes, |
451 | | u_int64_t diff_rcvd_packets, |
452 | | u_int64_t diff_rcvd_bytes) const; |
453 | | /* |
454 | | Check (and possibly enqueues) the flow for dump |
455 | | */ |
456 | | void dumpCheck(time_t t, bool last_dump_before_free); |
457 | | void updateCliJA4(); |
458 | | void updateHASSH(bool as_client); |
459 | | void processExtraDissectedInformation(); |
460 | | void processDetectedProtocol( |
461 | | u_int8_t* payload, u_int16_t payload_len); /* nDPI detected protocol */ |
462 | | void processDetectedProtocolData(); /* nDPI detected protocol data (e.g., |
463 | | ndpiFlow->host_server_name) */ |
464 | | void setExtraDissectionCompleted(bool src2dst_direction); |
465 | | void setProtocolDetectionCompleted(u_int8_t* payload, u_int16_t payload_len, |
466 | | time_t when_seen); |
467 | | void updateProtocol(ndpi_protocol proto_id); |
468 | | const char* cipher_weakness2str(ndpi_cipher_weakness w) const; |
469 | | bool get_partial_traffic_stats(PartializableFlowTrafficStats** dst, |
470 | | PartializableFlowTrafficStats* delta, |
471 | | bool* first_partial) const; |
472 | | void lua_tos(lua_State* vm); |
473 | | void lua_confidence(lua_State* vm); |
474 | | void luaScore(lua_State* vm); |
475 | | void luaIEC104(lua_State* vm); |
476 | | bool setAlertsMap(FlowAlert* alert); |
477 | | void setNormalToAlertedCounters(); |
478 | | /* Decreases scores on both client and server hosts when the flow is being |
479 | | * destructed */ |
480 | | void decAllFlowScores(); |
481 | | void updateServerPortsStats(Host* server_host, ndpi_protocol* proto, |
482 | | time_t when_seen); |
483 | | void updateClientContactedPorts(Host* client, ndpi_protocol* proto); |
484 | | void updateTCPHostServices(Host* cli_h, Host* srv_h); |
485 | | void updateUDPHostServices(bool src2dst_direction); |
486 | | void updateServerName(Host* h); |
487 | | void allocateCollection(); |
488 | | void mergeHRCounters(std::vector<uint64_t>& flow_counters, |
489 | | const std::vector<uint64_t>& update_counters, |
490 | | time_t update_first_seen); |
491 | | void computeKey(); |
492 | | void accountBidirectionalTCPProtocolServices(); |
493 | | void accountBidirectionalUDPProtocolServices(); |
494 | | void setServerName(char* value); |
495 | | void setClientInfo(char* value); |
496 | | #ifdef NTOPNG_PRO |
497 | | void processHostName(char* host_name); |
498 | | #endif |
499 | | void updateMac(); |
500 | | void decodeTCPstats(u_int32_t v, TCPStats* stats); |
501 | | void serializeTCPFlagsJSON(ndpi_serializer* serializer, TCPStats* stats, |
502 | | const char* label); |
503 | | void allocTCPStats(); |
504 | | void allocUDPStats(); |
505 | | |
506 | | public: |
507 | | Flow(NetworkInterface* _iface, int32_t iface_idx, u_int16_t _vlanId, |
508 | | u_int16_t _observation_point_id, u_int32_t _private_flow_id, |
509 | | u_int8_t _protocol, Mac* _cli_mac, IpAddress* _cli_ip, |
510 | | u_int16_t _cli_port, Mac* _srv_mac, IpAddress* _srv_ip, |
511 | | u_int16_t _srv_port, const ICMPinfo* const icmp_info, time_t _first_seen, |
512 | | time_t _last_seen, u_int8_t* _view_cli_mac, u_int8_t* _view_srv_mac); |
513 | | ~Flow(); |
514 | | |
515 | | virtual bool is_active_entry_now_idle(u_int max_idleness) const; |
516 | 0 | inline Bitmap128 getAlertsBitmap() const { return (alerts_map); } |
517 | | |
518 | | /* Enqueues an alert to all available flow recipients. */ |
519 | | bool enqueueAlertToRecipients(FlowAlert* alert); |
520 | | |
521 | | /* |
522 | | Called by FlowCheck subclasses to trigger a flow alert. Setting sync |
523 | | will causes the alert (FlowAlert) to be immediatly enqueued to recipients. |
524 | | */ |
525 | | bool triggerAlert(FlowAlert* alert, bool sync = false); |
526 | | |
527 | 0 | inline FlowAlert* getTriggeredAlert(FlowAlertTypeEnum alert_type) const { |
528 | 0 | std::map<FlowAlertTypeEnum, FlowAlert*>::const_iterator it; |
529 | 0 | it = triggered_alerts.find(alert_type); |
530 | 0 | return (it != triggered_alerts.end()) ? it->second : NULL; |
531 | 0 | } |
532 | | |
533 | | /* |
534 | | Alerts are not flushed immediatly as optimization (unless sync is set in |
535 | | triggerAlert). If pending_alerts, they are enqueued to recipients, in a |
536 | | single notification for the predominant one. |
537 | | */ |
538 | | void flushAlerts(); |
539 | | |
540 | | /* |
541 | | Refresh alert stored in flows (rebuild JSON) as the content of some |
542 | | of them have been updated (e.g. re-triggered) and the value may be changed |
543 | | (e.g. the value that exceeded a threshold has increased further) |
544 | | */ |
545 | | void refreshAlert(FlowAlertTypeEnum alert_type); |
546 | | |
547 | | /* |
548 | | Enqueues the predominant alert of the flow to all available flow recipients. |
549 | | */ |
550 | | void enqueuePredominantAlert(); |
551 | | |
552 | 0 | inline void setFlowVerdict(u_int8_t _flow_verdict) { |
553 | 0 | flow_verdict = _flow_verdict; |
554 | 0 | }; |
555 | | |
556 | | inline void setPredominantAlert(FlowAlertType alert_type, u_int16_t score); |
557 | 0 | inline FlowAlertType getPredominantAlert() const { |
558 | 0 | return predominant_alert; |
559 | 0 | }; |
560 | 0 | inline u_int16_t getPredominantAlertScore() const { |
561 | 0 | return predominant_alert_score; |
562 | 0 | }; |
563 | 0 | inline AlertLevel getPredominantAlertSeverity() const { |
564 | 0 | return Utils::mapScoreToSeverity(predominant_alert_score); |
565 | 0 | }; |
566 | 5.00k | inline bool isFlowAlerted() const { |
567 | 5.00k | return (predominant_alert.id != flow_alert_normal); |
568 | 5.00k | }; |
569 | | |
570 | | #if defined(NTOPNG_PRO) |
571 | | bool isFlowAllowed(bool* is_allowed); |
572 | | |
573 | | #endif |
574 | 0 | inline u_int32_t getSrcPeerAS() const { return srcPeerAS; } |
575 | 0 | inline u_int32_t getDstPeerAS() const { return dstPeerAS; } |
576 | 0 | inline u_int32_t getNextAdjacentAS() const { return (collection ? collection->nextAdjacentAS : 0); } |
577 | | |
578 | | void setAlertInfo(FlowAlert* alert); |
579 | 0 | inline bool isAlertAutoAck() { return !!alert_info.auto_acknowledge; }; |
580 | 0 | inline u_int8_t isClientAttacker() { return alert_info.is_cli_attacker; }; |
581 | 0 | inline u_int8_t isClientVictim() { return alert_info.is_cli_victim; }; |
582 | 0 | inline u_int8_t isServerAttacker() { return alert_info.is_srv_attacker; }; |
583 | 0 | inline u_int8_t isServerVictim() { return alert_info.is_srv_victim; }; |
584 | 0 | inline char* getProtocolInfo() { return json_protocol_info; }; |
585 | | void updateAlertsJSON(); |
586 | 0 | inline char* getAlertJSON() { return alerts_json; }; |
587 | | const char* getDomainName(); |
588 | | void callFlowUpdate(time_t t); |
589 | | void setProtocolJSONInfo(); |
590 | | void serializeProtocolJSONInfo(ndpi_serializer* serializer); |
591 | | void serializeCustomFieldsInfo(ndpi_serializer* serializer); |
592 | | |
593 | 0 | inline char* getJa4CliHash() { return (protos.tls.ja4.client_hash); } |
594 | | |
595 | | char* getCliCountry(char* buf, u_int buf_len); |
596 | | char* getSrvCountry(char* buf, u_int buf_len); |
597 | | bool isBlacklistedFlow() const; |
598 | | bool isBlacklistedClient() const; |
599 | | bool isBlacklistedServer() const; |
600 | | struct site_categories* getFlowCategory(bool force_categorization); |
601 | | void freeDPIMemory(); |
602 | | bool isTiny() const; |
603 | 247k | inline bool isProto(u_int16_t p) const { |
604 | 247k | return (((ndpiDetectedProtocol.proto.master_protocol == p) || |
605 | 247k | (ndpiDetectedProtocol.proto.app_protocol == p)) |
606 | 247k | ? true |
607 | 247k | : false); |
608 | 247k | } |
609 | | bool isTLS() const; |
610 | 0 | inline bool isEncryptedProto() const { |
611 | 0 | return (ndpi_is_encrypted_proto(iface->get_ndpi_struct(), |
612 | 0 | ndpiDetectedProtocol.proto)); |
613 | 0 | } |
614 | 9.42k | inline bool isSSH() const { return (isProto(NDPI_PROTOCOL_SSH)); } |
615 | 9.12k | inline bool isMining() const { return (isProto(NDPI_PROTOCOL_MINING)); } |
616 | 35.3k | inline bool isDNS() const { return (isProto(NDPI_PROTOCOL_DNS)); } |
617 | 3.77k | inline bool isSTUN() const { return (isProto(NDPI_PROTOCOL_STUN)); } |
618 | 0 | inline bool isQUIC() const { return (isProto(NDPI_PROTOCOL_QUIC)); } |
619 | 35 | inline bool isZoomRTP() const { |
620 | 35 | return (isProto(NDPI_PROTOCOL_ZOOM) && |
621 | 29 | (isProto(NDPI_PROTOCOL_RTP) || isProto(NDPI_PROTOCOL_SRTP))); |
622 | 35 | } |
623 | 6.44k | inline bool isIEC60870() const { return (isProto(NDPI_PROTOCOL_IEC60870)); } |
624 | 0 | inline bool isModbus() const { return (isProto(NDPI_PROTOCOL_MODBUS)); } |
625 | 0 | inline bool isS7Comm() const { return (isProto(NDPI_PROTOCOL_S7COMM)); } |
626 | 0 | inline bool isProfinet() const { |
627 | 0 | return (isProto(NDPI_PROTOCOL_PROFINET_IO)); |
628 | 0 | } |
629 | 4.68k | inline bool isMDNS() const { return (isProto(NDPI_PROTOCOL_MDNS)); } |
630 | 4.52k | inline bool isSSDP() const { return (isProto(NDPI_PROTOCOL_SSDP)); } |
631 | 4.46k | inline bool isNetBIOS() const { return (isProto(NDPI_PROTOCOL_NETBIOS)); } |
632 | 8.59k | inline bool isSIP() const { return (isProto(NDPI_PROTOCOL_SIP)); } |
633 | 4.33k | inline bool isDHCP() const { return (isProto(NDPI_PROTOCOL_DHCP)); } |
634 | 0 | inline bool isNTP() const { return (isProto(NDPI_PROTOCOL_NTP)); } |
635 | 0 | inline bool isSMTPorSMTPS() const { return (isSMTP() || isSMTPS()); } |
636 | 4.18k | inline bool isSMTP() const { return (isProto(NDPI_PROTOCOL_MAIL_SMTP)); } |
637 | 0 | inline bool isSMTPS() const { return (isProto(NDPI_PROTOCOL_MAIL_SMTPS)); } |
638 | 10.7k | inline bool isHTTP() const { return (isProto(NDPI_PROTOCOL_HTTP)); } |
639 | 8.65k | inline bool isHTTP_PROXY() const { |
640 | 8.65k | return (isProto(NDPI_PROTOCOL_HTTP_PROXY)); |
641 | 8.65k | } |
642 | 8.65k | inline bool isHTTP_CONNECT() const { |
643 | 8.65k | return (isProto(NDPI_PROTOCOL_HTTP_CONNECT)); |
644 | 8.65k | } |
645 | 13 | inline bool isIGMP() const { return (isProto(NDPI_PROTOCOL_IP_IGMP)); } |
646 | 3.21k | inline bool isICMP() const { |
647 | 3.21k | return (isProto(NDPI_PROTOCOL_IP_ICMP) || isProto(NDPI_PROTOCOL_IP_ICMPV6)); |
648 | 3.21k | } |
649 | 42 | inline bool isBittorrent() const { |
650 | 42 | return (isProto(NDPI_PROTOCOL_BITTORRENT)); |
651 | 42 | } |
652 | | |
653 | 0 | inline bool isTwhOverForViewInterface() { |
654 | 0 | return ((twh_over_view == 1) ? true : false); |
655 | 0 | } |
656 | 0 | inline void setTwhOverForViewInterface() { twh_over_view = 1; } |
657 | | #if defined(NTOPNG_PRO) |
658 | | inline bool isLateralMovement() const { return (lateral_movement); } |
659 | | inline void setLateralMovement(bool change) { lateral_movement = change; } |
660 | | PeriodicityStatus getPeriodicity() const { return (periodicity_status); } |
661 | | inline void setPeriodicity(PeriodicityStatus _periodicity_status) { |
662 | | periodicity_status = _periodicity_status; |
663 | | } |
664 | | #endif |
665 | | |
666 | 0 | inline bool isCliDeviceAllowedProtocol() const { |
667 | 0 | return !cli_host || |
668 | 0 | cli_host->getDeviceAllowedProtocolStatus( |
669 | 0 | get_detected_protocol(), true) == device_proto_allowed; |
670 | 0 | } |
671 | 0 | inline bool isSrvDeviceAllowedProtocol() const { |
672 | 0 | return !srv_host || |
673 | 0 | get_bytes_srv2cli() == |
674 | 0 | 0 /* Server must respond to be considered NOT allowed */ |
675 | 0 | || srv_host->getDeviceAllowedProtocolStatus( |
676 | 0 | get_detected_protocol(), false) == device_proto_allowed; |
677 | 0 | } |
678 | 0 | inline bool isDeviceAllowedProtocol() const { |
679 | 0 | return isCliDeviceAllowedProtocol() && isSrvDeviceAllowedProtocol(); |
680 | 0 | } |
681 | 0 | inline u_int16_t getCliDeviceDisallowedProtocol() const { |
682 | 0 | DeviceProtoStatus cli_ps = |
683 | 0 | cli_host->getDeviceAllowedProtocolStatus(get_detected_protocol(), true); |
684 | |
|
685 | 0 | return (cli_ps == device_proto_forbidden_app) |
686 | 0 | ? ndpiDetectedProtocol.proto.app_protocol |
687 | 0 | : ndpiDetectedProtocol.proto.master_protocol; |
688 | 0 | } |
689 | 0 | inline u_int16_t getSrvDeviceDisallowedProtocol() const { |
690 | 0 | DeviceProtoStatus srv_ps = srv_host->getDeviceAllowedProtocolStatus( |
691 | 0 | get_detected_protocol(), false); |
692 | |
|
693 | 0 | return (srv_ps == device_proto_forbidden_app) |
694 | 0 | ? ndpiDetectedProtocol.proto.app_protocol |
695 | 0 | : ndpiDetectedProtocol.proto.master_protocol; |
696 | 0 | } |
697 | 64 | inline bool isMaskedFlow() const { |
698 | 64 | return ((get_cli_ip_addr() && |
699 | 64 | Utils::maskHost(get_cli_ip_addr()->isLocalHost())) || |
700 | 64 | (get_srv_ip_addr() && |
701 | 64 | Utils::maskHost(get_srv_ip_addr()->isLocalHost()))); |
702 | 64 | }; |
703 | | char* serialize(ExportFormat format = export_format_GENERIC); |
704 | | /* Prepares an alert JSON and puts int in the resulting `serializer`. */ |
705 | | void alert2JSON(FlowAlert* alert, ndpi_serializer* serializer); |
706 | | json_object* flow2JSON(ExportFormat format); |
707 | | json_object* flow2es(json_object* flow_object); |
708 | | void formatECSInterface(json_object* my_object); |
709 | | void formatECSNetwork(json_object* my_object, const IpAddress* addr); |
710 | | void formatECSHost(json_object* my_object, bool is_client, |
711 | | const IpAddress* addr, Host* host); |
712 | | void formatECSEvent(json_object* my_object); |
713 | | void formatECSFlow(json_object* my_object); |
714 | | void formatSyslogFlow(json_object* my_object); |
715 | | void formatGenericFlow(json_object* my_object); |
716 | | void formatECSExtraInfo(json_object* my_object); |
717 | | void formatECSAppProto(json_object* my_object); |
718 | | void formatECSObserver(json_object* my_object); |
719 | | |
720 | 0 | inline u_int16_t getLowerProtocol() { |
721 | 0 | return (ndpi_get_lower_proto(ndpiDetectedProtocol.proto)); |
722 | 0 | } |
723 | 0 | inline u_int16_t getUpperProtocol() { |
724 | 0 | return (ndpi_get_upper_proto(ndpiDetectedProtocol.proto)); |
725 | 0 | } |
726 | | |
727 | 0 | inline void updateJA4C(char* j) { |
728 | 0 | if (j && (j[0] != '\0') && (protos.tls.ja4.client_hash == NULL)) |
729 | 0 | protos.tls.ja4.client_hash = strdup(j); |
730 | 0 | updateCliJA4(); |
731 | 0 | } |
732 | | |
733 | 0 | inline u_int8_t getTcpFlags() const { |
734 | 0 | return (src2dst_tcp_flags | dst2src_tcp_flags); |
735 | 0 | }; |
736 | 2.54k | inline u_int8_t getTcpFlagsCli2Srv() const { return (src2dst_tcp_flags); }; |
737 | 0 | inline u_int8_t getTcpFlagsSrv2Cli() const { return (dst2src_tcp_flags); }; |
738 | | #ifdef HAVE_NEDGE |
739 | | bool checkPassVerdict(const struct tm* now); |
740 | | bool isPassVerdict(); |
741 | | inline void setConntrackMarker(u_int32_t marker) { this->marker = marker; } |
742 | | inline u_int32_t getConntrackMarker() { return (marker); } |
743 | | void incFlowDroppedCounters(); |
744 | | #endif |
745 | | void setDropVerdict(DropReason reason); |
746 | 0 | inline bool getVerdict() { return passVerdict; }; |
747 | 0 | inline DropReason getDropReason() { return dropVerdictReason; }; |
748 | | u_int32_t getPid(bool client); |
749 | | u_int32_t getFatherPid(bool client); |
750 | | u_int32_t get_uid(bool client) const; |
751 | | char* get_proc_name(bool client); |
752 | | char* get_user_name(bool client); |
753 | | u_int32_t getNextTcpSeq(u_int8_t tcpFlags, u_int32_t tcpSeqNum, |
754 | | u_int32_t payloadLen); |
755 | | static double toMs(const struct timeval* t); |
756 | | void timeval_diff(struct timeval* begin, const struct timeval* end, |
757 | | struct timeval* result, bool divide_by_two); |
758 | | std::string getFlowInfo(bool isLuaRequest); |
759 | 0 | inline std::string getL7JSON() { return (l7_json); } |
760 | 0 | inline void setL7JSON(const std::string &j) { l7_json = j; } |
761 | 0 | inline char* getFlowServerInfo() { |
762 | 0 | return (isTLS() && protos.tls.client_requested_server_name) |
763 | 0 | ? protos.tls.client_requested_server_name |
764 | 0 | : host_server_name; |
765 | 0 | } |
766 | 58 | inline char* getBitTorrentHash() { return (bt_hash); }; |
767 | 0 | inline void setBTHash(char* h) { |
768 | 0 | if (!h) return; |
769 | 0 | if (bt_hash) free(bt_hash); |
770 | 0 | bt_hash = h; |
771 | 0 | } |
772 | | void updateICMPFlood(const struct bpf_timeval* when, bool src2dst_direction); |
773 | | void updateDNSFlood(const struct bpf_timeval* when, bool src2dst_direction); |
774 | | void updateSNMPFlood(const struct bpf_timeval* when, bool src2dst_direction); |
775 | | void updateTcpFlags(const struct bpf_timeval* when, u_int8_t flags, |
776 | | bool src2dst_direction, bool new_flow); |
777 | | void updateTcpWindow(u_int16_t window, bool src2dst_direction); |
778 | | void updateTcpSeqIssues(const ParsedFlow* pf); |
779 | | void updateTLS(ParsedFlow* zflow); |
780 | | void updateDNS(ParsedFlow* zflow); |
781 | | void updateHTTP(ParsedFlow* zflow); |
782 | | void updateSuspiciousDGADomain(); |
783 | | void incTcpBadStats(bool src2dst_direction, Host* cli, Host* srv, |
784 | | NetworkInterface* iface, u_int32_t ooo_pkts, |
785 | | u_int32_t retr_pkts, u_int32_t lost_pkts, |
786 | | u_int32_t keep_alive_pkts); |
787 | | |
788 | | void updateTcpSeqNum(const struct bpf_timeval* when, u_int32_t seq_num, |
789 | | u_int32_t ack_seq_num, u_int16_t window, u_int8_t flags, |
790 | | u_int16_t payload_len, bool src2dst_direction); |
791 | | |
792 | | void updateSeqNum(time_t when, u_int32_t sN, u_int32_t aN); |
793 | | void setDetectedProtocol(ndpi_protocol proto_id, bool src2dst_direction); |
794 | | void processPacket(bool src2dst_direction, const struct pcap_pkthdr* h, |
795 | | const u_char* ip_packet, u_int16_t ip_len, |
796 | | u_int64_t packet_time, u_int8_t* payload, |
797 | | u_int16_t payload_len, u_int16_t src_port); |
798 | | void processDNSPacket(const u_char* ip_packet, u_int16_t ip_len, |
799 | | u_int64_t packet_time); |
800 | | void processIEC60870Packet(bool tx_direction, const u_char* payload, |
801 | | u_int16_t payload_len, |
802 | | const struct pcap_pkthdr* h); |
803 | | #ifdef NTOPNG_PRO |
804 | | void updateOTStats(ParsedFlow* zflow); |
805 | | void processModbusPacket(bool is_query, const u_char* payload, |
806 | | u_int16_t payload_len, const struct pcap_pkthdr* h); |
807 | | void processRTPPacket(const u_char* payload, u_int16_t payload_len, |
808 | | const struct pcap_pkthdr* h, bool src2dst_direction); |
809 | | void updateQUICStats(bool src2dst_direction, const struct timeval* tv, |
810 | | u_int8_t* payload, u_int16_t payload_len); |
811 | | void updateUDPTimestamp(bool src2dst_direction, const struct timeval* tv); |
812 | | void computeQoEscore(u_int8_t* cli_to_srv_qoe, |
813 | | std::vector<std::string>* cli_to_srv_qoe_issues, |
814 | | u_int8_t* srv_to_cli_qoe, |
815 | | std::vector<std::string>* srv_to_cli_qoe_issues); |
816 | | u_int8_t computeQoETCPscore(QoELimits* l, bool cli_to_srv, |
817 | | std::vector<std::string>* issues); |
818 | | u_int8_t computeQoEUDPscore(QoELimits* l, bool cli_to_srv, |
819 | | std::vector<std::string>* issues); |
820 | | u_int8_t computeQoEMOSscore(bool cli_to_srv); |
821 | | u_int8_t getQoEScore(); |
822 | | void serializeQoEInfo(ndpi_serializer* serializer); |
823 | | QoEType getQoEType(); |
824 | | #endif |
825 | | void endProtocolDissection(bool src2dst_direction); |
826 | 0 | inline void setCustomApp(custom_app_t ca) { |
827 | 0 | memcpy(&custom_app, &ca, sizeof(custom_app)); |
828 | 0 | }; |
829 | 0 | inline custom_app_t getCustomApp() const { return custom_app; }; |
830 | | u_int16_t getStatsProtocol() const; |
831 | | void setJSONInfo(json_object* json); |
832 | | void setTLVInfo(ndpi_serializer* tlv); |
833 | | void incStats(bool cli2srv_direction, u_int pkt_len, u_int8_t* payload, |
834 | | u_int payload_len, u_int8_t l4_proto, u_int8_t is_fragment, |
835 | | u_int16_t tcp_flags, const struct timeval* when, |
836 | | u_int16_t fragment_extra_overhead); |
837 | | bool addFlowStats(bool new_flow, bool cli2srv_direction, u_int in_pkts, |
838 | | u_int in_bytes, u_int in_goodput_bytes, u_int out_pkts, |
839 | | u_int out_bytes, u_int out_goodput_bytes, |
840 | | u_int in_fragments, u_int out_fragments, time_t first_seen, |
841 | | time_t last_seen); |
842 | | |
843 | | void addPostNATIPv4(u_int32_t _src_ip_addr_post_nat, |
844 | | u_int32_t _dst_ip_addr_post_nat); |
845 | | |
846 | | void addPostNATPort(u_int32_t _src_port_post_nat, |
847 | | u_int32_t _dst_port_post_nat); |
848 | | void check_swap(); |
849 | | |
850 | | bool isThreeWayHandshakeOK() const; |
851 | | |
852 | 7.22k | inline ndpi_classification_state getDetectionState() { |
853 | 7.22k | return (ndpiDetectedProtocol.state); |
854 | 7.22k | } |
855 | 14.4k | inline bool isDetectionCompleted() const { |
856 | 14.4k | return (detection_completed ? true : false); |
857 | 14.4k | }; |
858 | 4.21k | inline bool isOneWay() const { |
859 | 4.21k | return (get_packets() && |
860 | 4.21k | (!get_packets_cli2srv() || !get_packets_srv2cli())); |
861 | 4.21k | }; |
862 | 5.87k | inline bool isBidirectional() const { |
863 | 5.87k | return (get_packets_cli2srv() && get_packets_srv2cli()); |
864 | 5.87k | }; |
865 | | |
866 | | /* |
867 | | Find a simple criteria to ignore probing attempts selecting |
868 | | only flows with real data exchanged both ways |
869 | | */ |
870 | 76 | inline bool isTCPReallyBidirectional() const { |
871 | 76 | return ((get_packets_cli2srv() > NUM_MIN_TCP_PKTS_PER_DIRECTION) && |
872 | 0 | (src2dst_tcp_flags & TH_PUSH) && |
873 | 0 | (get_packets_srv2cli() > NUM_MIN_TCP_PKTS_PER_DIRECTION) && |
874 | 0 | (dst2src_tcp_flags & TH_PUSH)); |
875 | 76 | }; |
876 | | |
877 | 0 | inline bool isRemoteToRemote() const { |
878 | 0 | return (cli_host && srv_host && !cli_host->isLocalHost() && |
879 | 0 | !srv_host->isLocalHost()); |
880 | 0 | }; |
881 | | |
882 | 0 | inline bool isLocalToRemote() const { |
883 | 0 | return get_cli_ip_addr()->isLocalHost() && |
884 | 0 | !get_srv_ip_addr()->isLocalHost(); |
885 | 0 | }; |
886 | | |
887 | 0 | inline bool isRemoteToLocal() const { |
888 | 0 | return !get_cli_ip_addr()->isLocalHost() && |
889 | 0 | get_srv_ip_addr()->isLocalHost(); |
890 | 0 | }; |
891 | | |
892 | 29.2k | inline bool isLocalToLocal() const { |
893 | 29.2k | return get_cli_ip_addr()->isLocalHost() && get_srv_ip_addr()->isLocalHost(); |
894 | 29.2k | }; |
895 | | |
896 | 0 | inline bool isUnicast() const { |
897 | 0 | return (cli_ip_addr && srv_ip_addr && |
898 | 0 | !cli_ip_addr->isBroadMulticastAddress() && |
899 | 0 | !srv_ip_addr->isBroadMulticastAddress()); |
900 | 0 | }; |
901 | | |
902 | 0 | inline u_int32_t get_cli_ipv4() const { |
903 | 0 | return (cli_host->get_ip()->get_ipv4()); |
904 | 0 | }; |
905 | | |
906 | 0 | inline u_int32_t get_srv_ipv4() const { |
907 | 0 | return (srv_host->get_ip()->get_ipv4()); |
908 | 0 | }; |
909 | 3.06k | inline ndpi_protocol get_detected_protocol() const { |
910 | 3.06k | return (ndpiDetectedProtocol); |
911 | 3.06k | } |
912 | | |
913 | 35.1k | inline struct ndpi_flow_struct* get_ndpi_flow() const { return (ndpiFlow); }; |
914 | 0 | inline const struct ndpi_in6_addr* get_cli_ipv6() const { |
915 | 0 | return (cli_host->get_ip()->get_ipv6()); |
916 | 0 | }; |
917 | | |
918 | 0 | inline const struct ndpi_in6_addr* get_srv_ipv6() const { |
919 | 0 | return (srv_host->get_ip()->get_ipv6()); |
920 | 0 | }; |
921 | | |
922 | 3.79k | inline u_int16_t get_cli_port() const { return (ntohs(cli_port)); }; |
923 | 2.71k | inline u_int16_t get_srv_port() const { return (ntohs(srv_port)); }; |
924 | 1.75k | inline u_int16_t get_vlan_id() const { return (vlanId); }; |
925 | 44.1k | inline u_int8_t get_protocol() const { return (protocol); }; |
926 | 0 | inline u_int64_t get_bytes() const { |
927 | 0 | return (stats.get_cli2srv_bytes() + stats.get_srv2cli_bytes()); |
928 | 0 | }; |
929 | 13.1k | inline u_int64_t get_bytes_cli2srv() const { |
930 | 13.1k | return (stats.get_cli2srv_bytes()); |
931 | 13.1k | }; |
932 | 33.6k | inline u_int64_t get_bytes_srv2cli() const { |
933 | 33.6k | return (stats.get_srv2cli_bytes()); |
934 | 33.6k | }; |
935 | 0 | inline u_int64_t get_goodput_bytes() const { |
936 | 0 | return (stats.get_cli2srv_goodput_bytes() + |
937 | 0 | stats.get_srv2cli_goodput_bytes()); |
938 | 0 | }; |
939 | 0 | inline u_int64_t get_goodput_bytes_cli2srv() const { |
940 | 0 | return (stats.get_cli2srv_goodput_bytes()); |
941 | 0 | }; |
942 | 0 | inline u_int64_t get_goodput_bytes_srv2cli() const { |
943 | 0 | return (stats.get_srv2cli_goodput_bytes()); |
944 | 0 | }; |
945 | 12.8k | inline u_int64_t get_packets() const { |
946 | 12.8k | return (stats.get_cli2srv_packets() + stats.get_srv2cli_packets()); |
947 | 12.8k | }; |
948 | 16.0k | inline u_int32_t get_packets_cli2srv() const { |
949 | 16.0k | return (stats.get_cli2srv_packets()); |
950 | 16.0k | }; |
951 | 16.1k | inline u_int32_t get_packets_srv2cli() const { |
952 | 16.1k | return (stats.get_srv2cli_packets()); |
953 | 16.1k | }; |
954 | 0 | inline u_int64_t get_partial_bytes() const { |
955 | 0 | return get_partial_bytes_cli2srv() + get_partial_bytes_srv2cli(); |
956 | 0 | }; |
957 | 0 | inline u_int64_t get_partial_packets() const { |
958 | 0 | return get_partial_packets_cli2srv() + get_partial_packets_srv2cli(); |
959 | 0 | }; |
960 | 0 | inline u_int64_t get_partial_goodput_bytes() const { |
961 | 0 | return last_db_dump.delta.get_cli2srv_goodput_bytes() + |
962 | 0 | last_db_dump.delta.get_srv2cli_goodput_bytes(); |
963 | 0 | }; |
964 | 0 | inline u_int64_t get_partial_bytes_cli2srv() const { |
965 | 0 | return last_db_dump.delta.get_cli2srv_bytes(); |
966 | 0 | }; |
967 | 0 | inline u_int64_t get_partial_bytes_srv2cli() const { |
968 | 0 | return last_db_dump.delta.get_srv2cli_bytes(); |
969 | 0 | }; |
970 | 0 | inline u_int64_t get_partial_packets_cli2srv() const { |
971 | 0 | return last_db_dump.delta.get_cli2srv_packets(); |
972 | 0 | }; |
973 | 0 | inline u_int64_t get_partial_packets_srv2cli() const { |
974 | 0 | return last_db_dump.delta.get_srv2cli_packets(); |
975 | 0 | }; |
976 | 0 | inline void set_dump_in_progress() { last_db_dump.in_progress = true; }; |
977 | 0 | inline void set_dump_done() { last_db_dump.in_progress = false, last_db_dump.is_first_dump = false; }; |
978 | | bool needsExtraDissection(); |
979 | | bool hasDissectedTooManyPackets(); |
980 | | #ifdef NTOPNG_PRO |
981 | | bool get_partial_traffic_stats_view(PartializableFlowTrafficStats* delta, |
982 | | bool* first_partial); |
983 | | #endif |
984 | | bool update_partial_traffic_stats_db_dump(); |
985 | 2.16k | inline float get_pkts_thpt() const { return (pkts_thpt); }; |
986 | 2.16k | inline float get_bytes_thpt() const { return (bytes_thpt); }; |
987 | 2.16k | inline float get_goodput_bytes_thpt() const { return (goodput_bytes_thpt); }; |
988 | 0 | inline float get_goodput_ratio() const { |
989 | 0 | return ((float)(100 * get_goodput_bytes()) / ((float)get_bytes() + 1)); |
990 | 0 | }; |
991 | 0 | inline time_t get_partial_first_seen() const { |
992 | 0 | return (last_db_dump.first_seen); |
993 | 0 | }; |
994 | 0 | inline time_t get_partial_last_seen() const { |
995 | 0 | return (last_db_dump.last_seen); |
996 | 0 | }; |
997 | 0 | inline char* get_protocol_name() const { |
998 | 0 | return (Utils::l4proto2name(protocol)); |
999 | 0 | }; |
1000 | | |
1001 | 52.9k | inline Host* get_cli_host() const { return (cli_host); }; |
1002 | 52.9k | inline Host* get_srv_host() const { return (srv_host); }; |
1003 | | u_int64_t getTags(); |
1004 | 84.7k | inline IpAddress* get_cli_ip_addr() const { return (cli_ip_addr); }; |
1005 | 60.1k | inline IpAddress* get_srv_ip_addr() const { return (srv_ip_addr); }; |
1006 | 0 | inline IpAddress* get_dns_srv_ip_addr() const { |
1007 | 0 | return ((get_cli_port() == 53) ? get_cli_ip_addr() : get_srv_ip_addr()); |
1008 | 0 | }; |
1009 | 0 | inline IpAddress* get_dhcp_srv_ip_addr() const { |
1010 | 0 | return ((get_cli_port() == 67) ? get_cli_ip_addr() : get_srv_ip_addr()); |
1011 | 0 | }; |
1012 | | |
1013 | 0 | inline json_object* get_json_info() const { return (json_info); }; |
1014 | 0 | inline ndpi_serializer* get_tlv_info() const { return (tlv_info); }; |
1015 | 775 | inline void setICMPPayloadSize(u_int16_t size) { |
1016 | 775 | if (isICMP()) |
1017 | 767 | protos.icmp.max_icmp_payload_size = |
1018 | 767 | max(protos.icmp.max_icmp_payload_size, size); |
1019 | 775 | }; |
1020 | 0 | inline u_int16_t getICMPPayloadSize() const { |
1021 | 0 | return (isICMP() ? protos.icmp.max_icmp_payload_size : 0); |
1022 | 0 | }; |
1023 | 0 | inline ICMPinfo* getICMPInfo() const { return (isICMP() ? icmp_info : NULL); } |
1024 | 0 | inline ndpi_protocol_breed_t get_protocol_breed() const { |
1025 | 0 | return (flow_breed); |
1026 | 0 | } |
1027 | 0 | inline const char* get_protocol_breed_name() const { |
1028 | 0 | return (ndpi_get_proto_breed_name(get_protocol_breed())); |
1029 | 0 | }; |
1030 | 49.5k | inline ndpi_protocol_category_t get_protocol_category() const { |
1031 | 49.5k | return (flow_category); |
1032 | 49.5k | }; |
1033 | | |
1034 | 0 | inline const char* get_protocol_category_name() const { |
1035 | 0 | return (ndpi_category_get_name(iface->get_ndpi_struct(), |
1036 | 0 | get_protocol_category())); |
1037 | 0 | }; |
1038 | 0 | char* get_detected_protocol_name(char* buf, u_int buf_len) const { |
1039 | 0 | return (iface->get_ndpi_full_proto_name(isDetectionCompleted() |
1040 | 0 | ? ndpiDetectedProtocol |
1041 | 0 | : getConstNdpiUnknownProtocol(), |
1042 | 0 | buf, buf_len)); |
1043 | 0 | } |
1044 | 11.0k | static inline ndpi_protocol get_ndpi_unknown_protocol() { |
1045 | 11.0k | return getConstNdpiUnknownProtocol(); |
1046 | 11.0k | }; |
1047 | | |
1048 | | #ifdef NTOPNG_PRO |
1049 | | /* NOTE: the caller must ensure that the hosts returned by these methods are |
1050 | | * not used concurrently by subinterfaces since hosts are shared between all |
1051 | | * the subinterfaces of the same ViewInterface. */ |
1052 | | inline Host* getViewSharedClient() { |
1053 | | return (viewFlowStats ? viewFlowStats->getViewSharedClient() |
1054 | | : get_cli_host()); |
1055 | | }; |
1056 | | inline Host* getViewSharedServer() { |
1057 | | return (viewFlowStats ? viewFlowStats->getViewSharedServer() |
1058 | | : get_srv_host()); |
1059 | | }; |
1060 | | #else |
1061 | 10.8k | inline Host* getViewSharedClient() { return (get_cli_host()); } |
1062 | 10.8k | inline Host* getViewSharedServer() { return (get_srv_host()); } |
1063 | | #endif |
1064 | | |
1065 | | u_int32_t get_packetsLost(); |
1066 | | u_int32_t get_packetsRetr(); |
1067 | | u_int32_t get_packetsOOO(); |
1068 | 0 | inline bool isUnderNetworkIssues(time_t now) { |
1069 | 0 | return tcp && tcp->last_network_issues >= now - 1; |
1070 | 0 | }; |
1071 | | |
1072 | 5.17k | inline const struct timeval* get_current_update_time() const { |
1073 | 5.17k | return &last_update_time; |
1074 | 5.17k | }; |
1075 | | u_int64_t get_current_bytes_cli2srv() const; |
1076 | | u_int64_t get_current_bytes_srv2cli() const; |
1077 | | u_int64_t get_current_goodput_bytes_cli2srv() const; |
1078 | | u_int64_t get_current_goodput_bytes_srv2cli() const; |
1079 | | u_int64_t get_current_packets_cli2srv() const; |
1080 | | u_int64_t get_current_packets_srv2cli() const; |
1081 | | void request_swap(); |
1082 | 54.5k | inline bool is_swap_requested() const { |
1083 | 54.5k | return (swap_requested ? true : false); |
1084 | 54.5k | }; |
1085 | 2.60k | inline bool is_swap_done() const { return (swap_done ? true : false); }; |
1086 | 0 | inline void set_swap_done() { swap_done = 1; }; |
1087 | | /* |
1088 | | Returns actual client and server, that is the client and server as |
1089 | | determined after the swap heuristic that has taken place. |
1090 | | */ |
1091 | | inline void get_actual_peers(Host** actual_client, |
1092 | 27.5k | Host** actual_server) const { |
1093 | 27.5k | if (is_swap_requested()) |
1094 | 6.15k | *actual_client = get_srv_host(), *actual_server = get_cli_host(); |
1095 | 21.4k | else |
1096 | 21.4k | *actual_client = get_cli_host(), *actual_server = get_srv_host(); |
1097 | 27.5k | }; |
1098 | | bool is_hash_entry_state_idle_transition_ready(); |
1099 | | void hosts_periodic_stats_update(NetworkInterface* iface, Host* cli_host, |
1100 | | Host* srv_host, |
1101 | | PartializableFlowTrafficStats* partial, |
1102 | | bool first_partial, |
1103 | | const struct timeval* tv); |
1104 | | void periodic_stats_update(const struct timeval* tv, bool force_update); |
1105 | | void flow_end_stats_update(); |
1106 | | void flow_end_housekeeping(); |
1107 | | void set_hash_entry_id(u_int32_t assigned_hash_entry_id); |
1108 | | u_int32_t get_hash_entry_id() const; |
1109 | | |
1110 | | static char* printTCPflags(u_int8_t flags, char* const buf, u_int buf_len); |
1111 | | char* print(char* buf, u_int buf_len, bool full_report = true); |
1112 | | |
1113 | 5.87k | inline u_int32_t key() { return (flow_key); } |
1114 | | static u_int32_t key(Host* cli, u_int16_t cli_port, Host* srv, |
1115 | | u_int16_t srv_port, u_int16_t vlan_id, |
1116 | | u_int16_t _observation_point_id, u_int16_t protocol); |
1117 | | void lua(lua_State* vm, AddressTree* allowed_nets, DetailsLevel details_level, |
1118 | | bool asListElement); |
1119 | | void lua_get_min_info(lua_State* vm); |
1120 | | void lua_duration_info(lua_State* vm); |
1121 | | void lua_dump_tcp_stats(lua_State* vm, const TCPStats* s, |
1122 | | const char* label) const; |
1123 | | void lua_snmp_info(lua_State* vm); |
1124 | | void lua_device_protocol_allowed_info(lua_State* vm); |
1125 | | void lua_get_flow_connection_state(lua_State* vm); |
1126 | | void lua_get_unicast_info(lua_State* vm) const; |
1127 | | void lua_get_status(lua_State* vm) const; |
1128 | | void lua_get_protocols(lua_State* vm) const; |
1129 | | void lua_get_bytes(lua_State* vm) const; |
1130 | | void lua_get_dir_traffic(lua_State* vm, bool cli2srv) const; |
1131 | | void lua_get_dir_iat(lua_State* vm, bool cli2srv) const; |
1132 | | void lua_get_packets(lua_State* vm) const; |
1133 | | void lua_get_throughput(lua_State* vm) const; |
1134 | | void lua_get_time(lua_State* vm) const; |
1135 | | void lua_get_ip(lua_State* vm, bool client) const; |
1136 | | void lua_get_mac(lua_State* vm, bool client) const; |
1137 | | void lua_get_info(lua_State* vm, bool client) const; |
1138 | | void lua_get_sip_info(lua_State* vm) const; |
1139 | | void lua_get_tls_info(lua_State* vm) const; |
1140 | | void lua_get_ssh_info(lua_State* vm) const; |
1141 | | void lua_get_http_info(lua_State* vm) const; |
1142 | | void lua_get_dns_info(lua_State* vm) const; |
1143 | | void lua_get_tcp_info(lua_State* vm) const; |
1144 | | void lua_get_port(lua_State* vm, bool client) const; |
1145 | | void lua_get_geoloc(lua_State* vm, bool client, bool coords, |
1146 | | bool country_city) const; |
1147 | | #if defined(NTOPNG_PRO) |
1148 | | void lua_get_qoe_score(lua_State* vm); |
1149 | | #endif |
1150 | | void lua_get_risk_info(lua_State* vm); |
1151 | | |
1152 | | void getInfo(ndpi_serializer* serializer); |
1153 | | void getHTTPInfo(ndpi_serializer* serializer) const; |
1154 | | void getDNSInfo(ndpi_serializer* serializer) const; |
1155 | | void getICMPInfo(ndpi_serializer* serializer) const; |
1156 | | void getTLSInfo(ndpi_serializer* serializer) const; |
1157 | | void getMDNSInfo(ndpi_serializer* serializer) const; |
1158 | | void getNetBiosInfo(ndpi_serializer* serializer) const; |
1159 | | void getSIPInfo(ndpi_serializer* serializer) const; |
1160 | | void getSSHInfo(ndpi_serializer* serializer) const; |
1161 | | |
1162 | | bool equal(const Mac* src_mac, const Mac* dst_mac, const IpAddress* _cli_ip, |
1163 | | const IpAddress* _srv_ip, u_int16_t _cli_port, u_int16_t _srv_port, |
1164 | | u_int16_t _u_int16_t, u_int16_t _observation_point_id, |
1165 | | u_int32_t _private_flow_id, u_int8_t _protocol, |
1166 | | const ICMPinfo* const icmp_info, bool* src2srv_direction) const; |
1167 | | void getFingerprintInfo(ndpi_serializer* serializer); |
1168 | | void serializeExporters(ndpi_serializer* serializer); |
1169 | | void sumStats(nDPIStats* ndpi_stats, FlowStats* stats); |
1170 | | bool dump(time_t t, bool last_dump_before_free); |
1171 | | bool match(AddressTree* ptree); |
1172 | | bool matchFlowIP(IpAddress* ip, u_int16_t vlan_id); |
1173 | | bool matchFlowVLAN(u_int16_t vlan_id); |
1174 | | bool matchFlowDeviceIP(struct ndpi_in6_addr *flow_device_ip); |
1175 | | bool matchInIfIdx(u_int32_t in_if_idx); |
1176 | | bool matchOutIfIdx(u_int32_t out_if_idx); |
1177 | | bool matchAlertsStatus(u_int32_t out_if_idx); |
1178 | | void dissectHTTP(bool src2dst_direction, char* payload, |
1179 | | u_int16_t payload_len); |
1180 | | void dissectDNS(bool src2dst_direction, char* payload, u_int16_t payload_len); |
1181 | | void dissectTLS(char* payload, u_int16_t payload_len); |
1182 | | void dissectSSDP(bool src2dst_direction, char* payload, |
1183 | | u_int16_t payload_len); |
1184 | | void dissectMDNS(u_int8_t* payload, u_int16_t payload_len); |
1185 | | void dissectNetBIOS(u_int8_t* payload, u_int16_t payload_len); |
1186 | | void dissectBittorrent(char* payload, u_int16_t payload_len); |
1187 | | void fillZMQFlowCategory(ndpi_protocol* res); |
1188 | | void setDHCPHostName(const char* name); |
1189 | | void setSIPCallId(const char* name); |
1190 | | inline void setICMP(bool src2dst_direction, u_int8_t icmp_type, |
1191 | 775 | u_int8_t icmp_code, u_int8_t* icmpdata) { |
1192 | 775 | if (isICMP()) { |
1193 | 767 | if (src2dst_direction) |
1194 | 699 | protos.icmp.cli2srv.icmp_type = icmp_type, |
1195 | 699 | protos.icmp.cli2srv.icmp_code = icmp_code; |
1196 | 68 | else |
1197 | 68 | protos.icmp.srv2cli.icmp_type = icmp_type, |
1198 | 68 | protos.icmp.srv2cli.icmp_code = icmp_code; |
1199 | | // if(get_cli_host()) get_cli_host()->incICMP(icmp_type, icmp_code, |
1200 | | // src2dst_direction ? true : false, get_srv_host()); if(get_srv_host()) |
1201 | | // get_srv_host()->incICMP(icmp_type, icmp_code, src2dst_direction ? false |
1202 | | // : true, get_cli_host()); |
1203 | 767 | } |
1204 | 775 | } |
1205 | 0 | inline void getICMP(u_int8_t* _icmp_type, u_int8_t* _icmp_code) { |
1206 | 0 | if (isBidirectional()) |
1207 | 0 | *_icmp_type = protos.icmp.srv2cli.icmp_type, |
1208 | 0 | *_icmp_code = protos.icmp.srv2cli.icmp_code; |
1209 | 0 | else |
1210 | 0 | *_icmp_type = protos.icmp.cli2srv.icmp_type, |
1211 | 0 | *_icmp_code = protos.icmp.cli2srv.icmp_code; |
1212 | 0 | } |
1213 | 0 | inline u_int8_t getICMPType() { |
1214 | 0 | if (isICMP()) { |
1215 | 0 | return isBidirectional() ? protos.icmp.srv2cli.icmp_type |
1216 | 0 | : protos.icmp.cli2srv.icmp_type; |
1217 | 0 | } |
1218 | 0 |
|
1219 | 0 | return 0; |
1220 | 0 | } |
1221 | | |
1222 | 0 | inline bool hasInvalidDNSQueryChars() const { |
1223 | 0 | return (isDNS() && hasRisk(NDPI_INVALID_CHARACTERS)); |
1224 | 0 | } |
1225 | 0 | inline bool hasMaliciousSignature(bool as_client) const { |
1226 | 0 | return as_client ? has_malicious_cli_signature |
1227 | 0 | : has_malicious_srv_signature; |
1228 | 0 | } |
1229 | | |
1230 | | void setRisk(ndpi_risk r); |
1231 | | void addRisk(ndpi_risk r); |
1232 | 0 | inline ndpi_risk getRiskBitmap() const { return ndpi_flow_risk_bitmap; } |
1233 | | bool hasRisk(ndpi_risk_enum r) const; |
1234 | | bool hasRisks() const; |
1235 | | void clearRisks(); |
1236 | 0 | inline void setDGADomain(char* name) { |
1237 | 0 | if (name) { |
1238 | 0 | if (suspicious_dga_domain) free(suspicious_dga_domain); |
1239 | 0 | suspicious_dga_domain = strdup(name); |
1240 | 0 | } |
1241 | 0 | } |
1242 | 0 | inline char* getDGADomain() const { |
1243 | 0 | return (hasRisk(NDPI_SUSPICIOUS_DGA_DOMAIN) && suspicious_dga_domain |
1244 | 0 | ? suspicious_dga_domain |
1245 | 0 | : (char*)""); |
1246 | 0 | } |
1247 | 0 | inline char* getDNSQuery() const { |
1248 | 0 | return (isDNS() ? protos.dns.last_query : (char*)""); |
1249 | 0 | } |
1250 | | bool setDNSQuery(char* value, char* rsp_addresses, bool copy_memory); |
1251 | 0 | inline void setDNSQueryType(u_int16_t t) { |
1252 | 0 | if (isDNS()) { |
1253 | 0 | protos.dns.last_query_type = t; |
1254 | 0 | } |
1255 | 0 | } |
1256 | 0 | inline void setDNSRetCode(u_int16_t c) { |
1257 | 0 | if (isDNS()) { |
1258 | 0 | protos.dns.last_return_code = c; |
1259 | 0 | } |
1260 | 0 | } |
1261 | 99 | inline u_int16_t getLastQueryType() { |
1262 | 99 | return (isDNS() ? protos.dns.last_query_type : 0); |
1263 | 99 | } |
1264 | 35 | inline u_int16_t getDNSRetCode() { |
1265 | 35 | return (isDNS() ? protos.dns.last_return_code : 0); |
1266 | 35 | } |
1267 | 0 | inline char* getHTTPURL() { |
1268 | 0 | return (isHTTP() ? protos.http.last_url : (char*)""); |
1269 | 0 | } |
1270 | 0 | inline void setHTTPURL(char* v) { |
1271 | 0 | if (isHTTP()) { |
1272 | 0 | if (!protos.http.last_url) |
1273 | 0 | protos.http.last_url = v; |
1274 | 0 | else |
1275 | 0 | free(v); |
1276 | 0 | } else { |
1277 | 0 | if (v) free(v); |
1278 | 0 | } |
1279 | 0 | } |
1280 | 0 | inline char* getHTTPUserAgent() { |
1281 | 0 | return (isHTTP() ? protos.http.last_user_agent : (char*)""); |
1282 | 0 | } |
1283 | 0 | inline void setHTTPUserAgent(char* v) { |
1284 | 0 | if (isHTTP()) { |
1285 | 0 | if (!protos.http.last_user_agent) |
1286 | 0 | protos.http.last_user_agent = v; |
1287 | 0 | else |
1288 | 0 | free(v); |
1289 | 0 | } else { |
1290 | 0 | if (v) free(v); |
1291 | 0 | } |
1292 | 0 | } |
1293 | | void setHTTPMethod(const char* method, ssize_t method_len); |
1294 | | void setHTTPMethod(ndpi_http_method m); |
1295 | 0 | inline void setHTTPRetCode(u_int16_t c) { |
1296 | 0 | if (isHTTP()) { |
1297 | 0 | protos.http.last_return_code = c; |
1298 | 0 | } |
1299 | 0 | } |
1300 | 0 | inline u_int16_t getHTTPRetCode() const { |
1301 | 0 | return isHTTP() ? protos.http.last_return_code : 0; |
1302 | 0 | }; |
1303 | 0 | inline const char* getHTTPMethod() const { |
1304 | 0 | return isHTTP() ? ndpi_http_method2str(protos.http.last_method) : (char*)""; |
1305 | 0 | }; |
1306 | | |
1307 | | void setExternalAlert(json_object* a); |
1308 | 0 | inline bool hasExternalAlert() const { return external_alert.json != NULL; }; |
1309 | 0 | inline json_object* getExternalAlert() { return external_alert.json; }; |
1310 | 0 | inline char* getExternalSource() { return external_alert.source; }; |
1311 | | void luaRetrieveExternalAlert(lua_State* vm); |
1312 | | |
1313 | | u_int32_t getSrvTcpIssues(); |
1314 | | u_int32_t getCliTcpIssues(); |
1315 | | double getCliRetrPercentage(); |
1316 | | double getSrvRetrPercentage(); |
1317 | | |
1318 | | #if defined(NTOPNG_PRO) |
1319 | | void updateTCPAck(const struct bpf_timeval* when, bool src2dst_direction, |
1320 | | u_int32_t ack_id); |
1321 | | void updateTCPWinScale(bool src2dst_direction, u_int8_t winscale); |
1322 | | void updateTCPWin(bool src2dst_direction, u_int16_t win); |
1323 | | void getModbusInfo(ndpi_serializer* serializer); |
1324 | | void getS7CommInfo(ndpi_serializer* serializer); |
1325 | | void getProfinetInfo(ndpi_serializer* serializer); |
1326 | | |
1327 | | #if !defined(HAVE_NEDGE) |
1328 | | #ifdef HAVE_NBPF |
1329 | | inline void updateProfile() { trafficProfile = iface->getFlowProfile(this); } |
1330 | | #endif |
1331 | | #endif |
1332 | | inline char* get_profile_name() { |
1333 | | return ( |
1334 | | #if !defined(HAVE_NEDGE) |
1335 | | #ifdef HAVE_NBPF |
1336 | | trafficProfile ? trafficProfile->getName() : |
1337 | | #endif |
1338 | | #endif |
1339 | | (char*)""); |
1340 | | } |
1341 | | #endif |
1342 | | /* http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/ |
1343 | | */ |
1344 | 0 | inline float getCli2SrvMaxThpt() const { |
1345 | 0 | if (tcp == NULL) |
1346 | 0 | return (0); |
1347 | 0 | else |
1348 | 0 | return (rttSec ? ((float)(tcp->cli2srv_window * 8) / rttSec) : 0); |
1349 | 0 | } |
1350 | 0 | inline float getSrv2CliMaxThpt() const { |
1351 | 0 | if (tcp == NULL) |
1352 | 0 | return (0); |
1353 | 0 | else |
1354 | 0 | return (rttSec ? ((float)(tcp->srv2cli_window * 8) / rttSec) : 0); |
1355 | 0 | } |
1356 | | |
1357 | 6.61k | inline InterarrivalStats* getCli2SrvIATStats() const { |
1358 | 6.61k | return cli2srvPktTime; |
1359 | 6.61k | } |
1360 | 610 | inline InterarrivalStats* getSrv2CliIATStats() const { |
1361 | 610 | return srv2cliPktTime; |
1362 | 610 | } |
1363 | | |
1364 | 29.9k | inline bool isTCP() const { return protocol == IPPROTO_TCP; }; |
1365 | 2.85k | inline bool isUDP() const { return protocol == IPPROTO_UDP; }; |
1366 | 0 | inline bool isTCPEstablished() const { |
1367 | 0 | return (!isTCPClosed() && !isTCPReset() && isThreeWayHandshakeOK()); |
1368 | 0 | } |
1369 | 0 | inline bool isTCPConnecting() const { |
1370 | 0 | if (tcp == NULL) |
1371 | 0 | return (false); |
1372 | 0 | else |
1373 | 0 | return (src2dst_tcp_flags == TH_SYN && |
1374 | 0 | (!dst2src_tcp_flags || (dst2src_tcp_flags == (TH_SYN | TH_ACK)))); |
1375 | 0 | } |
1376 | 0 | inline bool isTCPClosed() const { |
1377 | 0 | if (tcp == NULL) |
1378 | 0 | return (false); |
1379 | 0 | else |
1380 | 0 | return (((src2dst_tcp_flags & (TH_SYN | TH_ACK | TH_FIN)) == |
1381 | 0 | (TH_SYN | TH_ACK | TH_FIN)) && |
1382 | 0 | ((dst2src_tcp_flags & (TH_SYN | TH_ACK | TH_FIN)) == |
1383 | 0 | (TH_SYN | TH_ACK | TH_FIN))); |
1384 | 0 | } |
1385 | 0 | inline bool isTCPReset() const { |
1386 | 0 | if (tcp == NULL) |
1387 | 0 | return (false); |
1388 | 0 | else |
1389 | 0 | return (!isTCPClosed() && |
1390 | 0 | ((src2dst_tcp_flags & TH_RST) || (dst2src_tcp_flags & TH_RST))); |
1391 | 0 | }; |
1392 | 0 | inline bool isOnlyTCPReset() const { |
1393 | 0 | if (tcp == NULL) |
1394 | 0 | return (false); |
1395 | 0 | else |
1396 | 0 | return ((src2dst_tcp_flags & TH_RST) || (dst2src_tcp_flags & TH_RST)); |
1397 | 0 | } |
1398 | 0 | inline bool isTCPRefused() const { |
1399 | 0 | if (tcp == NULL) |
1400 | 0 | return (false); |
1401 | 0 | else |
1402 | 0 | return (!isThreeWayHandshakeOK() && |
1403 | 0 | (dst2src_tcp_flags & TH_RST) == TH_RST); |
1404 | 0 | }; |
1405 | 0 | inline bool isTCPZeroWindow() const { |
1406 | 0 | return (src2dst_tcp_zero_window || dst2src_tcp_zero_window); |
1407 | 0 | }; |
1408 | 0 | inline void setVRFid(u_int32_t v) { |
1409 | 0 | allocateCollection(); |
1410 | 0 | if (collection) collection->vrfId = v; |
1411 | 0 | } |
1412 | 0 | inline void setSrcPeerAS(u_int32_t v) { |
1413 | 0 | if(v != srcAS) srcPeerAS = v; |
1414 | 0 | } /* Used when collecting flows via ZMQ (usually it contains the peer AS) */ |
1415 | 0 | inline void setDstPeerAS(u_int32_t v) { |
1416 | 0 | if(v != dstAS) dstPeerAS = v; |
1417 | 0 | } /* Used when collecting flows via ZMQ (usually it contains the peer AS) */ |
1418 | 0 | inline void setPrevAdjacentAS(u_int32_t v) { |
1419 | 0 | allocateCollection(); |
1420 | 0 | if (collection) collection->prevAdjacentAS = v; |
1421 | 0 | } |
1422 | 0 | inline void setNextAdjacentAS(u_int32_t v) { |
1423 | 0 | allocateCollection(); |
1424 | 0 | if (collection) collection->nextAdjacentAS = v; |
1425 | 0 | } |
1426 | | |
1427 | | #ifdef NTOPNG_PRO |
1428 | | inline ViewInterfaceFlowStats* getViewInterfaceFlowStats() { |
1429 | | return (viewFlowStats); |
1430 | | } |
1431 | | |
1432 | | void postDetectionCallback(); |
1433 | | #endif |
1434 | | |
1435 | 0 | inline double getFlowRTT(bool client) const { |
1436 | 0 | if (tcp == NULL) |
1437 | 0 | return (0.0); |
1438 | 0 | else |
1439 | 0 | return client ? tcp->clientRTT3WH : tcp->serverRTT3WH; |
1440 | 0 | }; |
1441 | | |
1442 | 0 | inline void setFlowRTT(const struct timeval* const tv, bool client) { |
1443 | 0 | allocTCPStats(); |
1444 | |
|
1445 | 0 | if (tcp != NULL) { |
1446 | 0 | if (client) { |
1447 | 0 | tcp->clientRTT3WH = Utils::timeval2ms(tv); |
1448 | |
|
1449 | 0 | if (cli_host) cli_host->updateNetworkRTT(tcp->clientRTT3WH); |
1450 | 0 | } else { |
1451 | 0 | tcp->serverRTT3WH = Utils::timeval2ms(tv); |
1452 | |
|
1453 | 0 | if (srv_host) srv_host->updateNetworkRTT(tcp->serverRTT3WH); |
1454 | 0 | } |
1455 | 0 | } |
1456 | 0 | } |
1457 | | |
1458 | 0 | inline void setFlowTcpWindow(u_int16_t window_val, bool client) { |
1459 | 0 | allocTCPStats(); |
1460 | 0 | if (tcp != NULL) { |
1461 | 0 | if (client) |
1462 | 0 | tcp->cli2srv_window = window_val; |
1463 | 0 | else |
1464 | 0 | tcp->srv2cli_window = window_val; |
1465 | 0 | } |
1466 | 0 | } |
1467 | 41 | inline void setRTT() { |
1468 | 41 | allocTCPStats(); |
1469 | | |
1470 | 41 | if (tcp != NULL) rttSec = (tcp->serverRTT3WH + tcp->clientRTT3WH) / 1000.; |
1471 | 41 | } |
1472 | 0 | inline void setFlowApplLatency(float latency_msecs) { |
1473 | 0 | applLatencyMsec = latency_msecs; |
1474 | 0 | } |
1475 | 0 | inline float getFlowApplLatency() const { return (applLatencyMsec); } |
1476 | | |
1477 | | struct ndpi_in6_addr getExporterIP(); |
1478 | | struct ndpi_in6_addr getOriginalExporterIP(); |
1479 | | struct ndpi_in6_addr getNextHopIP(); |
1480 | | struct ndpi_in6_addr getOriginalNextHopIP(); |
1481 | | u_int32_t getInIndex(); |
1482 | | u_int32_t getOutIndex(); |
1483 | | SNMPInterfaceRole getInRole(); |
1484 | | SNMPInterfaceRole getOutRole(); |
1485 | | SNMPInterfaceRole getMainRole(); |
1486 | | |
1487 | 0 | inline u_int16_t getObservationPointId() { return (observation_point_id); }; |
1488 | | |
1489 | | u_int16_t getExporterSiteId(); |
1490 | | u_int16_t getNextHopSiteId(); |
1491 | | u_int16_t getSrcNetworkSiteId(); |
1492 | | u_int16_t getDstNetworkSiteId(); |
1493 | | |
1494 | 0 | inline const u_int16_t getScore() const { return (flow_score); }; |
1495 | | |
1496 | | #ifdef HAVE_NEDGE |
1497 | | inline void setLastConntrackUpdate(u_int32_t when) { |
1498 | | last_conntrack_update = when; |
1499 | | } |
1500 | | inline u_int32_t getLastConntrackUpdate() { return (last_conntrack_update); } |
1501 | | bool isNetfilterIdleFlow() const; |
1502 | | |
1503 | | void setPacketsBytes(time_t now, u_int32_t s2d_pkts, u_int32_t d2s_pkts, |
1504 | | u_int64_t s2d_bytes, u_int64_t d2s_bytes, |
1505 | | u_int32_t *delta_pkts /* out */, |
1506 | | u_int64_t *delta_bytes /* out */); |
1507 | | void getFlowShapers(TrafficShaper** shaper_cli, TrafficShaper** shaper_srv) { |
1508 | | *shaper_cli = flowShapers.cli; |
1509 | | *shaper_srv = flowShapers.srv; |
1510 | | } |
1511 | | bool updateCliSrvShapers(TrafficShaper** ingress_shaper, |
1512 | | TrafficShaper** egress_shaper); |
1513 | | void updateFlowShapers(bool first_update = false); |
1514 | | void recheckQuota(const struct tm* now); |
1515 | | inline u_int8_t getFlowRoutingTableId() { return (routing_table_id); } |
1516 | | inline void setIngress2EgressDirection(bool _ingress2egress) { |
1517 | | ingress2egress_direction = _ingress2egress; |
1518 | | } |
1519 | | inline bool isIngress2EgressDirection() { return (ingress2egress_direction); } |
1520 | | void fillDynamicPoolBlacklist(); |
1521 | | #endif |
1522 | | void housekeep(time_t t); |
1523 | | void setParsedeBPFInfo(const ParsedeBPF* const _ebpf, bool swap_directions); |
1524 | 0 | inline const ContainerInfo* getClientContainerInfo() const { |
1525 | 0 | return ebpf && ebpf->container_info_set ? &ebpf->src_container_info : NULL; |
1526 | 0 | } |
1527 | 0 | inline const ContainerInfo* getServerContainerInfo() const { |
1528 | 0 | return ebpf && ebpf->container_info_set ? &ebpf->dst_container_info : NULL; |
1529 | 0 | } |
1530 | 0 | inline const ProcessInfo* getClientProcessInfo() const { |
1531 | 0 | return ebpf && ebpf->process_info_set ? &ebpf->src_process_info : NULL; |
1532 | 0 | } |
1533 | 0 | inline const ProcessInfo* getServerProcessInfo() const { |
1534 | 0 | return ebpf && ebpf->process_info_set ? &ebpf->dst_process_info : NULL; |
1535 | 0 | } |
1536 | 0 | inline const TcpInfo* getClientTcpInfo() const { |
1537 | 0 | return ebpf && ebpf->tcp_info_set ? &ebpf->src_tcp_info : NULL; |
1538 | 0 | } |
1539 | 0 | inline const TcpInfo* getServerTcpInfo() const { |
1540 | 0 | return ebpf && ebpf->tcp_info_set ? &ebpf->dst_tcp_info : NULL; |
1541 | 0 | } |
1542 | | |
1543 | 0 | inline bool isNotPurged() { |
1544 | 0 | return (getInterface()->isPacketInterface() && |
1545 | 0 | getInterface()->is_purge_idle_interface() && (!idle()) && |
1546 | 0 | is_active_entry_now_idle(10 * getInterface()->getFlowMaxIdle())); |
1547 | 0 | } |
1548 | | |
1549 | 0 | inline u_int16_t getTLSVersion() { |
1550 | 0 | return (isTLS() ? protos.tls.tls_version : 0); |
1551 | 0 | } |
1552 | 0 | inline u_int32_t getTLSNotBefore() { |
1553 | 0 | return (isTLS() ? protos.tls.notBefore : 0); |
1554 | 0 | }; |
1555 | 0 | inline u_int32_t getTLSNotAfter() { |
1556 | 0 | return (isTLS() ? protos.tls.notAfter : 0); |
1557 | 0 | }; |
1558 | 0 | inline char* getTLSCertificateIssuerDN() { |
1559 | 0 | return (isTLS() ? protos.tls.issuerDN : NULL); |
1560 | 0 | } |
1561 | 0 | inline char* getTLSCertificateSubjectDN() { |
1562 | 0 | return (isTLS() ? protos.tls.subjectDN : NULL); |
1563 | 0 | } |
1564 | | void setTLSCertificateIssuerDN(char* issuer); |
1565 | | void setTCPFingerprint(char* fp); |
1566 | | void setnDPIFingerprint(char* fp); |
1567 | 0 | inline char* getTCPFingerprint() { return (tcp_fingerprint); } |
1568 | 0 | inline char* getnDPIFingerprint() { return (ndpi_fingerprint); } |
1569 | | |
1570 | | /* For now, the check is only on the nDPI fingerprint, but it will |
1571 | | need to be extended to the TCP fingerprint and JA4 when they are |
1572 | | merged into the fingerprints block of proto_json_info.*/ |
1573 | 0 | inline bool isFingerprintAvailable() { |
1574 | 0 | return getnDPIFingerprint() != nullptr; |
1575 | 0 | } |
1576 | | |
1577 | 0 | inline void setSearchedField(const char* field) { |
1578 | 0 | snprintf(searched_field, sizeof(searched_field), "%s", field); |
1579 | 0 | } |
1580 | 0 | inline void resetSearchedField() { searched_field[0] = '\0'; } |
1581 | | |
1582 | 7.22k | inline void setTOS(u_int8_t tos, bool is_cli_tos) { |
1583 | 7.22k | if (is_cli_tos) |
1584 | 6.61k | cli2srv_tos = tos; |
1585 | 610 | else |
1586 | 610 | srv2cli_tos = tos; |
1587 | 7.22k | } |
1588 | 0 | inline u_int8_t getTOS(bool is_cli_tos) const { |
1589 | 0 | return (is_cli_tos ? cli2srv_tos : srv2cli_tos); |
1590 | 0 | } |
1591 | | |
1592 | 29.2k | inline u_int8_t getCli2SrvDSCP() const { return (cli2srv_tos & 0xFC) >> 2; } |
1593 | 14.6k | inline u_int8_t getSrv2CliDSCP() const { return (srv2cli_tos & 0xFC) >> 2; } |
1594 | | |
1595 | 0 | inline u_int8_t getCli2SrvECN() { return (cli2srv_tos & 0x3); } |
1596 | 0 | inline u_int8_t getSrv2CliECN() { return (srv2cli_tos & 0x3); } |
1597 | | |
1598 | 0 | inline float getICMPPacketsEntropy() { |
1599 | 0 | return (protos.icmp.client_to_server.max_entropy - |
1600 | 0 | protos.icmp.client_to_server.min_entropy); |
1601 | 0 | } |
1602 | | |
1603 | 0 | inline bool timeToPeriodicDump(u_int sec) { |
1604 | 0 | return ((sec - get_first_seen() >= CONST_DB_DUMP_FREQUENCY) && |
1605 | 0 | (sec - get_partial_last_seen() >= CONST_DB_DUMP_FREQUENCY)); |
1606 | 0 | } |
1607 | | |
1608 | | u_char* getCommunityId(u_char* community_id, u_int community_id_len); |
1609 | | void setJSONRiskInfo(char* r); |
1610 | | void setEndReason(char* r); |
1611 | | char* getEndReason(); |
1612 | | void setSMTPMailFrom(char* r); |
1613 | | char* getSMTPMailFrom(); |
1614 | | void setSMTPRcptTo(char* r); |
1615 | | char* getSMTPRcptTo(); |
1616 | | void setFlowRiskName(char* r); |
1617 | | char* getFlowRiskName(); |
1618 | | void serializeJSONRiskInfo(ndpi_serializer* serializer); |
1619 | | void serializeVerdictInfo(ndpi_serializer* serializer); |
1620 | | void serializeTCPFlagsAnalysis(ndpi_serializer* serializer); |
1621 | | void serializeBGPInfo(ndpi_serializer* serializer); |
1622 | | void setWLANInfo(char* wlan_ssid, u_int8_t* wtp_mac_address); |
1623 | | void setClientBGPInfo(char* bgp_info); |
1624 | | void setServerBGPInfo(char* bgp_info); |
1625 | 0 | inline char* getClientBGPInfo() { return((collection && collection->bgp.src) ? collection->bgp.src : (char*)""); } |
1626 | 0 | inline char* getServerBGPInfo() { return((collection && collection->bgp.dst) ? collection->bgp.dst : (char*)""); } |
1627 | 0 | void updateHRSrc2DstBytes(const std::vector<uint64_t>& v, time_t update_first_seen) { |
1628 | 0 | mergeHRCounters(hr_src2dst_bytes, v, update_first_seen); |
1629 | 0 | } |
1630 | 0 | void updateHRDst2SrcBytes(const std::vector<uint64_t>& v, time_t update_first_seen) { |
1631 | 0 | mergeHRCounters(hr_dst2src_bytes, v, update_first_seen); |
1632 | 0 | } |
1633 | 0 | inline const std::vector<uint64_t>& getHRSrc2DstBytes() const { return hr_src2dst_bytes; } |
1634 | 0 | inline const std::vector<uint64_t>& getHRDst2SrcBytes() const { return hr_dst2src_bytes; } |
1635 | 0 | inline void resetHRCounters() { hr_src2dst_bytes.clear(); hr_dst2src_bytes.clear(); hr_base_first_seen = 0; } |
1636 | 0 | char* getWLANSSID() { |
1637 | 0 | return (collection ? collection->wifi.wlan_ssid : NULL); |
1638 | 0 | }; |
1639 | 0 | u_int8_t* getWTPMACAddress() { |
1640 | 0 | return (collection ? collection->wifi.wtp_mac_address : NULL); |
1641 | 0 | }; |
1642 | | |
1643 | 0 | inline FlowTrafficStats* getTrafficStats() { return (&stats); }; |
1644 | 5.87k | inline char* get_custom_category_file() const { |
1645 | 5.87k | if (category_list_name_shared_pointer) |
1646 | 0 | return (category_list_name_shared_pointer); |
1647 | 5.87k | else |
1648 | 5.87k | return ((char*)ndpiDetectedProtocol.custom_category_userdata); |
1649 | 5.87k | } |
1650 | | |
1651 | 0 | inline u_int32_t getErrorCode() { return (protocolErrorCode); } |
1652 | 5.02k | inline void setErrorCode(u_int32_t rc) { protocolErrorCode = rc; } |
1653 | | |
1654 | 0 | inline char* getAddressFamilyProtocol() const { |
1655 | 0 | return (ndpiAddressFamilyProtocol); |
1656 | 0 | } |
1657 | 167 | inline void setAddressFamilyProtocol(char* proto) { |
1658 | 167 | if (ndpiAddressFamilyProtocol) free(ndpiAddressFamilyProtocol); |
1659 | 167 | ndpiAddressFamilyProtocol = proto ? strdup(proto) : NULL; |
1660 | 167 | } |
1661 | | |
1662 | 149 | inline ndpi_confidence_t getConfidence() { return (confidence); } |
1663 | 0 | inline void setConfidence(ndpi_confidence_t rc) { confidence = rc; } |
1664 | 0 | inline void setNdpiConfidence(ndpi_confidence_t rc) { ndpi_confidence = rc; } |
1665 | | |
1666 | 0 | inline u_int8_t getCliLocation() { |
1667 | 0 | if ((cli_host && cli_host->isMulticastHost()) || |
1668 | 0 | (cli_ip_addr && cli_ip_addr->isMulticastAddress())) |
1669 | 0 | return 2; // Multicast host |
1670 | 0 | else if ((cli_host && cli_host->isLocalHost()) || |
1671 | 0 | (cli_ip_addr && cli_ip_addr->isLocalHost())) |
1672 | 0 | return 1; // Local host |
1673 | 0 | else |
1674 | 0 | return 0; // Remote host |
1675 | 0 | } |
1676 | 0 | inline u_int8_t getSrvLocation() { |
1677 | 0 | if ((srv_host && srv_host->isMulticastHost()) || |
1678 | 0 | (srv_ip_addr && srv_ip_addr->isMulticastAddress())) |
1679 | 0 | return 2; // Multicast host |
1680 | 0 | else if ((srv_host && srv_host->isLocalHost()) || |
1681 | 0 | (srv_ip_addr && srv_ip_addr->isLocalHost())) |
1682 | 0 | return 1; // Local host |
1683 | 0 | else |
1684 | 0 | return 0; // Remote host |
1685 | 0 | } |
1686 | | |
1687 | 1.76k | inline u_int32_t getPrivateFlowId() const { return (privateFlowId); } |
1688 | | |
1689 | 0 | inline bool isCustomFlowAlertTriggered() { |
1690 | 0 | return (customFlowAlert.alertTriggered); |
1691 | 0 | } |
1692 | 0 | inline u_int8_t getCustomFlowAlertScore() { return (customFlowAlert.score); } |
1693 | 0 | inline char* getCustomFlowAlertMessage() { return (customFlowAlert.msg); } |
1694 | | void triggerCustomFlowAlert(u_int8_t score, char* msg); |
1695 | 8 | inline void setRTPStreamType(u_int8_t s) { rtp_stream_type = s; } |
1696 | 35 | inline u_int8_t getRTPStreamType() { return (rtp_stream_type); } |
1697 | 0 | inline void setPeriodicFlow(u_int32_t _periodicity) { |
1698 | 0 | is_periodic_flow = 1, periodicity = _periodicity; |
1699 | 0 | } |
1700 | 0 | inline bool isPeriodicFlow() { return (is_periodic_flow ? true : false); } |
1701 | | void swap(); |
1702 | | bool isDPIDetectedFlow(); |
1703 | | void updateHostBlacklists(); |
1704 | 0 | int32_t getInterfaceIndex() { return (iface_index); }; |
1705 | 0 | inline void setFlowSource(FlowSource n) { flow_source = n; } |
1706 | 14.6k | inline FlowSource getFlowSource() { return (flow_source); } |
1707 | 3.89k | inline MinorConnectionStates setCurrentConnectionState(u_int8_t new_state) { |
1708 | 3.89k | current_c_state = static_cast<MinorConnectionStates>(new_state); |
1709 | 3.89k | return (current_c_state); |
1710 | 3.89k | }; |
1711 | 220 | inline MinorConnectionStates getCurrentConnectionState() { |
1712 | 220 | return (current_c_state); |
1713 | 220 | }; |
1714 | | bool checkS1ConnState(); |
1715 | | bool isTCPFlagSet(u_int8_t flags, int flag_to_check); |
1716 | | MinorConnectionStates calculateConnectionState(bool is_cumulative); |
1717 | | MajorConnectionStates getMajorConnState(); |
1718 | 0 | inline u_int32_t getPostNATSrcIp() { |
1719 | 0 | return (collection ? ntohl(collection->nat.src_ip_addr_post_nat) : 0); |
1720 | 0 | }; |
1721 | 0 | inline u_int32_t getPostNATDstIp() { |
1722 | 0 | return (collection ? ntohl(collection->nat.dst_ip_addr_post_nat) : 0); |
1723 | 0 | }; |
1724 | 0 | inline u_int16_t getPostNATSrcPort() { |
1725 | 0 | return (collection ? ntohs(collection->nat.src_port_post_nat) : 0); |
1726 | 0 | }; |
1727 | 0 | inline u_int16_t getPostNATDstPort() { |
1728 | 0 | return (collection ? ntohs(collection->nat.dst_port_post_nat) : 0); |
1729 | 0 | }; |
1730 | | |
1731 | | void getSrcAS(u_int32_t* as, char** as_name); |
1732 | | void getDstAS(u_int32_t* as, char** as_name); |
1733 | | void getTransitAS(u_int32_t* as, char** as_nam); |
1734 | | |
1735 | | TransitAS getTransitASType(); |
1736 | | void setBittorrentHash(char* hash, u_int len); |
1737 | 8.76k | inline bool isFlowAccounted() { return iface_flow_accounted; }; |
1738 | 2.34k | inline void setFlowAccounted() { iface_flow_accounted = 1; }; |
1739 | | void accountFlowTraffic(bool src2dst_direction); |
1740 | | void setICMPTypeCode(u_int16_t icmp_type_code); |
1741 | 0 | inline void setQoE(u_int8_t c2s, u_int8_t s2c) { |
1742 | 0 | if ((c2s != NTOP_QOE_UNKNOWN) || (s2c != NTOP_QOE_UNKNOWN)) |
1743 | 0 | collected_qoe.src_to_dst = c2s, collected_qoe.dst_to_src = s2c, |
1744 | 0 | has_collected_qoe = 1; |
1745 | 0 | } |
1746 | | void setHostTCPFingerprint(char* fp, ndpi_os os_hint); |
1747 | | |
1748 | 0 | u_int32_t getSrcAS() { return (srcAS); } |
1749 | 0 | u_int32_t getDstAS() { return (dstAS); } |
1750 | 0 | u_int32_t getSrcPeerAS() { return (srcPeerAS); } |
1751 | 0 | u_int32_t getDstPeerAS() { return (dstPeerAS); } |
1752 | | |
1753 | 0 | inline Mac* getCliMac() { return (c_mac); } |
1754 | 0 | inline Mac* getSrvMac() { return (s_mac); } |
1755 | | |
1756 | 0 | inline u_int8_t* getCliMacRaw() { return (cli_mac); } |
1757 | 0 | inline u_int8_t* getSrvMacRaw() { return (srv_mac); } |
1758 | 0 | inline void setCliMacRaw(u_int8_t* m) { |
1759 | 0 | memcpy(cli_mac, m, 6); |
1760 | 0 | updateMac(); |
1761 | 0 | }; |
1762 | 0 | inline void setSrvMacRaw(u_int8_t* m) { |
1763 | 0 | memcpy(srv_mac, m, 6); |
1764 | 0 | updateMac(); |
1765 | 0 | }; |
1766 | | |
1767 | | #ifdef HAVE_NEDGE |
1768 | | inline void incNumProcessedPkts() { numFlowProcessedPkts++; } |
1769 | | inline void setNumPktsMarker() { numPktsMarkerSet = numFlowProcessedPkts; } |
1770 | | #endif |
1771 | | |
1772 | | void updateTCPStats(u_int32_t cli_stats, u_int32_t srv_stats); |
1773 | | |
1774 | | void setCliService(int service_enum); |
1775 | | void setSrvService(int service_enum); |
1776 | 0 | inline void setIGMPType(u_int8_t t) { protos.igmp.igmp_type = t; } |
1777 | | void addExporterInfo(struct ndpi_in6_addr *exporter_ip, |
1778 | | struct ndpi_in6_addr *next_hop, |
1779 | | struct ndpi_in6_addr *mapped_exporter_ip, |
1780 | | struct ndpi_in6_addr *mapped_next_hop, |
1781 | | u_int16_t exporter_site_id, |
1782 | | u_int16_t next_hop_site_id, |
1783 | | u_int32_t in_index, u_int32_t out_index, |
1784 | | SNMPInterfaceRole in_role, |
1785 | | SNMPInterfaceRole out_role, |
1786 | | FlowSource source, bool src2dst_direction); |
1787 | | |
1788 | 0 | inline bool isFirstFlowDump() { return(last_db_dump.is_first_dump); } |
1789 | | |
1790 | | u_int64_t get_transit_bytes(); |
1791 | | u_int64_t get_peering_bytes(); |
1792 | | u_int64_t get_ix_bytes(); |
1793 | | }; |
1794 | | |
1795 | | #endif /* _FLOW_H_ */ |