File: plugin_api.h

package info (click to toggle)
falcosecurity-libs 0.20.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 23,732 kB
  • sloc: ansic: 532,812; cpp: 100,792; python: 1,490; sh: 532; makefile: 195
file content (1130 lines) | stat: -rw-r--r-- 52,817 bytes parent folder | download | duplicates (2)
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
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.

*/

#pragma once

#include <plugin/plugin_types.h>

#ifdef __cplusplus
extern "C" {
#endif

//
// API versions of this plugin framework
//
// todo(jasondellaluce): when/if major changes to v4, check and solve all todos
#define PLUGIN_API_VERSION_MAJOR 3
#define PLUGIN_API_VERSION_MINOR 10
#define PLUGIN_API_VERSION_PATCH 0

//
// Just some not so smart defines to retrieve plugin api version as string
//
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
#define PLUGIN_API_VERSION \
	PLUGIN_API_VERSION_MAJOR.PLUGIN_API_VERSION_MINOR.PLUGIN_API_VERSION_PATCH
#define PLUGIN_API_VERSION_STR EXPAND_AND_QUOTE(PLUGIN_API_VERSION)

//
// The max length of errors returned by a plugin in some of its API symbols.
//
#define PLUGIN_MAX_ERRLEN 1024

// Supported by the API but deprecated. Use the extended version ss_plugin_table_reader_vtable_ext
// instead. todo(jasondellaluce): when/if major changes to v4, remove this and give this name to the
// associated *_ext struct.
typedef struct {
	const ss_plugin_table_fieldinfo* (*list_table_fields)(ss_plugin_table_t* t, uint32_t* nfields);
	ss_plugin_table_field_t* (*get_table_field)(ss_plugin_table_t* t,
	                                            const char* name,
	                                            ss_plugin_state_type data_type);
	ss_plugin_table_field_t* (*add_table_field)(ss_plugin_table_t* t,
	                                            const char* name,
	                                            ss_plugin_state_type data_type);
} ss_plugin_table_fields_vtable;

// Vtable for controlling and the fields for the entries of a state table.
// This allows discovering the fields available in the table, defining new ones,
// and obtaining accessors usable at runtime for reading and writing the fields'
// data from each entry of a given state table.
typedef struct {
	// Returns a pointer to an array containing info about all the fields
	// available in the entries of the table. nfields will be filled with the number
	// of elements of the returned array. The array's memory is owned by the
	// tables's owner. Returns NULL in case of error.
	const ss_plugin_table_fieldinfo* (*list_table_fields)(ss_plugin_table_t* t, uint32_t* nfields);
	//
	// Returns an opaque pointer representing an accessor to a data field
	// present in all entries of the table, given its name and type.
	// This can later be used for read and write operations for all entries of
	// the table. The pointer is owned by the table's owner.
	// Returns NULL in case of issues (including when the field is not defined
	// or it has a type different than the specified one).
	ss_plugin_table_field_t* (*get_table_field)(ss_plugin_table_t* t,
	                                            const char* name,
	                                            ss_plugin_state_type data_type);
	//
	// Defines a new field in the table given its name and data type,
	// which will then be available in all entries contained in the table.
	// Returns an opaque pointer representing an accessor to the newly-defined
	// field. This can later be used for read and write operations for all entries of
	// the table. The pointer is owned by the table's owner.
	// Returns NULL in case of issues (including when a field is defined multiple
	// times with different data types).
	ss_plugin_table_field_t* (*add_table_field)(ss_plugin_table_t* t,
	                                            const char* name,
	                                            ss_plugin_state_type data_type);
} ss_plugin_table_fields_vtable_ext;

// Supported by the API but deprecated. Use the extended version ss_plugin_table_reader_vtable_ext
// instead. todo(jasondellaluce): when/if major changes to v4, remove this and give this name to the
// associated *_ext struct.
typedef struct {
	const char* (*get_table_name)(ss_plugin_table_t* t);
	uint64_t (*get_table_size)(ss_plugin_table_t* t);
	ss_plugin_table_entry_t* (*get_table_entry)(ss_plugin_table_t* t,
	                                            const ss_plugin_state_data* key);
	ss_plugin_rc (*read_entry_field)(ss_plugin_table_t* t,
	                                 ss_plugin_table_entry_t* e,
	                                 const ss_plugin_table_field_t* f,
	                                 ss_plugin_state_data* out);
} ss_plugin_table_reader_vtable;

// Opaque pointer to the state data relative to a state table iteration.
// This is passed initially by the invoker when starting the iteration, and
// is then dispatched to the iterator for each of the entries of the table.
typedef void ss_plugin_table_iterator_state_t;

// Iterator function callback used by a plugin for looping through all the
// entries of a given state table. Returns true if the iteration should
// proceed to the next element, or false in case of break out.
typedef ss_plugin_bool (*ss_plugin_table_iterator_func_t)(ss_plugin_table_iterator_state_t* s,
                                                          ss_plugin_table_entry_t* e);

typedef struct {
	// Returns the table's name, or NULL in case of error.
	// The returned pointer is owned by the table's owner.
	const char* (*get_table_name)(ss_plugin_table_t* t);
	//
	// Returns the number of entries in the table, or ((uint64_t) -1) in
	// case of error.
	uint64_t (*get_table_size)(ss_plugin_table_t* t);
	//
	// Returns an opaque pointer to an entry present in the table at the given
	// key, or NULL in case of issues (including if no entry is found at the
	// given key). The returned pointer is owned by the table's owner.
	// Every non-NULL returned entry must be released by invoking release_table_entry()
	// once it becomes no more used by the invoker.
	ss_plugin_table_entry_t* (*get_table_entry)(ss_plugin_table_t* t,
	                                            const ss_plugin_state_data* key);
	//
	// Reads the value of an entry field from a table's entry.
	// The field accessor must be obtainied during plugin_init().
	// The read value is stored in the "out" parameter.
	// Returns SS_PLUGIN_SUCCESS if successful, and SS_PLUGIN_FAILURE otherwise.
	ss_plugin_rc (*read_entry_field)(ss_plugin_table_t* t,
	                                 ss_plugin_table_entry_t* e,
	                                 const ss_plugin_table_field_t* f,
	                                 ss_plugin_state_data* out);
	//
	// Releases a table entry obtained by from previous invocation of get_table_entry().
	// After being released, the same table entry cannot be reused by the invoker.
	// However, the same entry can be re-obtained through an invocation of get_table_entry().
	void (*release_table_entry)(ss_plugin_table_t* t, ss_plugin_table_entry_t* e);
	//
	// Iterates through all the entries of a table, invoking the interation
	// callback function for each of them. Returns false in case of failure or
	// iteration break-out, and true otherwise.
	ss_plugin_bool (*iterate_entries)(ss_plugin_table_t* t,
	                                  ss_plugin_table_iterator_func_t it,
	                                  ss_plugin_table_iterator_state_t* s);
} ss_plugin_table_reader_vtable_ext;

// Supported by the API but deprecated. Use the extended version ss_plugin_table_writer_vtable_ext
// instead. todo(jasondellaluce): when/if major changes to v4, remove this and give this name to the
// associated *_ext struct.
typedef struct {
	ss_plugin_rc (*clear_table)(ss_plugin_table_t* t);
	ss_plugin_rc (*erase_table_entry)(ss_plugin_table_t* t, const ss_plugin_state_data* key);
	ss_plugin_table_entry_t* (*create_table_entry)(ss_plugin_table_t* t);
	void (*destroy_table_entry)(ss_plugin_table_t* t, ss_plugin_table_entry_t* e);
	ss_plugin_table_entry_t* (*add_table_entry)(ss_plugin_table_t* t,
	                                            const ss_plugin_state_data* key,
	                                            ss_plugin_table_entry_t* entry);
	ss_plugin_rc (*write_entry_field)(ss_plugin_table_t* t,
	                                  ss_plugin_table_entry_t* e,
	                                  const ss_plugin_table_field_t* f,
	                                  const ss_plugin_state_data* in);
} ss_plugin_table_writer_vtable;

// Vtable for controlling a state table for write operations.
typedef struct {
	// Erases all the entries of the table.
	// Returns SS_PLUGIN_SUCCESS if successful, and SS_PLUGIN_FAILURE otherwise.
	ss_plugin_rc (*clear_table)(ss_plugin_table_t* t);
	//
	// Erases an entry from a table at the given key.
	// Returns SS_PLUGIN_SUCCESS if successful, and SS_PLUGIN_FAILURE otherwise.
	ss_plugin_rc (*erase_table_entry)(ss_plugin_table_t* t, const ss_plugin_state_data* key);
	//
	// Creates a new entry that can later be added to the same table it was
	// created from. The entry is represented as an opaque pointer owned
	// by the plugin. Once obtained, the plugin can either add the entry
	// to the table through add_table_entry(), or destroy it throgh
	// destroy_table_entry(). Returns an opaque pointer to the newly-created
	// entry, or NULL in case of error.
	ss_plugin_table_entry_t* (*create_table_entry)(ss_plugin_table_t* t);
	//
	// Destroys a table entry obtained by from previous invocation of create_table_entry().
	void (*destroy_table_entry)(ss_plugin_table_t* t, ss_plugin_table_entry_t* e);
	//
	// Adds a new entry to a table obtained by from previous invocation of
	// create_table_entry() on the same table. The entry is inserted in the table
	// with the given key. If another entry is already present with the same key,
	// it gets replaced. After insertion, table will be come the owner of the
	// entry's pointer. Returns an opaque pointer to the newly-added table's entry,
	// or NULL in case of error. Every non-NULL returned entry must be released
	// by invoking release_table_entry() once it becomes no more used by the invoker.
	ss_plugin_table_entry_t* (*add_table_entry)(ss_plugin_table_t* t,
	                                            const ss_plugin_state_data* key,
	                                            ss_plugin_table_entry_t* entry);
	//
	// Updates a table's entry by writing a value for one of its fields.
	// The field accessor must be obtainied during plugin_init().
	// The written value is read from the "in" parameter.
	// Returns SS_PLUGIN_SUCCESS if successful, and SS_PLUGIN_FAILURE otherwise.
	ss_plugin_rc (*write_entry_field)(ss_plugin_table_t* t,
	                                  ss_plugin_table_entry_t* e,
	                                  const ss_plugin_table_field_t* f,
	                                  const ss_plugin_state_data* in);
} ss_plugin_table_writer_vtable_ext;

// Plugin-provided input passed to the add_table() callback of
// ss_plugin_init_tables_input, that can be used by the plugin to inform its
// owner about one of the state tables owned by the plugin. The plugin
// is responsible of owning all the memory pointed by this struct and
// of implementing all the API functions. These will be used by other
// plugins loaded by the falcosecurity libraries to interact with the state
// of a given plugin to implement cross-plugin state access.
typedef struct {
	// The name of the state table.
	const char* name;
	//
	// The type of the state table's key.
	ss_plugin_state_type key_type;
	//
	// A non-NULL opaque pointer to the state table.
	// This will be passed as parameters to all the callbacks defined below.
	ss_plugin_table_t* table;
	//
	// Supported but deprecated. Use the extended version reader_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_reader_vtable reader;
	//
	// Supported but deprecated. Use the extended version writer_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_writer_vtable writer;
	//
	// Supported but deprecated. Use the extended version fields_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_fields_vtable fields;
	//
	// Vtable for controlling read operations on the state table.
	ss_plugin_table_reader_vtable_ext* reader_ext;
	//
	// Vtable for controlling write operations on the state table.
	ss_plugin_table_writer_vtable_ext* writer_ext;
	//
	// Vtable for controlling operations related to fields on the state table.
	ss_plugin_table_fields_vtable_ext* fields_ext;
} ss_plugin_table_input;

// Initialization-time input related to the event parsing or field extraction capability.
// This provides the plugin with callback functions implemented by its owner
// that can be used to discover, access, and define state tables.
typedef struct {
	// Returns a pointer to an array containing info about all the tables
	// registered in the plugin's owner. ntables will be filled with the number
	// of elements of the returned array. The array's memory is owned by the
	// plugin's owner. Returns NULL in case of error.
	ss_plugin_table_info* (*list_tables)(ss_plugin_owner_t* o, uint32_t* ntables);
	//
	// Returns an opaque accessor to a state table registered in the plugin's
	// owner, given its name and key type. Returns NULL if an case of error.
	ss_plugin_table_t* (*get_table)(ss_plugin_owner_t* o,
	                                const char* name,
	                                ss_plugin_state_type key_type);
	//
	// Registers a new state table in the plugin's owner. Returns
	// SS_PLUGIN_SUCCESS in case of success, and SS_PLUGIN_FAILURE otherwise.
	// The state table is owned by the plugin itself, and the input will be used
	// by other actors of the plugin's owner to interact with the state table.
	ss_plugin_rc (*add_table)(ss_plugin_owner_t* o, const ss_plugin_table_input* in);
	//
	// Supported but deprecated. Use the extended version fields_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_fields_vtable fields;
	//
	// Vtable for controlling operations related to fields on the state tables
	// registered in the plugin's owner.
	ss_plugin_table_fields_vtable_ext* fields_ext;
	//
	// Vtable for controlling read operations on the state tables registered
	// in the plugin's owner.
	ss_plugin_table_reader_vtable_ext* reader_ext;
	//
	// Vtable for controlling write operations on the state tables registered
	// in the plugin's owner.
	ss_plugin_table_writer_vtable_ext* writer_ext;
} ss_plugin_init_tables_input;

// Function used by plugin for sending messages to the framework-provided logger
// Arguments:
//  - component: name of the component that is logging
//			(if set to NULL automatically falls back to the plugin name in the log)
//  - msg: message to log
//			(it doesn't have to be '\n' terminated)
//  - sev: message severity as defined in ss_plugin_log_severity
typedef void (*ss_plugin_log_fn_t)(ss_plugin_owner_t* o,
                                   const char* component,
                                   const char* msg,
                                   ss_plugin_log_severity sev);

// Input passed at the plugin through plugin_init(). This contain information
// common to any plugin, and also information useful only in case the plugin
// implements a given capability. If a certain capability is not implemented
// by the plugin, its information is set to NULL.
typedef struct ss_plugin_init_input {
	// An opaque string representing the plugin init configuration.
	// The format of the string is arbitrary and defined by the plugin itself.
	const char* config;
	//
	// The plugin's owner. Can be passed by the plugin to the callbacks available
	// in this struct in order to invoke functions of its owner.
	// It doesn't change during the whole plugin's lifecycle, it's safe to store it in the state
	ss_plugin_owner_t* owner;
	//
	// Return a string with the error that was last generated by the plugin's
	// owner, or NULL if no error is present.
	// The string pointer is owned by the plugin's owenr.
	const char* (*get_owner_last_error)(ss_plugin_owner_t* o);
	//
	// Init input related to the event parsing or field extraction capability.
	// It's set to NULL if the plugin does not implement at least one of the two
	// capabilities. The callbacks available in this input take the plugin's owner
	// as a parameter.
	const ss_plugin_init_tables_input* tables;
	//
	// Log function passed to the plugin through the init input
	// It doesn't change during the whole plugin's lifecycle, it's safe to store it in the state
	ss_plugin_log_fn_t log_fn;
} ss_plugin_init_input;

// Input passed to the plugin when extracting a field from an event for
// the field extraction capability.
typedef struct ss_plugin_field_extract_input {
	//
	// The plugin's owner. Can be passed by the plugin to the callbacks available
	// in this struct in order to invoke functions of its owner.
	ss_plugin_owner_t* owner;
	//
	// Return a string with the error that was last generated by the plugin's
	// owner, or NULL if no error is present.
	// The string pointer is owned by the plugin's owenr.
	const char* (*get_owner_last_error)(ss_plugin_owner_t* o);
	//
	// The length of the fields array.
	uint32_t num_fields;
	//
	// An array of ss_plugin_extract_field structs. Each entry
	// contains a single field + optional argument as input, and the corresponding
	// extracted value as output. Memory pointers set as output must be allocated
	// by the plugin and must not be deallocated or modified until the next
	// extract_fields() call.
	ss_plugin_extract_field* fields;
	//
	// Supported but deprecated. Use the extended version table_reader_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_reader_vtable table_reader;
	//
	// Vtable for controlling a state table for read operations.
	ss_plugin_table_reader_vtable_ext* table_reader_ext;
} ss_plugin_field_extract_input;

// Input passed to the plugin when parsing an event for the event parsing
// capability.
typedef struct ss_plugin_event_parse_input {
	//
	// The plugin's owner. Can be passed by the plugin to the callbacks available
	// in this struct in order to invoke functions of its owner.
	ss_plugin_owner_t* owner;
	//
	// Return a string with the error that was last generated by the plugin's
	// owner, or NULL if no error is present.
	// The string pointer is owned by the plugin's owenr.
	const char* (*get_owner_last_error)(ss_plugin_owner_t* o);
	//
	// Supported but deprecated. Use the extended version table_reader_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_reader_vtable table_reader;
	//
	// Supported but deprecated. Use the extended version table_writer_ext.
	// todo(jasondellaluce): when/if major changes to v4, remove this and
	// give this name to the associated *_ext pointer.
	ss_plugin_table_writer_vtable table_writer;
	//
	// Vtable for controlling a state table for read operations.
	ss_plugin_table_reader_vtable_ext* table_reader_ext;
	//
	// Vtable for controlling a state table for write operations.
	ss_plugin_table_writer_vtable_ext* table_writer_ext;
} ss_plugin_event_parse_input;

// Input passed to the plugin when setting a new configuration
typedef struct ss_plugin_set_config_input {
	//
	// An opaque string representing the new configuration provided by the framework
	const char* config;
} ss_plugin_set_config_input;

//
// An opaque pointer representing a routine subscribed in the framework-provided thread pool
typedef void ss_plugin_routine_t;

//
// An opaque pointer representing the state of the routine on each iteration
typedef void ss_plugin_routine_state_t;

//
// The function executed by the routine on each iteration.
// Arguments:
// - s: the plugin state, returned by init(). Can be NULL.
// - i: the routine state, provided by the plugin when the routine is subscribed
//
// Return value: Returning false causes the routine to be unsubcribed from the thread pool.
typedef ss_plugin_bool (*ss_plugin_routine_fn_t)(ss_plugin_t* s, ss_plugin_routine_state_t* i);

//
// Vtable used by the plugin to subscribe and unsubscribe recurring loop-like routines
// to the framework-provide thread pool
typedef struct {
	//
	// Subscribes a routine to the framework-provided thread pool.
	// Arguments:
	// - o: the plugin's owner
	// - f: the function executed by the routine on each iteration
	// - i: the routine's state
	//
	// Return value: A routine handle that can be used to later unsubscribe the routine. Returns
	// null in case of failure.
	ss_plugin_routine_t* (*subscribe)(ss_plugin_owner_t* o,
	                                  ss_plugin_routine_fn_t f,
	                                  ss_plugin_routine_state_t* i);

	//
	// Unsubscribes a routine from the framework-provided thread pool.
	// Arguments:
	// - o: the plugin's owner
	// - r: the routine's handle
	//
	// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
	ss_plugin_rc (*unsubscribe)(ss_plugin_owner_t* o, ss_plugin_routine_t* r);
} ss_plugin_routine_vtable;

// Input passed to the plugin when the framework start and stops the capture.
typedef struct ss_plugin_capture_listen_input {
	//
	// The plugin's owner. Can be passed by the plugin to the callbacks available
	// in this struct in order to invoke functions of its owner.
	ss_plugin_owner_t* owner;
	//
	// Vtable containing callbacks that can be used by the plugin
	// for subscribing and unsubscribing routines to the framework's thread pool.
	ss_plugin_routine_vtable* routine;
	//
	// Vtable for controlling a state table for read operations.
	ss_plugin_table_reader_vtable_ext* table_reader_ext;
	//
	// Vtable for controlling a state table for write operations.
	ss_plugin_table_writer_vtable_ext* table_writer_ext;
	//
	// Return a string with the error that was last generated by the plugin's
	// owner, or NULL if no error is present.
	// The string pointer is owned by the plugin's owenr.
	const char* (*get_owner_last_error)(ss_plugin_owner_t* o);
} ss_plugin_capture_listen_input;

//
// Function handler used by plugin for sending asynchronous events to the
// Falcosecurity libs during a live event capture. The asynchronous events
// must be encoded as an async event type (code 402) as for the libscap specific.
//
// The plugin framework will automatically set the plugin ID of the produced
// async event depending on the running event source in which the event will
// be injected into. The event's thread ID can be set to control the system
// thread associated, with value (uint64_t) -1) representing no thread
// association. The event's timestamp can be set to forcefully specify
// the timestamp of the phenomena that the event represents, and value
// (uint64_t) -1) will cause the plugin framework to automatically assign
// a timestamp as the time in which the event is received asynchronously.
//
// The function returns SS_PLUGIN_SUCCESS in case of success, or
// SS_PLUGIN_FAILURE otherwise. If a non-NULL char pointer is passed for
// the "err" argument, it will be filled with an error message string
// in case the handler function returns SS_PLUGIN_FAILURE. The error string
// has a max length of PLUGIN_MAX_ERRLEN (termination char included) and its
// memory must be allocated and owned by the plugin.
typedef ss_plugin_rc (*ss_plugin_async_event_handler_t)(ss_plugin_owner_t* o,
                                                        const ss_plugin_event* evt,
                                                        char* err);

//
// The struct below define the functions and arguments for plugins capabilities:
// * event sourcing
// * field extraction
// * event parsing
// The structs are used by the plugin framework to load and interface with plugins.
//
// From the perspective of the plugin, each function below should be
// exported from the dynamic library as a C calling convention
// function, adding a prefix "plugin_" to the function name
// (e.g. plugin_get_required_api_version, plugin_init, etc.)
//
// Plugins are totally responsible of both allocating and deallocating memory.
// Plugins have the guarantee that they can safely deallocate memory in
// these cases:
// - During close(), for all the memory allocated in the context of a plugin
//   instance after open().
// - During destroy(), for all the memory allocated by the plugin, as it stops
//   being executed.
// - During subsequent calls to the same function, for all the exported
//   functions returning memory pointers.
//
// Plugins must not free memory passed in by the framework (i.e. function input
// parameters) if not corresponding to plugin-allocated memory in the
// cases above. Plugins can safely use the passed memory during the execution
// of the exported functions.

//
// Plugins API vtable
//
typedef struct {
	//
	// Return the version of the plugin API used by this plugin.
	// Required: yes
	// Return value: the API version string, in the following format:
	//       "<major>.<minor>.<patch>", e.g. "1.2.3".
	// NOTE: to ensure correct interoperability between the framework and the plugins,
	//       we use a semver approach. Plugins are required to specify the version
	//       of the API they run against, and the framework will take care of checking
	//       and enforcing compatibility.
	//
	const char* (*get_required_api_version)();

	//
	// Return a string representation of a schema describing the data expected
	// to be passed as a configuration during the plugin initialization.
	// Required: no
	// Arguments:
	// - schema_type: The schema format type of the returned value among the
	//   list of the supported ones according to the ss_plugin_config_schema
	//   enumeration.
	// Return value: a string representation of the schema for the config
	//   to be passed to init().
	//
	// Plugins can optionally export this symbol to specify the expected
	// format for the configuration string passed to init(). If specified,
	// the init() function can assume the config string to always be
	// well-formed. The framework will take care of automatically parsing it
	// against the provided schema and generating ad-hoc errors accordingly.
	// This also serves as a piece of documentation for users about how the
	// plugin needs to be configured.
	//
	const char* (*get_init_schema)(ss_plugin_schema_type* schema_type);

	//
	// Initialize the plugin and allocate its state.
	// Required: yes
	// Arguments:
	// - in: init-time input for the plugin.
	// - rc: pointer to a ss_plugin_rc that will contain the initialization result
	// Return value: pointer to the plugin state that will be treated as opaque
	//   by the framework and passed to the other plugin functions.
	//   If rc is SS_PLUGIN_FAILURE, this function may return NULL or a state to
	//   later retrieve the error string.
	//
	// If a non-NULL ss_plugin_t* state is returned, then subsequent invocations
	// of init() must not return the same ss_plugin_t* value again, if not after
	// it has been disposed with destroy() first.
	ss_plugin_t* (*init)(const ss_plugin_init_input* input, ss_plugin_rc* rc);

	//
	// Destroy the plugin and, if plugin state was allocated, free it.
	// Required: yes
	//
	void (*destroy)(ss_plugin_t* s);

	//
	// Return a string with the error that was last generated by
	// the plugin.
	// Required: yes
	//
	// In cases where any other api function returns an error, the
	// plugin should be prepared to return a human-readable error
	// string with more context for the error. The framework
	// calls get_last_error() to access that string.
	//
	const char* (*get_last_error)(ss_plugin_t* s);

	//
	// Return the name of the plugin, which will be printed when displaying
	// information about the plugin.
	// Required: yes
	//
	const char* (*get_name)();

	//
	// Return the descriptions of the plugin, which will be printed when displaying
	// information about the plugin.
	// Required: yes
	//
	const char* (*get_description)();

	//
	// Return a string containing contact info (url, email, etc) for
	// the plugin authors.
	// Required: yes
	//
	const char* (*get_contact)();

	//
	// Return the version of this plugin itself
	// Required: yes
	// Return value: a string with a version identifier, in the following format:
	//        "<major>.<minor>.<patch>", e.g. "1.2.3".
	// This differs from the api version in that this versions the
	// plugin itself. Note, increasing the major version signals breaking
	// changes in the plugin implementation but must not change the
	// serialization format of the event data. For example, events written
	// in pre-existing capture files must always be readable by newer versions
	// of the plugin.
	//
	const char* (*get_version)();

	// Event sourcing capability API
	struct {
		//
		// Return the unique ID of the plugin.
		// Required: yes if get_event_source is defined and returns a non-empty string, no
		// otherwise.
		//
		// If the plugin has a specific ID and event source, then its next_batch()
		// function is allowed to only return events of plugin type (code 322)
		// with its own plugin ID and event source.
		//
		// EVERY PLUGIN WITH EVENT SOURCING CAPABILITY IMPLEMENTING
		// A SPECIFIC EVENT SOURCE MUST OBTAIN AN OFFICIAL ID FROM THE
		// FALCOSECURITY ORGANIZATION, OTHERWISE IT WON'T PROPERLY COEXIST
		// WITH OTHER PLUGINS.
		//
		uint32_t (*get_id)();

		//
		// Return a string representing the name of the event source generated
		// by this plugin.
		// Required: yes if get_id is defined and returns a non-zero number, no otherwise.
		//
		// If the plugin has a specific ID and event source, then its next_batch()
		// function is allowed to only return events of plugin type (code 322)
		// with its own plugin ID and event source.
		//
		// Example event sources would be strings like "aws_cloudtrail",
		// "k8s_audit", etc. The source can be used by plugins with event
		// sourcing capabilities to filter the events they receive.
		//
		const char* (*get_event_source)();

		//
		// Open the event source and start a capture (e.g. stream of events)
		// Required: yes
		// Arguments:
		// - s: the plugin state returned by init()
		// - params: the open parameters, as an opaque string.
		//           The string format is defined by the plugin itself
		// - rc: pointer to a ss_plugin_rc that will contain the open result
		// Return value: a pointer to the opened plugin instance that will be
		//               passed to next_batch(), close(), event_to_string()
		//               and extract_fields().
		//
		// If a non-NULL ss_instance_t* instance is returned, then subsequent
		// invocations of open() must not return the same ss_instance_t* value
		// again, if not after it has been disposed with close() first.
		ss_instance_t* (*open)(ss_plugin_t* s, const char* params, ss_plugin_rc* rc);

		//
		// Close a capture.
		// Required: yes
		// Arguments:
		// - s: the plugin state, returned by init(). Can be NULL.
		// - h: the plugin instance, returned by open(). Can be NULL.
		//
		void (*close)(ss_plugin_t* s, ss_instance_t* h);

		//
		// Return a list of suggested open parameters supported by this plugin.
		// Any of the values in the returned list are valid parameters for open().
		// Required: no
		// Return value: a string with the list of open params encoded as
		//   a json array. Each field entry is a json object with the following
		//   properties:
		//     - "value": a string usable as an open() parameter.
		//     - "desc": (optional) a string with a description of the parameter.
		//     - "separator": (optional) a separator string, for when "value"
		//                    represents multiple contatenated open parameters
		//   Example return value:
		//   [
		//      {"value": "resource1", "desc": "An example of openable resource"},
		//      {"value": "resource2", "desc": "Another example of openable resource"},
		//      {
		//          "value": "res1;res2;res3",
		//          "desc": "Some names",
		//          "separator": ";"
		//      }
		//   ]
		const char* (*list_open_params)(ss_plugin_t* s, ss_plugin_rc* rc);

		//
		// Return the read progress.
		// Required: no
		// Arguments:
		// - progress_pct: the read progress, as a number between 0 (no data has been read)
		//   and 10000 (100% of the data has been read). This encoding allows the framework to
		//   print progress decimals without requiring to deal with floating point numbers
		//   (which could cause incompatibility problems with some languages).
		// Return value: a string representation of the read
		//   progress. This might include the progress percentage
		//   combined with additional context added by the plugin. If
		//   NULL, progress_pct should be used.
		//   The returned memory pointer must be allocated by the plugin
		//   and must not be deallocated or modified until the next call to
		//   get_progress().
		// NOTE: reporting progress is optional and in some case could be impossible. However,
		//       when possible, it's recommended as it provides valuable information to the
		//       user.
		//
		// This function can be invoked concurrently by multiple threads,
		// each with distinct and unique parameter values.
		// If the returned pointer is non-NULL, then it must be uniquely
		// attached to the ss_instance_t* parameter value. The pointer must not
		// be shared across multiple distinct ss_instance_t* values.
		const char* (*get_progress)(ss_plugin_t* s, ss_instance_t* h, uint32_t* progress_pct);

		//
		// Return a text representation of an event generated by this plugin with
		// event sourcing capability. Even if defined, this function is not
		// used by the framework if the plugin does not implement a specific
		// event source (get_id() is zero or get_event_source() is empty).
		//
		// Required: no
		//
		// Arguments:
		// - evt: an event input provided by the framework.
		//   This is allocated by the framework, and it is not guaranteed
		//   that the event struct pointer is the same returned by the last
		//   next_batch() call.
		// Return value: the text representation of the event. This is used, for example,
		//   to print a line for the given event.
		//   The returned memory pointer must be allocated by the plugin
		//   and must not be deallocated or modified until the next call to
		//   event_to_string().
		//
		// This function can be invoked concurrently by multiple threads,
		// each with distinct and unique parameter values.
		// If the returned pointer is non-NULL, then it must be uniquely
		// attached to the ss_plugin_t* parameter value. The pointer must not
		// be shared across multiple distinct ss_plugin_t* values.
		const char* (*event_to_string)(ss_plugin_t* s, const ss_plugin_event_input* evt);

		//
		// Return the next batch of events.
		// On success:
		//   - nevts will be filled in with the number of events.
		//   - evts: pointer to an ss_plugin_event pointer. The plugin must
		//     allocate an array of contiguous ss_plugin_event structs
		//     and each data buffer within each ss_plugin_event struct.
		//     Memory pointers set as output must be allocated by the plugin
		//     and must not be deallocated or modified until the next call to
		//     next_batch() or close().
		// Required: yes
		//
		// If a plugin implements a specific event source (get_id() is non-zero
		// and get_event_source() is non-empty), then, it is only allowed to
		// produce events of type plugin (code 322) containing its own plugin ID
		// (as returned by get_id()). In such a case, when an event contains
		// a zero plugin ID, the framework automatically sets the plugin ID of
		// the event to the one of the plugin. If a plugin does not implement
		// a specific event source, it is allowed to produce events of any
		// of the types supported by the libscap specific.
		//
		// This function can be invoked concurrently by multiple threads,
		// each with distinct and unique parameter values.
		// The value of the ss_plugin_event** output parameter must be uniquely
		// attached to the ss_instance_t* parameter value. The pointer must not
		// be shared across multiple distinct ss_instance_t* values.
		ss_plugin_rc (*next_batch)(ss_plugin_t* s,
		                           ss_instance_t* h,
		                           uint32_t* nevts,
		                           ss_plugin_event*** evts);
	};

	// Field extraction capability API
	struct {
		//
		// Return the list of event types that this plugin will receive
		// for field extraction. The event types follow the libscap specific.
		// This will be invoked only once by the framework after the plugin's
		// initialization. Events that are not included in the returned list
		// will not be received by the plugin.
		//
		// This is a non-functional filter that should not influence the plugin's
		// functional behavior. Instead, this is a performance optimization
		// with the goal of avoiding unnecessary communication between the
		// framework and the plugin for events that are known to be not used for
		// field extraction.
		//
		// Required: no
		//
		// This function is optional--if NULL or an empty array, then:
		// - the plugin will receive every event type if the result of
		//   get_extract_event_sources (either default or custom) is compatible
		//   with the "syscall" event source, otherwise
		// - the plugin will only receive events of plugin type (code 322).
		// todo(jasondellaluce): when/if major changes to v4, reorder the arguments
		// and put ss_plugin_t* as first
		uint16_t* (*get_extract_event_types)(uint32_t* numtypes, ss_plugin_t* s);

		//
		// Return a string describing the event sources that this plugin
		// can consume for field extraction.
		// Required: no
		// Return value: a json array of strings containing event
		//   sources returned by a plugin with event sourcing capabilities get_event_source()
		//   function, or "syscall" for indicating support to non-plugin events.
		// This function is optional--if NULL or an empty array, then if plugin has sourcing
		// capability, and implements a specific event source, it will only receive events matching
		// its event source, otherwise it will receive events from all event sources.
		//
		const char* (*get_extract_event_sources)();

		//
		// Return the list of extractor fields exported by this plugin. Extractor
		// fields can be used in Falco rule conditions.
		// Required: yes
		// Return value: a string with the list of fields encoded as a json
		//   array.
		//   Each field entry is a json object with the following properties:
		//     "name": a string with a name for the field
		//     "type": one of "string", "uint64", "bool", "reltime", "abstime",
		//             "ipaddr", "ipnet"
		//     "isList: (optional) if present and set to true, notes
		//              that the field extracts a list of values.
		//     "arg": (optional) if present, notes that the field can accept
		//             an argument e.g. field[arg]. More precisely, the following
		//             flags could be specified:
		//             "isRequired": if true, the argument is required.
		//             "isIndex": if true, the field is numeric.
		//             "isKey": if true, the field is a string.
		//             If "isRequired" is true, one between "isIndex" and
		//             "isKey" must be true, to specify the argument type.
		//             If "isRequired" is false, but one between "isIndex"
		//             and "isKey" is true, the argument is allowed but
		//             not required.
		//     "display": (optional) If present, a string that will be used to
		//                display the field instead of the name. Used in tools
		//                like wireshark.
		//     "desc": a string with a description of the field
		//     "addOutput": (optional) if true, suggest this field to be appended to the
		//				  output string for compatible event sources.
		// Example return value:
		// [
		//    {"type": "uint64", "name": "field1", "desc": "Describing field 1", "addOutput": true},
		//    {"type": "string", "name": "field2", "arg": {"isRequired": true, "isIndex": true},
		//    "desc": "Describing field 2"},
		// ]
		const char* (*get_fields)();

		//
		// Extract one or more a filter field values from an event.
		// Required: yes
		// Arguments:
		// - evt: an event input provided by the framework.
		//   This is allocated by the framework, and it is not guaranteed
		//   that the event struct pointer is the same returned by the last
		//   next_batch() call.
		// - in: An input struct representing the extraction request.
		//   The input includes vtables containing callbacks that can be used by
		//   the plugin for performing read/write operations on a state table
		//   not owned by itelf, for which it obtained accessors at init time.
		//   The plugin does not need to go through this vtable in order
		//   to read and write from a table it owns.
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		//
		// This function can be invoked concurrently by multiple threads,
		// each with distinct and unique parameter values.
		// The value of the ss_plugin_extract_field* output parameter must be
		// uniquely attached to the ss_plugin_t* parameter value. The pointer
		// must not be shared across multiple distinct ss_plugin_t* values.
		ss_plugin_rc (*extract_fields)(ss_plugin_t* s,
		                               const ss_plugin_event_input* evt,
		                               const ss_plugin_field_extract_input* in);
	};

	// Event parsing capability API
	struct {
		//
		// Return the list of event types that this plugin will receive
		// for event parsing. The event types follow the libscap specific.
		// This will be invoked only once by the framework after the plugin's
		// initialization. Events that are not included in the returned list
		// will not be received by the plugin.
		//
		// This is a non-functional filter that should not influence the plugin's
		// functional behavior. Instead, this is a performance optimization
		// with the goal of avoiding unnecessary communication between the
		// framework and the plugin for events that are known to be not used for
		// event parsing.
		//
		// Required: no
		//
		// This function is optional--if NULL or an empty array, then:
		// - the plugin will receive every event type if the result of
		//   get_parse_event_sources (either default or custom) is compatible
		//   with the "syscall" event source, otherwise
		// - the plugin will only receive events of plugin type (code 322).
		// todo(jasondellaluce): when/if major changes to v4, reorder the arguments
		// and put ss_plugin_t* as first
		uint16_t* (*get_parse_event_types)(uint32_t* numtypes, ss_plugin_t* s);
		//
		// Return a string describing the event sources that this plugin
		// is capable of parsing.
		//
		// Required: no
		//
		// Return value: a json array of strings containing event
		//   sources returned by a plugin with event sourcing capabilities get_event_source()
		//   function, or "syscall" for indicating support to non-plugin events.
		// This function is optional--if NULL or an empty array, then if plugin has sourcing
		// capability, and implements a specific event source, it will only receive events matching
		// its event source, otherwise it will receive events from all event sources.
		//
		const char* (*get_parse_event_sources)();
		//
		// Receives an event from the current capture and parses its content.
		// The plugin is guaranteed to receive an event at most once, after any
		// operation related the event sourcing capability, and before
		// any operation related to the field extraction capability.
		//
		// Required: yes
		//
		// Arguments:
		// - evt: an event input provided by the framework.
		//   This is allocated by the framework, and it is not guaranteed
		//   that the event struct pointer is the same returned by the last
		//   next_batch() call.
		// - in: A vtable containing callbacks that can be used by
		//   the plugin for performing read/write operations on a state table
		//   not owned by itelf, for which it obtained accessors at init time.
		//   The plugin does not need to go through this vtable in order
		//   to read and write from a table it owns.
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		//
		// This function can be invoked concurrently by multiple threads,
		// each with distinct and unique parameter values.
		// The value of the ss_plugin_event_parse_input* output parameter must be
		// uniquely attached to the ss_plugin_t* parameter value. The pointer
		// must not be shared across multiple distinct ss_plugin_t* values.
		ss_plugin_rc (*parse_event)(ss_plugin_t* s,
		                            const ss_plugin_event_input* evt,
		                            const ss_plugin_event_parse_input* in);
	};

	// Async events capability API
	struct {
		//
		// Return a string describing the event sources for which this plugin
		// is capable of injecting async events in the event stream of a capture.
		//
		// Required: no
		//
		// Return value: a json array of strings containing event
		//   sources returned by a plugin with event sourcing capabilities
		//   get_event_source() function, or "syscall" for indicating
		//   support to non-plugin events.
		// This function is optional--if NULL or an empty array, then async
		// events produced by this plugin will be injected in the event stream
		// of any data source.
		//
		const char* (*get_async_event_sources)();
		//
		// Return a string describing the name list of all asynchronous events
		// that this plugin is capable of pushing into a live event stream.
		// The framework rejects async events produced by a plugin if their
		// name is not on the name list returned by this function.
		//
		// Required: yes
		//
		// Return value: a non-empty json array of strings containing the
		//   names of the async events returned by a plugin.
		const char* (*get_async_events)();
		//
		// Sets a function handler that allows the plugin to send asynchronous
		// events to its owner during a live event capture. The handler is
		// a thread-safe function that can be invoked concurrently by
		// multiple threads. The asynchronous events must be encoded as
		// an async event type (code 402) as for the libscap specific.
		//
		// The plugin can start sending async events through the passed-in
		// handler right after returning from this function.
		// set_async_event_handler() can be invoked multiple times during the
		// lifetime of a plugin. In that case, the registered function handler
		// remains valid up until the next invocation of set_async_event_handler()
		// on the same plugin, after which the new handler set will replace any
		// already-set one. If the handler is set to a NULL function pointer,
		// the plugin is instructed about disabling or stopping the
		// production of async events. If a NULL handler is set, and an
		// asynchronous job has been started by the plugin before, the plugin
		// should stop the job and wait for it to be finished before returning
		// from this function. Although the event handler is thread-safe and
		// can be invoked concurrently, this function is still invoked
		// by the framework sequentially from the same thread.
		//
		// Async events encode a plugin ID that defines its event source.
		// However, this value is set by the framework when the async event
		// is received, and is set to the ID associated to the plugin-defined
		// event source currently open during a live capture, or zero in case
		// of the "syscall" event source. The event source assigned by the
		// framework to the async event can only be among the ones compatible
		// with the list returned by get_async_event_sources().
		//
		// Async events encode a string representing their event name, which is
		// used for runtime matching and define the encoded data payload.
		// Plugins are allowed to only send async events with one of the names
		// expressed in the list returned by get_async_events(). The name
		// of an async event acts as a contract on the encoding of the data
		// payload of all async events with the same name.
		//
		// Required: yes
		//
		// Arguments:
		// - owner: Opaque pointer to the plugin's owner. Must be passed
		//   as an argument to the async event function handler.
		// - handler: Function handler to be used for sending asynchronous
		//   events to the plugin's owner. The handler must be invoked with
		//   the same owner opaque pointer passed to this function, and with
		//   an event pointer owned and controlled by the plugin. The event
		//   pointer is not retained by the handler after it returns.
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		//
		ss_plugin_rc (*set_async_event_handler)(ss_plugin_t* s,
		                                        ss_plugin_owner_t* owner,
		                                        const ss_plugin_async_event_handler_t handler);

		//
		// Called by the framework when a capture file dump is requested.
		//
		// Required: no
		// Arguments:
		// - s: the plugin state, returned by init(). Can be NULL.
		// - owner: Opaque pointer to the plugin's owner. Must be passed
		//	 as an argument to the async event function handler.
		// - handler: Function handler to be used for sending events to be dumped
		//   to the plugin's owner. The handler must be invoked with
		//   the same owner opaque pointer passed to this function, and with
		//   an event pointer owned and controlled by the plugin. The event
		//   pointer is not retained by the handler after it returns.
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		ss_plugin_rc (*dump_state)(ss_plugin_t* s,
		                           ss_plugin_owner_t* owner,
		                           const ss_plugin_async_event_handler_t handler);
	};

	// Sets a new plugin configuration when provided by the framework.
	// Required: no
	// Arguments:
	// - s: the plugin state, returned by init(). Can be NULL.
	// - i: configuration input provided by the framework.
	//
	// Return value: A ss_plugin_rc with value SS_PLUGIN_SUCCESS if the config is accepted
	// or SS_PLUGIN_FAILURE if the config is rejected.
	// If rejected the plugin should provide context in the string returned by get_last_error().
	ss_plugin_rc (*set_config)(ss_plugin_t* s, const ss_plugin_set_config_input* i);

	//
	// Return an updated set of metrics provided by this plugin.
	// Required: no
	// Arguments:
	// - s: the plugin state, returned by init(). Can be NULL.
	// - num_metrics: lenght of the returned metrics array.
	//
	// Return value: Pointer to the first element of the metrics array.
	// 'num_metrics' must be set to the lenght of the array before returning
	// and it can be set to 0 if no metrics are provided.
	ss_plugin_metric* (*get_metrics)(ss_plugin_t* s, uint32_t* num_metrics);

	// Capture listening capability API
	struct {
		//
		// Called by the framework when the event capture opens.
		//
		// Required: no
		// Arguments:
		// - s: the plugin state, returned by init(). Can be NULL.
		// - i: input containing vtables for performing table operations and subscribe/unsubscribe
		// async routines
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		ss_plugin_rc (*capture_open)(ss_plugin_t* s, const ss_plugin_capture_listen_input* i);

		//
		// Called by the framework when the event capture closes.
		//
		// Required: yes if capture_open is defined
		// Arguments:
		// - s: the plugin state, returned by init(). Can be NULL.
		// - i: input containing vtables for performing table operations and subscribe/unsubscribe
		// async routines
		//
		// Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE.
		ss_plugin_rc (*capture_close)(ss_plugin_t* s, const ss_plugin_capture_listen_input* i);
	};
} plugin_api;

#ifdef __cplusplus
}
#endif