#![no_std]
#![allow(unsafe_code)]
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "std")]
pub mod exports;
pub const EVENT_OPENAT: u32 = 1;
pub const EVENT_CONNECT: u32 = 2;
pub const EVENT_FORK: u32 = 3;
pub const EVENT_EXEC: u32 = 4;
pub const EVENT_EXIT: u32 = 5;
pub const KEY_MONITOR_ALL: u32 = 100;
pub const EVENT_FILE_BLOCKED: u32 = 10;
pub const EVENT_CONNECT_BLOCKED: u32 = 20;
pub const DATA_LEN: usize = 512;
pub const MONITOR_STATS_LEN: u32 = 10;
pub const MONITOR_STAT_TRACEPOINT_EVENTS_EMITTED: u32 = 0;
pub const MONITOR_STAT_TRACEPOINT_RINGBUF_DROPPED: u32 = 1;
pub const MONITOR_STAT_LSM_EVENTS_EMITTED: u32 = 2;
pub const MONITOR_STAT_LSM_RINGBUF_DROPPED: u32 = 3;
pub const SOCKET_STATS_LEN: u32 = 8;
pub const SOCKET_STAT_CHECKS: u32 = 0;
pub const SOCKET_STAT_BLOCKED_CIDR: u32 = 1;
pub const SOCKET_STAT_BLOCKED_PORT: u32 = 2;
pub const SOCKET_STAT_ALLOWED: u32 = 3;
pub const SOCKET_STAT_EVENTS_EMITTED: u32 = 4;
pub const SOCKET_STAT_RINGBUF_DROPPED: u32 = 5;
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct MonitorEvent {
pub pid: u32,
pub event_type: u32,
pub data: [u8; DATA_LEN],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct InodeKey {
pub ino: u64,
pub dev: u32,
pub gen: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct InodeKeyMap {
pub ino: u64,
pub dev: u32,
pub gen: u32,
}
#[cfg(target_os = "linux")]
pub fn encode_kernel_dev(dev: u64) -> u32 {
let major = ((dev >> 8) & 0xfff) as u32;
let minor = ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as u32;
(minor & 0xff) | ((major & 0xfff) << 8) | ((minor & 0xfffff00) << 12)
}
pub const EVENT_INODE_RESOLVED: u32 = 112;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct InodeResolved {
pub dev: u64, pub ino: u64, pub gen: u32, pub _pad: u32,
}
#[cfg(all(target_os = "linux", feature = "user"))]
unsafe impl aya::Pod for InodeResolved {}
#[cfg(all(target_os = "linux", feature = "user"))]
unsafe impl aya::Pod for InodeKeyMap {}
#[cfg(all(target_os = "linux", feature = "user"))]
unsafe impl aya::Pod for InodeKey {}
#[cfg(all(target_os = "linux", feature = "user"))]
const _: () = {
fn _assert_pod<T: aya::Pod>() {}
fn _check() {
_assert_pod::<InodeKeyMap>();
}
};
impl MonitorEvent {
pub const fn zeroed() -> Self {
Self {
pid: 0,
event_type: 0,
data: [0u8; DATA_LEN],
}
}
}
impl Default for MonitorEvent {
fn default() -> Self {
Self::zeroed()
}
}
const _: [(); 520] = [(); core::mem::size_of::<MonitorEvent>()];
const _: [(); 4] = [(); core::mem::align_of::<MonitorEvent>()];
#[cfg(all(target_os = "linux", feature = "std"))]
pub fn get_inode_generation(fd: std::os::fd::RawFd) -> std::io::Result<u32> {
use nix::libc;
use nix::request_code_read;
const fn fs_ioc_getversion() -> libc::c_ulong {
request_code_read!(b'v', 1, core::mem::size_of::<libc::c_long>()) as libc::c_ulong
}
let mut out: libc::c_long = 0;
let rc = unsafe { libc::ioctl(fd, fs_ioc_getversion() as _, &mut out) };
if rc < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(out as u32)
}
#[cfg(all(target_os = "linux", feature = "std"))]
pub mod strict_open {
use libc::c_long;
use std::{ffi::CStr, mem::size_of};
#[repr(C)]
pub struct OpenHow {
pub flags: u64,
pub mode: u64,
pub resolve: u64,
}
pub const RESOLVE_NO_SYMLINKS: u64 = 0x04;
pub fn openat2_strict(path: &CStr) -> std::io::Result<i32> {
let how = OpenHow {
flags: (libc::O_RDONLY | libc::O_NONBLOCK | libc::O_CLOEXEC) as u64,
mode: 0,
resolve: RESOLVE_NO_SYMLINKS, };
let fd = unsafe {
libc::syscall(
libc::SYS_openat2,
libc::AT_FDCWD,
path.as_ptr(),
&how as *const OpenHow,
size_of::<OpenHow>(),
) as c_long
};
if fd < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(fd as i32)
}
}