Skip to content

Instantly share code, notes, and snippets.

@raffysommy
Created August 6, 2018 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raffysommy/45cf0544f34eb0e5fbf533f4d9a3b955 to your computer and use it in GitHub Desktop.
Save raffysommy/45cf0544f34eb0e5fbf533f4d9a3b955 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
#
from bcc import BPF
import ctypes as ct
# define BPF program
prog = """
#include <linux/sched.h>
#include <linux/bpf.h>
// define output data structure in C
struct data_t {
u64 key;
char map[16];
};
struct fd_pid {
u32 fd;
u32 pid;
};
BPF_PERF_OUTPUT(events);
BPF_HASH(currmap, u32, char*);
#Keep track of fd_pid to map name association
BPF_HASH(mapidfdpid,struct fd_pid,char*);
int kprobe__bpf_map_new_fd(struct pt_regs *ctx, struct bpf_map *map){
u32 pid = bpf_get_current_pid_tgid();
char mapname[16];
bpf_probe_read_str(mapname,16,map->name);
currmap.update(&pid,&mapname);
}
int kretprobe__bpf_map_new_fd(struct pt_regs *ctx){
int ret = PT_REGS_RC(ctx);
u32 pid = bpf_get_current_pid_tgid();
char ** mapname = currmap.lookup(&pid);
if(mapname==0){
return 0;
}
struct fd_pid fd_pid={};
fd_pid.pid=pid;
fd_pid.fd=ret;
mapidfdpid.update(&fd_pid,mapname);
bpf_trace_printk("trace %d %d %s\\n", pid, ret, mapname);
}
int hello(struct pt_regs *ctx, union bpf_attr *attr) {
struct data_t data = {};
u32 pid = bpf_get_current_pid_tgid();
struct fd_pid fd_pid={};
fd_pid.pid=pid;
fd_pid.fd=attr->map_fd;
#Recover mapname from current pid and fd
char** mapname=mapidfdpid.lookup(&fd_pid);
if(mapname==0){
return 0;
}
__aligned_u64 key=attr->key;
bpf_probe_read_str(&(data.map),16U,mapname);
#doing the same operation of map_update elem
void __user *ukey = u64_to_user_ptr(key);
#TODO:!assume that key is a long
bpf_probe_read(&data.key, 8, ukey);
bpf_trace_printk("trace %d %d %s\\n", pid, attr->value, mapname);
events.perf_submit(ctx, &data, sizeof(data));
bpf_trace_printk("trace \\n");
return 0;
}
"""
# load BPF program
b = BPF(text=prog)
b.attach_kprobe(event="map_update_elem", fn_name="hello")
# define output data structure in Python
class Data(ct.Structure):
_fields_ = [("key", ct.c_ulonglong),
("map",ct.c_char*16),]
# process event
start = 0
def print_event(cpu, data, size):
event = ct.cast(data, ct.POINTER(Data)).contents
print("%s %d" % (event.map, event.key))
# loop with callback to print_event
b["events"].open_perf_buffer(print_event)
while 1:
b.perf_buffer_poll()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment