1use serde::{Deserialize, Serialize};
7
8pub mod canonical;
9pub mod semantics_v3;
10
11pub const RAW_OBSERVATION_SCHEMA_VERSION: u32 = 2;
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14pub struct Observation {
15 pub schema_version: u32,
16 pub backend: BackendMetadata,
17 pub complete: bool,
18 pub outcome: CommandOutcome,
19 pub events: Vec<RawEvent>,
20 pub warnings: Vec<ObserverWarning>,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24pub struct BackendMetadata {
25 pub name: String,
26 pub platform: String,
27 pub architecture: String,
28 pub capabilities: Vec<String>,
29 pub limitations: Vec<String>,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
33pub struct CommandOutcome {
34 pub exit_code: Option<i32>,
35 pub signal: Option<i32>,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39pub struct RawEvent {
40 pub sequence: u64,
41 pub tid: i32,
42 #[serde(flatten)]
43 pub kind: RawEventKind,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47#[serde(tag = "event_type", rename_all = "snake_case")]
48pub enum RawEventKind {
49 ProcessSpawn {
50 child_tid: i32,
51 mechanism: SpawnMechanism,
52 },
53 ProcessExec {
54 path: String,
55 },
56 FilePathAccess {
57 operation: FileOperation,
58 path: String,
59 flags: Option<u64>,
60 },
61 FileOpenAt2 {
62 path: String,
63 flags: u64,
64 resolve: u64,
65 },
66 FileDescriptorAccess {
67 operation: FileOperation,
68 fd: i32,
69 path: String,
70 },
71 FileRename {
72 from: String,
73 to: String,
74 },
75 NetworkConnectAttempt {
76 endpoint: NetworkEndpoint,
77 },
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
81#[serde(rename_all = "snake_case")]
82pub enum SpawnMechanism {
83 Fork,
84 Vfork,
85 Clone,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
89#[serde(rename_all = "snake_case")]
90pub enum FileOperation {
91 Open,
92 Create,
93 Delete,
94 Read,
95 Write,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99#[serde(tag = "address_family", rename_all = "snake_case")]
100pub enum NetworkEndpoint {
101 Inet { ip: String, port: u16 },
102 Inet6 { ip: String, port: u16 },
103 Unix { path: Option<String> },
104 Other { family: u16 },
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108pub struct ObserverWarning {
109 pub code: String,
110 pub tid: Option<i32>,
111 pub message: String,
112}
113
114impl Observation {
115 pub fn empty(backend: BackendMetadata) -> Self {
116 Self {
117 schema_version: RAW_OBSERVATION_SCHEMA_VERSION,
118 backend,
119 complete: true,
120 outcome: CommandOutcome::default(),
121 events: Vec::new(),
122 warnings: Vec::new(),
123 }
124 }
125}