1 use aya::maps::HashMap; 2 use aya::programs::KProbe; 3 use aya::{include_bytes_aligned, Ebpf}; 4 use aya_log::EbpfLogger; 5 use log::{info, warn}; 6 use std::error::Error; 7 use tokio::task::yield_now; 8 use tokio::{signal, time}; 9 10 #[tokio::main(flavor = "current_thread")] 11 async fn main() -> Result<(), Box<dyn Error>> { 12 env_logger::builder() 13 .filter_level(log::LevelFilter::Warn) 14 .format_timestamp(None) 15 .init(); 16 17 let mut bpf = Ebpf::load(include_bytes_aligned!( 18 "../syscall_ebpf/target/bpfel-unknown-none/release/syscall_ebpf" 19 ))?; 20 21 // create a async task to read the log 22 if let Err(e) = EbpfLogger::init(&mut bpf) { 23 // This can happen if you remove all log statements from your eBPF program. 24 warn!("failed to initialize eBPF logger: {}", e); 25 } 26 27 let program: &mut KProbe = bpf.program_mut("syscall_ebpf").unwrap().try_into()?; 28 program.load()?; 29 program.attach("dragonos_kernel::syscall::Syscall::handle", 0)?; 30 31 info!("attacch the kprobe to dragonos_kernel::syscall::Syscall::handle"); 32 33 // print the value of the blocklist per 5 seconds 34 tokio::spawn(async move { 35 let blocklist: HashMap<_, u32, u32> = 36 HashMap::try_from(bpf.map("SYSCALL_LIST").unwrap()).unwrap(); 37 let mut now = time::Instant::now(); 38 loop { 39 let new_now = time::Instant::now(); 40 let duration = new_now.duration_since(now); 41 if duration.as_secs() >= 5 { 42 println!("------------SYSCALL_LIST----------------"); 43 let iter = blocklist.iter(); 44 for item in iter { 45 if let Ok((key, value)) = item { 46 println!("syscall: {:?}, count: {:?}", key, value); 47 } 48 } 49 println!("----------------------------------------"); 50 now = new_now; 51 } 52 yield_now().await; 53 } 54 }); 55 56 info!("Waiting for Ctrl-C..."); 57 signal::ctrl_c().await?; 58 info!("Exiting..."); 59 Ok(()) 60 } 61