/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_ */ |