forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.3 KiB
102 lines
2.3 KiB
/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com |
|
* |
|
* This program is free software; you can redistribute it and/or |
|
* modify it under the terms of version 2 of the GNU General Public |
|
* License as published by the Free Software Foundation. |
|
*/ |
|
#include <linux/skbuff.h> |
|
#include <linux/netdevice.h> |
|
#include <linux/version.h> |
|
#include <uapi/linux/bpf.h> |
|
#include <bpf/bpf_helpers.h> |
|
#include <bpf/bpf_tracing.h> |
|
#include "trace_common.h" |
|
|
|
struct { |
|
__uint(type, BPF_MAP_TYPE_HASH); |
|
__type(key, long); |
|
__type(value, long); |
|
__uint(max_entries, 1024); |
|
} my_map SEC(".maps"); |
|
|
|
/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe |
|
* example will no longer be meaningful |
|
*/ |
|
SEC("kprobe/kfree_skb") |
|
int bpf_prog2(struct pt_regs *ctx) |
|
{ |
|
long loc = 0; |
|
long init_val = 1; |
|
long *value; |
|
|
|
/* read ip of kfree_skb caller. |
|
* non-portable version of __builtin_return_address(0) |
|
*/ |
|
BPF_KPROBE_READ_RET_IP(loc, ctx); |
|
|
|
value = bpf_map_lookup_elem(&my_map, &loc); |
|
if (value) |
|
*value += 1; |
|
else |
|
bpf_map_update_elem(&my_map, &loc, &init_val, BPF_ANY); |
|
return 0; |
|
} |
|
|
|
static unsigned int log2(unsigned int v) |
|
{ |
|
unsigned int r; |
|
unsigned int shift; |
|
|
|
r = (v > 0xFFFF) << 4; v >>= r; |
|
shift = (v > 0xFF) << 3; v >>= shift; r |= shift; |
|
shift = (v > 0xF) << 2; v >>= shift; r |= shift; |
|
shift = (v > 0x3) << 1; v >>= shift; r |= shift; |
|
r |= (v >> 1); |
|
return r; |
|
} |
|
|
|
static unsigned int log2l(unsigned long v) |
|
{ |
|
unsigned int hi = v >> 32; |
|
if (hi) |
|
return log2(hi) + 32; |
|
else |
|
return log2(v); |
|
} |
|
|
|
struct hist_key { |
|
char comm[16]; |
|
u64 pid_tgid; |
|
u64 uid_gid; |
|
u64 index; |
|
}; |
|
|
|
struct { |
|
__uint(type, BPF_MAP_TYPE_PERCPU_HASH); |
|
__uint(key_size, sizeof(struct hist_key)); |
|
__uint(value_size, sizeof(long)); |
|
__uint(max_entries, 1024); |
|
} my_hist_map SEC(".maps"); |
|
|
|
SEC("kprobe/" SYSCALL(sys_write)) |
|
int bpf_prog3(struct pt_regs *ctx) |
|
{ |
|
long write_size = PT_REGS_PARM3(ctx); |
|
long init_val = 1; |
|
long *value; |
|
struct hist_key key; |
|
|
|
key.index = log2l(write_size); |
|
key.pid_tgid = bpf_get_current_pid_tgid(); |
|
key.uid_gid = bpf_get_current_uid_gid(); |
|
bpf_get_current_comm(&key.comm, sizeof(key.comm)); |
|
|
|
value = bpf_map_lookup_elem(&my_hist_map, &key); |
|
if (value) |
|
__sync_fetch_and_add(value, 1); |
|
else |
|
bpf_map_update_elem(&my_hist_map, &key, &init_val, BPF_ANY); |
|
return 0; |
|
} |
|
char _license[] SEC("license") = "GPL"; |
|
u32 _version SEC("version") = LINUX_VERSION_CODE;
|
|
|