File: sinsp.h

package info (click to toggle)
falcosecurity-libs 0.1.1dev%2Bgit20220316.e5c53d64-5.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,732 kB
  • sloc: cpp: 55,770; ansic: 37,330; makefile: 74; sh: 13
file content (1369 lines) | stat: -rw-r--r-- 38,740 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
/*
Copyright (C) 2022 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/*!
	\mainpage libsinsp documentation

	\section Introduction

	libsinsp is a system inspection library written in C++ and implementing high level
	functionality like:
	- live capture control (start/stop/pause...)
	- event capture from file or the live OS
	- OS state reconstruction. By parsing /proc and inspecting the live event stream,
	libsinsp is capable of mirroring the OS process state and putting context around
	key OS primitives like process IDs and file descriptors. That way, these primitives
	can be treated like programs, files, connections and users.
	- parsing of OS events and conversion of events into human-readable strings
	- event filtering

	This manual includes the following sections:
	- \ref inspector
	- \ref event
	- \ref dump
	- \ref filter
	- \ref state
*/

#pragma once

#include "capture_stats_source.h"
#include "container_engine/wmi_handle_source.h"

#ifdef _WIN32
#pragma warning(disable: 4251 4200 4221 4190)
#else
#include "tbb/concurrent_queue.h"
#endif

#include "sinsp_inet.h"
#include "sinsp_public.h"
#include "sinsp_exception.h"

#define __STDC_FORMAT_MACROS

#include <string>
#include <unordered_map>
#include <map>
#include <queue>
#include <vector>
#include <unordered_set>
#include <list>
#include <memory>

using namespace std;

#include <scap.h>
#include "settings.h"
#include "logger.h"
#include "event.h"
#include "filter.h"
#include "dumper.h"
#include "stats.h"
#include "ifinfo.h"
#include "container.h"
#include "viewinfo.h"
#include "utils.h"

#ifndef VISIBILITY_PRIVATE
// Some code defines VISIBILITY_PRIVATE to nothing to get private access to sinsp
#define VISIBILITY_PRIVATE private:
#define VISIBILITY_PROTECTED protected:
#else
#define VISIBILITY_PROTECTED
#endif

#define ONE_SECOND_IN_NS 1000000000LL

#ifdef _WIN32
#define NOCURSESUI
#endif

#include "tuples.h"
#include "fdinfo.h"
#include "threadinfo.h"
#include "ifinfo.h"
#include "eventformatter.h"
#include "sinsp_pd_callback_type.h"

#include "include/sinsp_external_processor.h"
#include "plugin.h"
class sinsp_partial_transaction;
class sinsp_parser;
class sinsp_analyzer;
class sinsp_filter;
class cycle_writer;
class sinsp_protodecoder;
#if !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)
class k8s;
#endif // !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)
class sinsp_partial_tracer;
class mesos;
class sinsp_plugin;

#if defined(HAS_CAPTURE) && !defined(_WIN32)
class sinsp_ssl;
class sinsp_bearer_token;
template <class T> class socket_data_handler;
template <class T> class socket_collector;
class k8s_handler;
class k8s_api_handler;
#endif // HAS_CAPTURE

std::vector<std::string> sinsp_split(const std::string &s, char delim);

/*!
  \brief Information about a group of filter/formatting fields.
*/
class filter_check_info
{
public:
	enum flags
	{
		FL_NONE =   0,
		FL_WORKS_ON_THREAD_TABLE = (1 << 0),	///< This filter check class supports filtering incomplete events that contain only valid thread info and FD info.
		FL_HIDDEN = (1 << 1),	///< This filter check class won't be shown by fields/filter listings.
	};

	filter_check_info()
	{
		m_flags = 0;
	}

	string m_name; ///< Field class name.
	string m_shortdesc; ///< short (< 10 words) description of this filtercheck. Can be blank.
	string m_desc; ///< Field class description.
	int32_t m_nfields; ///< Number of fields in this field group.
	const filtercheck_field_info* m_fields; ///< Array containing m_nfields field descriptions.
	uint32_t m_flags;
};

/*!
  \brief Parameters to configure the download behavior when connected to an
  orchestrator like Kubernetes or mesos.
*/
class metadata_download_params
{
public:
	uint32_t m_data_max_b = K8S_DATA_MAX_B;
	uint32_t m_data_chunk_wait_us = K8S_DATA_CHUNK_WAIT_US;
	uint32_t m_data_watch_freq_sec = METADATA_DATA_WATCH_FREQ_SEC;
};

/*!
  \brief The user agent string to use for any libsinsp connection, can be changed at compile time
*/

#if !defined(LIBSINSP_USER_AGENT)
#define LIBSINSP_USER_AGENT "falcosecurity-libs"
#endif // LIBSINSP_USER_AGENT

/*!
  \brief The default way an event is converted to string by the library
*/
#define DEFAULT_OUTPUT_STR "*%evt.num %evt.time %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.args"

