Last active
September 9, 2019 09:45
-
-
Save alessandrod/293bb4dfdf82fd8cc5f7de98e01b10d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::mem::transmute; | |
use cty::*; | |
#[repr(C)] | |
pub struct pt_regs { | |
pub r15: c_ulong, | |
pub r14: c_ulong, | |
pub r13: c_ulong, | |
pub r12: c_ulong, | |
pub bp: c_ulong, | |
pub bx: c_ulong, | |
pub r11: c_ulong, | |
pub r10: c_ulong, | |
pub r9: c_ulong, | |
pub r8: c_ulong, | |
pub ax: c_ulong, | |
pub cx: c_ulong, | |
pub dx: c_ulong, | |
pub si: c_ulong, | |
pub di: c_ulong, | |
pub orig_ax: c_ulong, | |
pub ip: c_ulong, | |
pub cs: c_ulong, | |
pub flags: c_ulong, | |
pub sp: c_ulong, | |
pub ss: c_ulong, | |
} | |
#[repr(C)] | |
#[derive(Copy, Clone)] | |
pub struct bpf_map_def { | |
pub type_: c_uint, | |
pub key_size: c_uint, | |
pub value_size: c_uint, | |
pub max_entries: c_uint, | |
pub map_flags: c_uint, | |
pub pinning: c_uint, | |
pub namespace: [c_char; 256usize], | |
} | |
pub type bpf_map_type = u32; | |
pub const bpf_map_type_BPF_MAP_TYPE_HASH: bpf_map_type = 1; | |
pub const bpf_map_type_BPF_MAP_TYPE_PERF_EVENT_ARRAY: bpf_map_type = 4; | |
#[repr(C)] | |
pub struct Helpers { | |
pub bpf_trace_printk: unsafe extern "C" fn( | |
fmt: *const c_char, | |
fmt_size: c_int, | |
... | |
) -> c_int, | |
pub bpf_map_lookup_elem: unsafe extern "C" fn( | |
map: *mut c_void, | |
key: *mut c_void, | |
) -> *mut c_void, | |
pub bpf_perf_event_output: unsafe extern "C" fn( | |
ctx: *mut c_void, | |
map: *mut c_void, | |
flags: c_ulonglong, | |
data: *mut c_void, | |
size: c_int, | |
) -> c_int, | |
pub bpf_get_smp_processor_id: unsafe extern "C" fn() -> c_ulonglong, | |
pub bpf_get_current_pid_tgid: unsafe extern "C" fn() -> c_ulonglong, | |
pub bpf_get_current_comm: unsafe extern "C" fn( | |
buf: *mut c_void, | |
buf_size: c_int, | |
) -> c_int, | |
} | |
pub type bpf_func_id = u64; | |
pub const bpf_func_id_BPF_FUNC_unspec: bpf_func_id = 0; | |
pub const bpf_func_id_BPF_FUNC_map_lookup_elem: bpf_func_id = 1; | |
pub const bpf_func_id_BPF_FUNC_map_update_elem: bpf_func_id = 2; | |
pub const bpf_func_id_BPF_FUNC_map_delete_elem: bpf_func_id = 3; | |
pub const bpf_func_id_BPF_FUNC_probe_read: bpf_func_id = 4; | |
pub const bpf_func_id_BPF_FUNC_ktime_get_ns: bpf_func_id = 5; | |
pub const bpf_func_id_BPF_FUNC_trace_printk: bpf_func_id = 6; | |
pub const bpf_func_id_BPF_FUNC_get_prandom_u32: bpf_func_id = 7; | |
pub const bpf_func_id_BPF_FUNC_get_smp_processor_id: bpf_func_id = 8; | |
pub const bpf_func_id_BPF_FUNC_skb_store_bytes: bpf_func_id = 9; | |
pub const bpf_func_id_BPF_FUNC_l3_csum_replace: bpf_func_id = 10; | |
pub const bpf_func_id_BPF_FUNC_l4_csum_replace: bpf_func_id = 11; | |
pub const bpf_func_id_BPF_FUNC_tail_call: bpf_func_id = 12; | |
pub const bpf_func_id_BPF_FUNC_clone_redirect: bpf_func_id = 13; | |
pub const bpf_func_id_BPF_FUNC_get_current_pid_tgid: bpf_func_id = 14; | |
pub const bpf_func_id_BPF_FUNC_get_current_uid_gid: bpf_func_id = 15; | |
pub const bpf_func_id_BPF_FUNC_get_current_comm: bpf_func_id = 16; | |
pub const bpf_func_id_BPF_FUNC_get_cgroup_classid: bpf_func_id = 17; | |
pub const bpf_func_id_BPF_FUNC_skb_vlan_push: bpf_func_id = 18; | |
pub const bpf_func_id_BPF_FUNC_skb_vlan_pop: bpf_func_id = 19; | |
pub const bpf_func_id_BPF_FUNC_skb_get_tunnel_key: bpf_func_id = 20; | |
pub const bpf_func_id_BPF_FUNC_skb_set_tunnel_key: bpf_func_id = 21; | |
pub const bpf_func_id_BPF_FUNC_perf_event_read: bpf_func_id = 22; | |
pub const bpf_func_id_BPF_FUNC_redirect: bpf_func_id = 23; | |
pub const bpf_func_id_BPF_FUNC_get_route_realm: bpf_func_id = 24; | |
pub const bpf_func_id_BPF_FUNC_perf_event_output: bpf_func_id = 25; | |
pub const bpf_func_id_BPF_FUNC_skb_load_bytes: bpf_func_id = 26; | |
pub const bpf_func_id_BPF_FUNC_get_stackid: bpf_func_id = 27; | |
pub const bpf_func_id_BPF_FUNC_csum_diff: bpf_func_id = 28; | |
pub const bpf_func_id_BPF_FUNC_skb_get_tunnel_opt: bpf_func_id = 29; | |
pub const bpf_func_id_BPF_FUNC_skb_set_tunnel_opt: bpf_func_id = 30; | |
pub const bpf_func_id_BPF_FUNC_skb_change_proto: bpf_func_id = 31; | |
pub const bpf_func_id_BPF_FUNC_skb_change_type: bpf_func_id = 32; | |
pub const bpf_func_id_BPF_FUNC_skb_under_cgroup: bpf_func_id = 33; | |
pub const bpf_func_id_BPF_FUNC_get_hash_recalc: bpf_func_id = 34; | |
pub const bpf_func_id_BPF_FUNC_get_current_task: bpf_func_id = 35; | |
pub const bpf_func_id_BPF_FUNC_probe_write_user: bpf_func_id = 36; | |
pub const bpf_func_id_BPF_FUNC_current_task_under_cgroup: bpf_func_id = 37; | |
pub const bpf_func_id_BPF_FUNC_skb_change_tail: bpf_func_id = 38; | |
pub const bpf_func_id_BPF_FUNC_skb_pull_data: bpf_func_id = 39; | |
pub const bpf_func_id_BPF_FUNC_csum_update: bpf_func_id = 40; | |
pub const bpf_func_id_BPF_FUNC_set_hash_invalid: bpf_func_id = 41; | |
pub const bpf_func_id_BPF_FUNC_get_numa_node_id: bpf_func_id = 42; | |
pub const bpf_func_id_BPF_FUNC_skb_change_head: bpf_func_id = 43; | |
pub const bpf_func_id_BPF_FUNC_xdp_adjust_head: bpf_func_id = 44; | |
pub const bpf_func_id_BPF_FUNC_probe_read_str: bpf_func_id = 45; | |
pub const bpf_func_id_BPF_FUNC_get_socket_cookie: bpf_func_id = 46; | |
pub const bpf_func_id_BPF_FUNC_get_socket_uid: bpf_func_id = 47; | |
pub const bpf_func_id_BPF_FUNC_set_hash: bpf_func_id = 48; | |
pub const bpf_func_id_BPF_FUNC_setsockopt: bpf_func_id = 49; | |
pub const bpf_func_id_BPF_FUNC_skb_adjust_room: bpf_func_id = 50; | |
pub const bpf_func_id_BPF_FUNC_redirect_map: bpf_func_id = 51; | |
pub const bpf_func_id_BPF_FUNC_sk_redirect_map: bpf_func_id = 52; | |
pub const bpf_func_id_BPF_FUNC_sock_map_update: bpf_func_id = 53; | |
pub const bpf_func_id_BPF_FUNC_xdp_adjust_meta: bpf_func_id = 54; | |
pub const bpf_func_id_BPF_FUNC_perf_event_read_value: bpf_func_id = 55; | |
pub const bpf_func_id_BPF_FUNC_perf_prog_read_value: bpf_func_id = 56; | |
pub const bpf_func_id_BPF_FUNC_getsockopt: bpf_func_id = 57; | |
pub const bpf_func_id___BPF_FUNC_MAX_ID: bpf_func_id = 58; | |
pub const fn helpers() -> Helpers { | |
Helpers { | |
bpf_trace_printk: unsafe { transmute(bpf_func_id_BPF_FUNC_trace_printk) }, | |
bpf_map_lookup_elem: unsafe { transmute(bpf_func_id_BPF_FUNC_map_lookup_elem) }, | |
bpf_perf_event_output: unsafe { transmute(bpf_func_id_BPF_FUNC_perf_event_output) }, | |
bpf_get_smp_processor_id: unsafe { transmute(bpf_func_id_BPF_FUNC_get_smp_processor_id) }, | |
bpf_get_current_pid_tgid: unsafe { transmute(bpf_func_id_BPF_FUNC_get_current_pid_tgid) }, | |
bpf_get_current_comm: unsafe { transmute(bpf_func_id_BPF_FUNC_get_current_comm) }, | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::marker::PhantomData; | |
use core::mem; | |
use cty::*; | |
use crate::bindings::*; | |
#[repr(transparent)] | |
pub struct HashMap<K, V> { | |
def: bpf_map_def, | |
_k: PhantomData<K>, | |
_v: PhantomData<V> | |
} | |
impl<K, V: Copy> HashMap<K, V> { | |
pub const fn new() -> Self { | |
Self { | |
def: bpf_map_def { | |
type_: bpf_map_type_BPF_MAP_TYPE_HASH, | |
key_size: mem::size_of::<K>() as u32, | |
value_size: mem::size_of::<V>() as u32, | |
max_entries: 10240u32, | |
map_flags: 0u32, | |
pinning: 0u32, | |
namespace: [0; 256], | |
}, | |
_k: PhantomData, | |
_v: PhantomData | |
} | |
} | |
pub fn get(&mut self, mut key: K) -> Option<&V> { | |
let Helpers { | |
bpf_map_lookup_elem, | |
.. | |
} = helpers(); | |
let value = unsafe { | |
let value = bpf_map_lookup_elem(&mut self.def as *mut _ as *mut c_void, &mut key as *mut _ as *mut c_void); | |
if value.is_null() { | |
None | |
} else { | |
Some(&*(value as *const V)) | |
} | |
}; | |
value | |
} | |
} | |
#[repr(transparent)] | |
pub struct PerfMap<T> { | |
def: bpf_map_def, | |
_event: PhantomData<T> | |
} | |
impl<T> PerfMap<T> { | |
pub const fn new() -> Self { | |
Self { | |
def: bpf_map_def { | |
type_: bpf_map_type_BPF_MAP_TYPE_PERF_EVENT_ARRAY, | |
key_size: mem::size_of::<u32>() as u32, | |
value_size: mem::size_of::<u32>() as u32, | |
max_entries: 10240u32, | |
map_flags: 0u32, | |
pinning: 0u32, | |
namespace: [0; 256], | |
}, | |
_event: PhantomData | |
} | |
} | |
pub fn insert<C>(&mut self, ctx: *mut C, mut data: T) { | |
let Helpers { | |
bpf_perf_event_output, | |
bpf_get_smp_processor_id, | |
.. | |
} = helpers(); | |
let cpu = unsafe { bpf_get_smp_processor_id() }; | |
unsafe { | |
bpf_perf_event_output( | |
ctx as *mut _ as *mut c_void, | |
&mut self.def as *mut _ as *mut c_void, | |
cpu, | |
&mut data as *mut _ as *mut c_void, | |
mem::size_of::<T>() as i32, | |
); | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(const_fn)] | |
#![feature(const_transmute)] | |
#![no_std] | |
mod bindings; | |
mod maps; | |
use cty::*; | |
use bindings::*; | |
use maps::*; | |
#[no_mangle] | |
#[link_section = "license"] | |
pub static _license: [u8; 4] = [71u8, 80, 76, 0]; //b"GPL\0" | |
#[no_mangle] | |
#[link_section = "version"] | |
pub static _version: u32 = 0xFFFFFFFE; | |
#[no_mangle] | |
#[link_section = "maps/syscall_tp_trigger"] | |
static mut syscall_event: PerfMap<_data_syscall_tracepoint> = PerfMap::new(); | |
#[no_mangle] | |
#[link_section = "maps/host_pid"] | |
static mut host_pid: HashMap<u8, u64> = HashMap::new(); | |
#[no_mangle] | |
#[link_section = "kprobe/syscall_enter"] | |
pub extern "C" fn syscall_enter(ctx: *mut c_void) -> i32 { | |
let Helpers { | |
bpf_get_current_pid_tgid, | |
.. | |
} = helpers(); | |
let ignore_pid = unsafe { host_pid.get(1u8) }; | |
let pid_tgid = unsafe { bpf_get_current_pid_tgid() }; | |
if let Some(pid) = ignore_pid { | |
if *pid == pid_tgid >> 32 { | |
return 0; | |
} | |
} | |
let data = _data_syscall_tracepoint::new(ctx, pid_tgid >> 32); | |
unsafe { syscall_event.insert(ctx, data) }; | |
return 0; | |
} | |
#[repr(C)] | |
struct _data_syscall_tracepoint { | |
id: c_ulonglong, | |
syscall_nr: c_ulonglong, | |
comm: [c_char; 16usize], | |
} | |
impl _data_syscall_tracepoint { | |
fn new<C>(ctx: *mut C, pid: u64) -> Self { | |
let Helpers { | |
bpf_get_current_comm, | |
.. | |
} = helpers(); | |
let mut comm: [c_char; 16usize] = [0i8; 16] ; | |
unsafe { bpf_get_current_comm(&mut comm as *mut _ as *mut c_void, 16i32) }; | |
let data = _data_syscall_tracepoint { | |
id: pid, | |
syscall_nr: unsafe { (*(ctx as *mut pt_regs)).ax }, | |
comm | |
}; | |
data | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment