1#![no_std]
2#![allow(unsafe_code)]
3
4#[cfg(feature = "std")]
5extern crate std;
6
7#[cfg(feature = "std")]
8pub mod exports;
9
10pub const EVENT_OPENAT: u32 = 1;
11pub const EVENT_CONNECT: u32 = 2;
12pub const EVENT_FORK: u32 = 3;
13pub const EVENT_EXEC: u32 = 4;
14pub const EVENT_EXIT: u32 = 5;
15
16pub const KEY_MONITOR_ALL: u32 = 100;
17
18pub const EVENT_FILE_BLOCKED: u32 = 10;
19pub const EVENT_CONNECT_BLOCKED: u32 = 20;
20
21pub const DATA_LEN: usize = 512;
22
23pub const MONITOR_STATS_LEN: u32 = 10;
24pub const MONITOR_STAT_TRACEPOINT_EVENTS_EMITTED: u32 = 0;
25pub const MONITOR_STAT_TRACEPOINT_RINGBUF_DROPPED: u32 = 1;
26pub const MONITOR_STAT_LSM_EVENTS_EMITTED: u32 = 2;
27pub const MONITOR_STAT_LSM_RINGBUF_DROPPED: u32 = 3;
28
29pub const SOCKET_STATS_LEN: u32 = 8;
30pub const SOCKET_STAT_CHECKS: u32 = 0;
31pub const SOCKET_STAT_BLOCKED_CIDR: u32 = 1;
32pub const SOCKET_STAT_BLOCKED_PORT: u32 = 2;
33pub const SOCKET_STAT_ALLOWED: u32 = 3;
34pub const SOCKET_STAT_EVENTS_EMITTED: u32 = 4;
35pub const SOCKET_STAT_RINGBUF_DROPPED: u32 = 5;
36
37#[repr(C)]
38#[derive(Clone, Copy, Debug, Eq, PartialEq)]
39pub struct MonitorEvent {
40 pub pid: u32,
41 pub event_type: u32,
42 pub data: [u8; DATA_LEN],
43}
44
45#[repr(C)]
59#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
60pub struct InodeKey {
61 pub ino: u64,
62 pub dev: u32,
63 pub gen: u32,
64}
65
66#[repr(C)]
70#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
71pub struct InodeKeyMap {
72 pub ino: u64,
73 pub dev: u32,
74 pub gen: u32,
75}
76
77#[cfg(target_os = "linux")]
81pub fn encode_kernel_dev(dev: u64) -> u32 {
82 let major = ((dev >> 8) & 0xfff) as u32;
86 let minor = ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as u32;
87
88 (minor & 0xff) | ((major & 0xfff) << 8) | ((minor & 0xfffff00) << 12)
91}
92
93pub const EVENT_INODE_RESOLVED: u32 = 112;
95
96#[repr(C)]
98#[derive(Clone, Copy, Debug)]
99pub struct InodeResolved {
100 pub dev: u64, pub ino: u64, pub gen: u32, pub _pad: u32,
104}
105
106#[cfg(all(target_os = "linux", feature = "user"))]
107unsafe impl aya::Pod for InodeResolved {}
108
109#[cfg(all(target_os = "linux", feature = "user"))]
110unsafe impl aya::Pod for InodeKeyMap {}
111
112#[cfg(all(target_os = "linux", feature = "user"))]
113unsafe impl aya::Pod for InodeKey {}
114
115#[cfg(all(target_os = "linux", feature = "user"))]
116const _: () = {
117 fn _assert_pod<T: aya::Pod>() {}
118 fn _check() {
119 _assert_pod::<InodeKeyMap>();
120 }
121};
122
123impl MonitorEvent {
124 pub const fn zeroed() -> Self {
125 Self {
126 pid: 0,
127 event_type: 0,
128 data: [0u8; DATA_LEN],
129 }
130 }
131}
132
133impl Default for MonitorEvent {
134 fn default() -> Self {
135 Self::zeroed()
136 }
137}
138
139const _: [(); 520] = [(); core::mem::size_of::<MonitorEvent>()];
145
146const _: [(); 4] = [(); core::mem::align_of::<MonitorEvent>()];
148
149#[cfg(all(target_os = "linux", feature = "std"))]
150pub fn get_inode_generation(fd: std::os::fd::RawFd) -> std::io::Result<u32> {
151 use nix::libc;
152 use nix::request_code_read;
153
154 const fn fs_ioc_getversion() -> libc::c_ulong {
160 request_code_read!(b'v', 1, core::mem::size_of::<libc::c_long>()) as libc::c_ulong
161 }
162
163 let mut out: libc::c_long = 0;
164 let rc = unsafe { libc::ioctl(fd, fs_ioc_getversion() as _, &mut out) };
167 if rc < 0 {
168 return Err(std::io::Error::last_os_error());
169 }
170 Ok(out as u32)
171}
172
173#[cfg(all(target_os = "linux", feature = "std"))]
174pub mod strict_open {
175 use libc::c_long;
176 use std::{ffi::CStr, mem::size_of};
177
178 #[repr(C)]
179 pub struct OpenHow {
180 pub flags: u64,
181 pub mode: u64,
182 pub resolve: u64,
183 }
184
185 pub const RESOLVE_NO_SYMLINKS: u64 = 0x04;
187 pub fn openat2_strict(path: &CStr) -> std::io::Result<i32> {
190 let how = OpenHow {
191 flags: (libc::O_RDONLY | libc::O_NONBLOCK | libc::O_CLOEXEC) as u64,
192 mode: 0,
193 resolve: RESOLVE_NO_SYMLINKS, };
195
196 let fd = unsafe {
197 libc::syscall(
198 libc::SYS_openat2,
199 libc::AT_FDCWD,
200 path.as_ptr(),
201 &how as *const OpenHow,
202 size_of::<OpenHow>(),
203 ) as c_long
204 };
205
206 if fd < 0 {
207 return Err(std::io::Error::last_os_error());
208 }
209 Ok(fd as i32)
210 }
211}