//
// Internal stuff for meta event management
//
typedef void (*meta_event_callback)(sinsp*, void* data);
class sinsp_proc_metainfo
{
public:
	sinsp_evt m_pievt;
	scap_evt* m_piscapevt;
	uint64_t* m_piscapevt_vals;
	uint64_t m_n_procinfo_evts;
	int64_t m_cur_procinfo_evt;
	ppm_proclist_info* m_pli;
};

/** @defgroup inspector Main library
 @{
*/

/*!
  \brief System inspector class.
  This is the library entry point class. The functionality it exports includes:
  - live capture control (start/stop/pause...)
  - trace file management
  - event retrieval
  - setting capture filters
*/
class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source
{
public:
	typedef std::shared_ptr<sinsp> ptr;
	typedef std::set<std::string> k8s_ext_list_t;
	typedef std::shared_ptr<k8s_ext_list_t> k8s_ext_list_ptr_t;

	sinsp(bool static_container = false,
		  const std::string static_id = "",
		  const std::string static_name = "",
		  const std::string static_image = "");
	virtual ~sinsp();

	/*!
	  \brief Start a live event capture.

	  \param timeout_ms the optional read timeout, i.e. the time after which a
	  call to \ref next() returns even if no events are available.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	virtual void open(uint32_t timeout_ms = SCAP_TIMEOUT_MS);

	/*!
	  \brief Start an event capture from a trace file.

	  \param filename the trace file name.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void open(const std::string &filename);

	/*!
	  \brief Start an event capture from a file descriptor.

	  \param fd the file descriptor

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void fdopen(int fd);

	void open_udig(uint32_t timeout_ms = SCAP_TIMEOUT_MS);
	void open_nodriver();

	/*!
	  \brief Ends a capture and release all resources.
	*/
	void close();

	/*!
	  \brief Get the next event from the open capture source

	  \param evt a \ref sinsp_evt pointer that will be initialized to point to
	  the next available event.

	  \return SCAP_SUCCESS if the call is successful and pevent and pcpuid contain
	   valid data. SCAP_TIMEOUT in case the read timeout expired and no event is
	   available. SCAP_EOF when the end of an offline capture is reached.
	   On Failure, SCAP_FAILURE is returned and getlasterr() can be used to
	   obtain the cause of the error.

	  \note: the returned event can be considered valid only until the next
	   call to \ref)
	*/
	virtual int32_t next(OUT sinsp_evt **evt);

	/*!
	  \brief Get the maximum number of bytes currently in use by any CPU buffer
     */
	uint64_t max_buf_used();

	/*!
	  \brief Get the number of events that have been captured and processed
	   since the call to \ref open()

	  \return the number of captured events.
	*/
	uint64_t get_num_events();

	/*!
	  \brief Set the capture snaplen, i.e. the maximum size an event
	  parameter can reach before the driver starts truncating it.

	  \param snaplen the snaplen for this capture instance, in bytes.

	  \note This function can only be called for live captures.
	  \note By default, the driver captures the first 80 bytes of the
	  buffers coming from events like read, write, send, recv, etc.
	  If you're not interested in payloads, smaller values will save
	  capture buffer space and make capture files smaller.
	  Conversely, big values should be used with care because they can
	  easily generate huge capture files.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void set_snaplen(uint32_t snaplen);

	/*!
	  \brief Determine if this inspector is going to load user tables on
	  startup.

	  \param import_users if true, no user tables will be created for
	  this capture. This also means that no user or group info will be
	  written to the trace file by the -w flag. The user/group tables are
	  necessary to use filter fields like user.name or group.name. However,
	  creating them can increase the startup time. Moreover, they contain
	  information that could be privacy sensitive.

	  \note default behavior is import_users=true.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void set_import_users(bool import_users);

	/*!
	  \brief temporarily pauses event capture.

	  \note This function can only be called for live captures.
	*/
	void stop_capture();

	/*!
	  \brief Restarts an event capture that had been paused with
	   \ref stop_capture().

	  \note This function can only be called for live captures.
	*/
	void start_capture();

#ifdef HAS_FILTERING
	/*!
	  \brief Compiles and installs the given capture filter.

	  \param filter the filter string. Refer to the filtering language
	   section for information about the filtering
	   syntax.

	  @throws a sinsp_exception containing the error string is thrown in case
	   the filter is invalid.
	*/
	void set_filter(const string& filter);

	/*!
	  \brief Installs the given capture runtime filter object.

	  \param filter the runtime filter object
	*/
	void set_filter(sinsp_filter* filter);

	/*!
	  \brief Return the filter set for this capture.

	  \return the filter previously set with \ref set_filter(), or an empty
	   string if no filter has been set yet.
	*/
	const string get_filter();

	bool run_filters_on_evt(sinsp_evt *evt);
#endif

	/*!
	  \brief This method can be used to specify a function to collect the library
	   log messages.

	  \param cb the target function that will receive the log messages.
	*/
	void set_log_callback(sinsp_logger_callback cb);

	/*!
	  \brief Instruct sinsp to write its log messages to the given file.
	*/
	void set_log_file(string filename);

	/*!
	  \brief Instruct sinsp to write its log messages to stderr.
	*/
	void set_log_stderr();

	/*!
	  \brief Specify the minimum severity of the messages that go into the logs
	   emitted by the library.
	*/
	void set_min_log_severity(sinsp_logger::severity sev);

	/*!
	 * \brief set whether the library will automatically purge the threadtable
	 *        at specific times. If not, client is responsible for thread lifetime
	 *        management. If invoked, then the purge interval and thread timeout change
	 *        defaults, but have no observable effect.
	 */
	void disable_automatic_threadtable_purging();

	/*!
	 * \brief sets the interval at which the thread purge code runs. This does
	 *        not run every event as it's mildly expensive if there are lots of threads
	 */
	void set_thread_purge_interval_s(uint32_t val);

	/*!
	 * \brief sets the amount of time after which a thread which has seen no events
	 *        can be purged. As the purging happens only every m_thread_purge_interval_s,
	 *        the max time a thread may linger is actually m_thread_purge_interval +
	 *        m_thread_timeout_s
	 */
	void set_thread_timeout_s(uint32_t val);


	/*!
	  \brief Start writing the captured events to file.

	  \param dump_filename the destination trace file.

	  \param compress true to save the trace file in a compressed format.

	  \note only the events that pass the capture filter set with \ref set_filter()
	   will be saved to disk.
	  \note this simplified dump interface allows only one dump per capture.
	   For more flexibility, refer to the \ref sinsp_dumper class, that can
	   also be combined with \ref sinsp_filter to filter what will go into
	   the file.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void autodump_start(const string& dump_filename, bool compress);

 	/*!
	  \brief Cycles the file pointer to a new capture file
	*/
	void autodump_next_file();

	/*!
	  \brief Stops an event dump that was started with \ref autodump_start().

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	void autodump_stop();

	/*!
	  \brief Populate the given vector with the full list of filter check fields
	   that this version of the library supports.
	*/
	static void get_filtercheck_fields_info(std::vector<const filter_check_info*>& list);

	bool has_metrics();

	/*!
	  \brief Return information about the machine generating the events.

	  \note this call works with file captures as well, because the machine
	   info is stored in the trace files. In that case, the returned
	   machine info is the one of the machine where the capture happened.
	*/
	const scap_machine_info* get_machine_info();

	/*!
	  \brief Look up a thread given its tid and return its information,
	   and optionally go dig into proc if the thread is not in the thread table.

	  \param tid the ID of the thread. In case of multi-thread processes,
	   this corresponds to the PID.
	  \param query_os_if_not_found if true, the library will search for this
	   thread's information in proc, use the result to create a new thread
	   entry, and return the new entry.

	  \return the \ref sinsp_threadinfo object containing full thread information
	   and state.

	  \note if you are interested in a process' information, just give this
	  function with the PID of the process.

	  @throws a sinsp_exception containing the error string is thrown in case
	   of failure.
	*/
	threadinfo_map_t::ptr_t get_thread_ref(int64_t tid, bool query_os_if_not_found = false, bool lookup_only = true, bool main_thread = false);

	/*!
	  \brief Return the table with all the machine users.

	  \return a hash table with the user ID (UID) as the key and the user
	   information as the data.

	  \note this call works with file captures as well, because the user
	   table is stored in the trace files. In that case, the returned
	   user list is the one of the machine where the capture happened.
	*/
	const unordered_map<uint32_t, scap_userinfo*>* get_userlist();

	/*!
	  \brief Lookup for user in the user table.

 	  \return the \ref scap_userinfo object containing full user information,
 	   if user not found, returns NULL.

 	  \note this call works with file captures as well, because the user
	   table is stored in the trace files. In that case, the returned
	   user list is the one of the machine where the capture happened.
	*/
	scap_userinfo* get_user(uint32_t uid);

	/*!
	  \brief Return the table with all the machine user groups.

	  \return a hash table with the group ID (GID) as the key and the group
	   information as the data.

	  \note this call works with file captures as well, because the group
	   table is stored in the trace files. In that case, the returned
	   user table is the one of the machine where the capture happened.
	*/
	const unordered_map<uint32_t, scap_groupinfo*>* get_grouplist();

	/*!
	  \brief Lookup for group in the group table.

	  \return the \ref scap_groupinfo object containing full group information,
	   if group not found, returns NULL.

 	  \note this call works with file captures as well, because the group
	   table is stored in the trace files. In that case, the returned
	   group list is the one of the machine where the capture happened.
	*/
	scap_groupinfo* get_group(uint32_t gid);

	/*!
	  \brief Fill the given structure with statistics about the currently
	   open capture.

	  \note this call won't work on file captures.
	*/
	void get_capture_stats(scap_stats* stats) const override;

#ifdef GATHER_INTERNAL_STATS
	sinsp_stats get_stats();
#endif

	libsinsp::event_processor* m_external_event_processor;

	sinsp_threadinfo* build_threadinfo()
    {
        return m_external_event_processor ? m_external_event_processor->build_threadinfo(this)
                                          : new sinsp_threadinfo(this);
    }

	/*!
	  \brief registers external event processor.
	  After this, callbacks on libsinsp::event_processor will happen at
	  the appropriate times. This registration must happen before calling open.
	*/
	void register_external_event_processor(libsinsp::event_processor& processor)
	{
		m_external_event_processor = &processor;
	}

	libsinsp::event_processor* get_external_event_processor() const
	{
		return m_external_event_processor;
	}

	/*!
	  \brief Return the event and system call information tables.

	  This function exports the tables containing the information about the
	  events supported by the capture infrastructure and the available system calls.
	*/
	sinsp_evttables* get_event_info_tables();

	/*!
	  \brief get last library error.
	*/
	string getlasterr()
	{
		return m_lasterr;
	}

	/*!
	  \brief Get the list of machine network interfaces.

	  \return Pointer to the interface list manager.
	*/
	sinsp_network_interfaces* get_ifaddr_list();

	/*!
	  \brief Set the format used to render event data
	   buffer arguments.
	*/
	void set_buffer_format(sinsp_evt::param_fmt format);

	/*!
	  \brief Get the format used to render event data
	   buffer arguments.
	*/
	sinsp_evt::param_fmt get_buffer_format();

	/*!
	  \brief Set event flags for which matching events should be dropped pre-filtering
	*/
	void set_drop_event_flags(ppm_event_flags flags);

	/*!
	  \brief Returns true if the current capture is offline
	*/
	inline bool is_capture()
	{
		return m_mode == SCAP_MODE_CAPTURE;
	}

	/*!
	  \brief Returns true if the current capture is live
	*/
	inline bool is_live()
	{
		return m_mode == SCAP_MODE_LIVE;
	}

	/*!
	  \brief Returns true if the kernel module is not loaded
	*/
	inline bool is_nodriver()
	{
		return m_mode == SCAP_MODE_NODRIVER;
	}

	/*!
	  \brief Returns true if the current capture has a plugin producing events
	*/
	inline bool is_plugin()
	{
		return m_mode == SCAP_MODE_PLUGIN;
	}

	/*!
	  \brief Returns the framework plugin api version as a string with static storage
	*/
	inline const char *get_plugin_api_version() const
	{
		return PLUGIN_API_VERSION_STR;
	}

	/*!
	  \brief Returns the API version supported by the driver
	*/
	inline uint64_t get_driver_api_version() const
	{
		return scap_get_driver_api_version(m_h);
	}

	/*!
	  \brief Returns the minimum API version required by the userspace library
	*/
	inline uint64_t get_scap_api_version() const
	{
		return SCAP_MINIMUM_DRIVER_API_VERSION;
	}

	/*!
	  \brief Returns the schema version supported by the driver
	*/
	inline uint64_t get_driver_schema_version() const
	{
		return scap_get_driver_schema_version(m_h);
	}

	/*!
	  \brief Returns the minimum schema version required by the userspace library
	*/
	inline uint64_t get_scap_schema_version() const
	{
		return SCAP_MINIMUM_DRIVER_SCHEMA_VERSION;
	}

	/*!
	  \brief Returns true if truncated environments should be loaded from /proc
	*/
	inline bool large_envs_enabled()
	{
		return is_live() && m_large_envs_enabled;
	}

	/*!
	  \brief Enable/disable large environment support

	  \param enable when it is true and the current capture is live
	  environments larger than SCAP_MAX_ENV_SIZE will be loaded
	  from /proc/<pid>/environ (if possible)
	*/
	void set_large_envs(bool enable);

	/*!
	  \brief Set the debugging mode of the inspector.

	  \param enable_debug when it is true and the current capture is live
	  the inspector filters out events about itself.
	*/
	void set_debug_mode(bool enable_debug);

	/*!
	  \brief Set the fatfile mode when writing events to file.

	  \note fatfile mode involves saving "hidden" events in the trace file
	   that make it possible to preserve full state even when filters that
	   would drop state packets are used during the capture.
	*/
	void set_fatfile_dump_mode(bool enable_fatfile);

	/*!
	  \brief Set internal events mode.

	  \note By default, internal events, such as events that note
                when new containers or orchestration entities have
                been created, are not returned in sinsp::next(). (They
                are always written to capture files, to ensure that
                the full state can be reconstructed when capture files
                are read). Enabling internal events mode will result
                in these events being returned.
	*/
	void set_internal_events_mode(bool enable_internal_events);

	/*!
	  \brief Set whether to resolve hostnames and port protocols or not.

	  \note It can use the system library functions getservbyport and so to
	   resolve protocol names and domain names.

	  \param enable If set to false it will enable this function and use plain
	   numerical values.
	*/
	void set_hostname_and_port_resolution_mode(bool enable);

