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")]
main() -> Result<(), Box<dyn Error>>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