useanyhow::Context;useaya::{include_bytes_aligned,programs::{Xdp,XdpFlags},Bpf,};useaya_log::BpfLogger;useclap::Parser;uselog::{info,warn};usetokio::signal;#[derive(Debug, Parser)]structOpt{#[clap(short, long, default_value = "eth0")]iface: String,}#[tokio::main]asyncfnmain()-> Result<(),anyhow::Error>{letopt=Opt::parse();env_logger::init();// This will include your eBPF object file as raw bytes at compile-time and load it at// runtime. This approach is recommended for most real-world use cases. If you would// like to specify the eBPF program at runtime rather than at compile-time, you can// reach for `Bpf::load_file` instead.#[cfg(debug_assertions)]letmutbpf=Bpf::load(include_bytes_aligned!("../../target/bpfel-unknown-none/debug/xdp-log"))?;#[cfg(not(debug_assertions))]letmutbpf=Bpf::load(include_bytes_aligned!("../../target/bpfel-unknown-none/release/xdp-log"))?;ifletErr(e)=BpfLogger::init(&mutbpf){// This can happen if you remove all log statements from your eBPF program.warn!("failed to initialize eBPF logger: {}",e);}letprogram: &mutXdp=bpf.program_mut("xdp_firewall").unwrap().try_into()?;program.load()?;program.attach(&opt.iface,XdpFlags::default()).context("failed to attach the XDP program with default flags - try changing XdpFlags::default() to XdpFlags::SKB_MODE")?;info!("Waiting for Ctrl-C...");signal::ctrl_c().await?;info!("Exiting...");Ok(())}
运行程序
与之前一样,可以通过提供接口名称作为参数来覆盖接口,例如,RUST_LOG=info cargo xtask run -- --iface wlp2s0。
$ RUST_LOG=info cargo xtask run
[2022-12-22T11:32:21Z INFO xdp_log] SRC IP: 172.52.22.104, SRC PORT: 443[2022-12-22T11:32:21Z INFO xdp_log] SRC IP: 172.52.22.104, SRC PORT: 443[2022-12-22T11:32:21Z INFO xdp_log] SRC IP: 172.52.22.104, SRC PORT: 443[2022-12-22T11:32:21Z INFO xdp_log] SRC IP: 172.52.22.104, SRC PORT: 443[2022-12-22T11:32:21Z INFO xdp_log] SRC IP: 234.130.159.162, SRC PORT: 443