	/*!
	  \brief Set the runtime flag for resolving the timespan in a human
	   readable mode.

	  \note Moved to the inspector due to sysdig#426 issue

	  \param flag Can be 'h', 'a', 'r', 'd', 'D' as documented in the manual.
	*/
	inline void set_time_output_mode(char flag)
	{
		m_output_time_flag = flag;
	}

	/*!
	  \brief Sets the max length of event argument strings.

	  \param len Max length after which an event argument string is truncated.
	   0 means no limit. Use this to reduce verbosity when printing event info
	   on screen.
	*/
	void set_max_evt_output_len(uint32_t len);

	/*!
	  \brief Returns true if the debug mode is enabled.
	*/
	inline bool is_debug_enabled()
	{
		return m_isdebug_enabled;
	}

	/*!
	  \brief Set a flag indicating if the command line requested to show container information.

	  \param set true if the command line argument is set to show container information
	*/
	void set_print_container_data(bool print_container_data);


	/*!
	  \brief Returns true if the command line argument is set to show container information.
	*/
	inline bool is_print_container_data()
	{
		return m_print_container_data;
	}

	/*!
	  \brief Lets a filter plugin request a protocol decoder.

	  \param the name of the required decoder
	*/
	sinsp_protodecoder* require_protodecoder(std::string decoder_name);

	/*!
	  \brief Lets a filter plugin request a protocol decoder.

	  \param the name of the required decoder
	*/
	void protodecoder_register_reset(sinsp_protodecoder* dec);

	/*!
	  \brief If this is an offline capture, return the name of the file that is
	   being read, otherwise return an empty string.
	*/
	std::string get_input_filename()
	{
		return m_input_filename;
	}

	/*!
	  \brief If this is an online capture, set event_id.
	  \param event type to set
	  \return SCAP_SUCCESS if the call is successful
	   On Failure, SCAP_FAILURE is returned and getlasterr() can be used to
	   obtain the cause of the error.

	  \note For a list of event types, refer to \ref etypes.
	*/
	void set_eventmask(uint32_t event_types);

	/*!
	  \brief If this is an online capture, unset event_id.
	  \param event type to unset
	  \return SCAP_SUCCESS if the call is successful
	   On Failure, SCAP_FAILURE is returned and getlasterr() can be used to
	   obtain the cause of the error.

	  \note For a list of event types, refer to \ref etypes.
	*/
	void unset_eventmask(uint32_t event_id);

	/*!
	  \brief When reading events from a trace file or a plugin, this function
	   returns the read progress as a number between 0 and 100.
	*/
	double get_read_progress();

	/*!
	  \brief When reading events from a trace file or a plugin, this function
	   returns the read progress as a number and as a string, giving the plugins
	   flexibility on the format.
	*/
	double get_read_progress_with_str(OUT string* progress_str);

	/*!
	  \brief Make the amount of data gathered for a syscall to be
	  determined by the number of parameters.
	*/
	virtual int /*SCAP_X*/ dynamic_snaplen(bool enable)
	{
		if(enable)
		{
			return scap_enable_dynamic_snaplen(m_h);
		}
		else
		{
			return scap_disable_dynamic_snaplen(m_h);
		}
	}

	/*!
	  \brief Set the parameters that control metadata fetching from orchestrators
	  like Kuberneted and mesos.
	*/
	void set_metadata_download_params(uint32_t data_max_b,
		uint32_t data_chunk_wait_us,
		uint32_t data_watch_freq_sec);


#if !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)
	void init_k8s_ssl(const std::string *ssl_cert);

	/*!
	  \brief Initialize the Kubernetes client.
	  \param api_server Kubernetes API server URI
	  \param ssl_cert use the provided file name to authenticate with the Kubernetes API server
	  \param node_name the node name is used as a filter when requesting metadata of pods 
	  to the API server; if empty, no filter is set
	*/
	void init_k8s_client(std::string* api_server, std::string* ssl_cert, std::string *node_name, bool verbose = false);
	void make_k8s_client();
	k8s* get_k8s_client() const { return m_k8s_client; }
	void validate_k8s_node_name();

	void init_mesos_client(std::string* api_server, bool verbose = false);
	mesos* get_mesos_client() const { return m_mesos_client; }
#endif // !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)

	//
	// Misc internal stuff
	//
	void stop_dropping_mode();
	void start_dropping_mode(uint32_t sampling_ratio);
	void on_new_entry_from_proc(void* context, scap_t* handle, int64_t tid, scap_threadinfo* tinfo,
		scap_fdinfo* fdinfo);
	void set_get_procs_cpu_from_driver(bool get_procs_cpu_from_driver)
	{
		m_get_procs_cpu_from_driver = get_procs_cpu_from_driver;
	}

	//
	// Used by filters to enable app event state tracking, which is disabled
	// by default for performance reasons
	//
	void request_tracer_state_tracking()
	{
		m_track_tracers_state = true;
	}

	//
	// Allocates private state in the thread info class.
	// Returns the ID to use when retrieving the memory area.
	// Will fail if called after the capture starts.
	//
	uint32_t reserve_thread_memory(uint32_t size);

	sinsp_parser* get_parser();

	/*!
	  \brief Enables simple_consumer mode on sinsp, at driver level.
	  This will avoid tracing syscalls flagged with EF_DROP_SIMPLE_CONS.
	  Must be called before sinsp opening.
	*/
	void set_simple_consumer();

	bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress);
	void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo);
	void add_meta_event(sinsp_evt *metaevt);
	void add_meta_event_callback(meta_event_callback cback, void* data);
	void remove_meta_event_callback();
	void filter_proc_table_when_saving(bool filter);
	void enable_tracers_capture();
	void enable_page_faults();
	uint64_t get_bytes_read()
	{
		return scap_ftell(m_h);
	}
	void refresh_ifaddr_list();
	void refresh_proc_list() {
		scap_refresh_proc_table(m_h);
	}
	void set_simpledriver_mode();
	std::vector<long> get_n_tracepoint_hit();
	void set_bpf_probe(const std::string& bpf_probe);

	bool is_bpf_enabled();

	static unsigned num_possible_cpus();

#if defined(HAS_CAPTURE) && !defined(_WIN32)
	static std::shared_ptr<std::string> lookup_cgroup_dir(const std::string& subsys);
#endif
#if defined(CYGWING_AGENT)
	wh_t* get_wmi_handle() override
	{
		return scap_get_wmi_handle(m_h);
	}
#endif

	static inline bool simple_consumer_consider_evtnum(uint16_t etype)
	{
		enum ppm_event_flags flags = g_infotables.m_event_info[etype].flags;

		return ! (flags & sinsp::simple_consumer_skip_flags());
	}

	static inline bool simple_consumer_consider_syscallid(uint16_t scid)
	{
		enum ppm_event_flags flags = g_infotables.m_syscall_info_table[scid].flags;

		return ! (flags & sinsp::simple_consumer_skip_flags());
	}

	// Add comm to the list of comms for which the inspector
	// should not return events.
	bool suppress_events_comm(const std::string &comm);

	bool check_suppressed(int64_t tid);

	void set_docker_socket_path(std::string socket_path);
	void set_query_docker_image_info(bool query_image_info);

	void set_cri_extra_queries(bool extra_queries);

	void set_fullcapture_port_range(uint16_t range_start, uint16_t range_end);

	void set_statsd_port(uint16_t port);

	/*!
	  \brief Reset list of crio socket paths currently stored, and set path as the only path.
	*/
	void set_cri_socket_path(const std::string& path);
	/*!
	  \brief Pushed a new path to the list of crio socket paths
	*/
	void add_cri_socket_path(const std::string &path);
	void set_cri_timeout(int64_t timeout_ms);
	void set_cri_async(bool async);
	void set_cri_delay(uint64_t delay_ms);
	void set_container_labels_max_len(uint32_t max_label_len);

	void add_plugin(std::shared_ptr<sinsp_plugin> plugin);
	void set_input_plugin(string plugin_name);
	void set_input_plugin_open_params(string params);
	const std::vector<std::shared_ptr<sinsp_plugin>>& get_plugins();
	std::shared_ptr<sinsp_plugin> get_plugin_by_evt(sinsp_evt &evt);
	std::shared_ptr<sinsp_plugin> get_plugin_by_id(uint32_t plugin_id);
	std::shared_ptr<sinsp_plugin> get_source_plugin_by_source(const std::string &source);

	uint64_t get_lastevent_ts() const { return m_lastevent_ts; }

VISIBILITY_PROTECTED
	bool add_thread(const sinsp_threadinfo *ptinfo);
	void set_mode(scap_mode_t value)
	{
		m_mode = value;
	}

VISIBILITY_PRIVATE

        static inline ppm_event_flags simple_consumer_skip_flags()
        {
		return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED | EF_DROP_SIMPLE_CONS | EF_OLD_VERSION);
        }
// Doxygen doesn't understand VISIBILITY_PRIVATE
#ifdef _DOXYGEN
private:
#endif

	void open_int();
	void open_live_common(uint32_t timeout_ms, scap_mode_t mode);
	void init();
	void deinit_state();
	void import_thread_table();
	void import_ifaddr_list();
	void import_user_list();
	void add_protodecoders();
	void fill_syscalls_of_interest(scap_open_args *oargs);
	void remove_thread(int64_t tid, bool force);

	//
	// Note: lookup_only should be used when the query for the thread is made
	//       not as a consequence of an event for that thread arriving, but
	//       just for lookup reason. In that case, m_lastaccess_ts is not updated
	//       and m_last_tinfo is not set.
	//
	inline threadinfo_map_t::ptr_t find_thread(int64_t tid, bool lookup_only)
	{
		return m_thread_manager->find_thread(tid, lookup_only);
	}

	// this is here for testing purposes only
	sinsp_threadinfo* find_thread_test(int64_t tid, bool lookup_only);
	bool remove_inactive_threads();

