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