#if !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)
	void k8s_discover_ext();
	void collect_k8s();
	void update_k8s_state();
	void update_mesos_state();
	bool get_mesos_data();
#endif // !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)

	static int64_t get_file_size(const std::string& fname, char *error);
	static std::string get_error_desc(const std::string& msg = "");

	void restart_capture();

	void fseek(uint64_t filepos)
	{
		scap_fseek(m_h, filepos);
	}

	void add_suppressed_comms(scap_open_args &oargs);

	bool increased_snaplen_port_range_set() const
	{
		return m_increased_snaplen_port_range.range_start > 0 &&
		       m_increased_snaplen_port_range.range_end > 0;
	}

	double get_read_progress_file();
	void get_read_progress_plugin(OUT double* nres, string* sres);

	void get_procs_cpu_from_driver(uint64_t ts);

	scap_t* m_h;
	uint64_t m_nevts;
	int64_t m_filesize;

	bool m_simpleconsumer;

	scap_mode_t m_mode = SCAP_MODE_NONE;

	// If non-zero, reading from this fd and m_input_filename contains "fd
	// <m_input_fd>". Otherwise, reading from m_input_filename.
	int m_input_fd;
	std::string m_input_filename;
	bool m_bpf;
	bool m_udig;
	bool m_is_windows;
	std::string m_bpf_probe;
	bool m_isdebug_enabled;
	bool m_isfatfile_enabled;
	bool m_isinternal_events_enabled;
	bool m_hostname_and_port_resolution_enabled;
	char m_output_time_flag;
	uint32_t m_max_evt_output_len;
	bool m_compress;
	sinsp_evt m_evt;
	std::string m_lasterr;
	int64_t m_tid_to_remove;
	int64_t m_tid_of_fd_to_remove;
	std::vector<int64_t>* m_fds_to_remove;
	uint64_t m_lastevent_ts;
	// the parsing engine
	sinsp_parser* m_parser;
	// the statistics analysis engine
	scap_dumper_t* m_dumper;
	bool m_is_dumping;
	bool m_filter_proc_table_when_saving;
	const scap_machine_info* m_machine_info;
	uint32_t m_num_cpus;
	sinsp_thread_privatestate_manager m_thread_privatestate_manager;
	bool m_is_tracers_capture_enabled;
	bool m_flush_memory_dump;
	bool m_large_envs_enabled;

	sinsp_network_interfaces* m_network_interfaces;

public:
	sinsp_thread_manager* m_thread_manager;

	sinsp_container_manager m_container_manager;

	metadata_download_params m_metadata_download_params;

	//
	// Kubernetes
	//
#if !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)
	std::string* m_k8s_api_server;
	std::string* m_k8s_api_cert;
	std::string* m_k8s_node_name;
	bool m_k8s_node_name_validated = false;
#ifdef HAS_CAPTURE
	std::shared_ptr<sinsp_ssl> m_k8s_ssl;
	std::shared_ptr<sinsp_bearer_token> m_k8s_bt;
	unique_ptr<k8s_api_handler> m_k8s_api_handler;
	shared_ptr<socket_collector<socket_data_handler<k8s_handler>>> m_k8s_collector;
	bool m_k8s_api_detected = false;
	unique_ptr<k8s_api_handler> m_k8s_ext_handler;
	k8s_ext_list_ptr_t m_ext_list_ptr;
	bool m_k8s_ext_detect_done = false;
#endif // HAS_CAPTURE
	k8s* m_k8s_client;
	uint64_t m_k8s_last_watch_time_ns;
#endif // !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD)

	//
	// Mesos/Marathon
	//
	std::string m_mesos_api_server;
	std::vector<std::string> m_marathon_api_server;
	mesos* m_mesos_client;
	uint64_t m_mesos_last_watch_time_ns;

	//
	// True when ran with -v.
	// Used by mesos and k8s objects.
	//
	bool m_verbose_json = false;

	//
	// True if the command line argument is set to show container information
	// The default is false set within the constructor
	//
	bool m_print_container_data;

#ifdef HAS_FILTERING
	uint64_t m_firstevent_ts;
	sinsp_filter* m_filter;
	std::string m_filterstring;
#endif
	unordered_set<uint32_t> m_ppm_sc_of_interest;

	//
	// Internal stats
	//
#ifdef GATHER_INTERNAL_STATS
	sinsp_stats m_stats;
#endif
#ifdef HAS_ANALYZER
	std::vector<uint64_t> m_tid_collisions;
#endif

	//
	// Saved snaplen
	//
	uint32_t m_snaplen;

	//
	// Saved increased capture range
	//
	struct
	{
		uint16_t range_start;
		uint16_t range_end;
	} m_increased_snaplen_port_range;

	int32_t m_statsd_port;

	//
	// Some thread table limits
	//
	uint32_t m_max_fdtable_size;
	bool m_automatic_threadtable_purging = true;
	uint64_t m_thread_timeout_ns = (uint64_t)1800 * ONE_SECOND_IN_NS;
	uint64_t m_inactive_thread_scan_time_ns = (uint64_t)1200 * ONE_SECOND_IN_NS;

	//
	// Container limits
	//
	uint64_t m_inactive_container_scan_time_ns;

	//
	// How to render the data buffers
	//
	sinsp_evt::param_fmt m_buffer_format;

	//
	// User and group tables
	//
	bool m_import_users;
	unordered_map<uint32_t, scap_userinfo*> m_userlist;
	unordered_map<uint32_t, scap_groupinfo*> m_grouplist;

	//
	// The cycle-writer for files
	//
	cycle_writer* m_cycle_writer;
	bool m_write_cycling;

#ifdef SIMULATE_DROP_MODE
	//
	// Some dropping infrastructure
	//
	bool m_isdropping;
#endif

	//
	// App events
	//
	bool m_track_tracers_state;
	list<sinsp_partial_tracer*> m_partial_tracers_list;
	simple_lifo_queue<sinsp_partial_tracer>* m_partial_tracers_pool;

	//
	// Protocol decoding state
	//
	std::vector<sinsp_protodecoder*> m_decoders_reset_list;

	//
	// meta event management for other sources like k8s, mesos.
	//
	sinsp_evt* m_metaevt;
	meta_event_callback m_meta_event_callback;
	void* m_meta_event_callback_data;

	// A queue of pending container events. Written from async
	// callbacks that occur after looking up container
	// information, read from sinsp::next().
#ifndef _WIN32
	tbb::concurrent_queue<shared_ptr<sinsp_evt>> m_pending_container_evts;
#endif

	// Holds an event dequeued from the above queue
	std::shared_ptr<sinsp_evt> m_container_evt;

	//
	// End of second housekeeping
	//
	bool m_get_procs_cpu_from_driver;
	uint64_t m_next_flush_time_ns;
	uint64_t m_last_procrequest_tod;
	sinsp_proc_metainfo m_meinfo;
	uint64_t m_next_stats_print_time_ns;

	static unsigned int m_num_possible_cpus;
#if defined(HAS_CAPTURE)
	int64_t m_self_pid;
#endif

	// Any thread with a comm in this set will not have its events
	// returned in sinsp::next()
	std::set<std::string> m_suppressed_comms;

	//
	// List of the sinsp/scap plugins configured by the user.
	//
	std::vector<std::shared_ptr<sinsp_plugin>> m_plugins_list;
	//
	// The ID of the plugin to use as event input, or zero
	// if no source plugin should be used as source
	//
	std::shared_ptr<sinsp_plugin> m_input_plugin;
	//
	// String with the parameters for the plugin to be used as input.
	// These parameters will be passed to the open function of the plugin.
	//
	string m_input_plugin_open_params;
	//
	// An instance of scap_evt to be used during the next call to sinsp::next().
	// If non-null, sinsp::next will use this pointer instead of invoking scap_next().
	// After using this event, sinsp::next() will set this back to NULL.
	// This is used internally during the state initialization phase.
	scap_evt *m_replay_scap_evt;
	//
	// This is related to m_replay_scap_evt, and is used to store the additional cpuid
	// information of the replayed scap event.
	uint16_t m_replay_scap_cpuid;

	bool m_inited;

	friend class sinsp_parser;
	friend class sinsp_analyzer;
	friend class sinsp_analyzer_parsers;
	friend class sinsp_evt;
	friend class sinsp_threadinfo;
	friend class sinsp_fdtable;
	friend class sinsp_thread_manager;
	friend class sinsp_container_manager;
	friend class sinsp_dumper;
	friend class sinsp_analyzer_fd_listener;
	friend class sinsp_chisel;
	friend class sinsp_tracerparser;
	friend class sinsp_filter_check_event;
	friend class sinsp_protodecoder;
	friend class lua_cbacks;
	friend class sinsp_filter_check_container;
	friend class sinsp_worker;
	friend class sinsp_table;
	friend class curses_textbox;
	friend class sinsp_filter_check_fd;
	friend class sinsp_filter_check_k8s;
	friend class sinsp_filter_check_mesos;
	friend class sinsp_filter_check_evtin;
	friend class sinsp_baseliner;
	friend class sinsp_memory_dumper;
	friend class sinsp_network_interfaces;
	friend class test_helper;

	template<class TKey,class THash,class TCompare> friend class sinsp_connection_manager;

#ifdef SYSDIG_TEST
protected:
	void inject_machine_info(const scap_machine_info *value)
	{
		m_machine_info = value;
	}
	void inject_network_interfaces(sinsp_network_interfaces *value)
	{
		m_network_interfaces = value;
	}
#endif // SYSDIG_TEST
};

/*@}*/