-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwaldo.bpf.c
131 lines (112 loc) · 3.21 KB
/
waldo.bpf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright(c) 2023 Brian Witte
*/
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
char LICENSE[] SEC("license") = "GPL";
static __always_inline void log_event(const char *event_name, void *dev_ptr)
{
long pid_tgid = bpf_get_current_pid_tgid();
pid_t pid = pid_tgid >> 32;
char comm[16];
bpf_get_current_comm(&comm, sizeof(comm));
if (dev_ptr) {
bpf_printk("pid: %d, command: %s, %s called for dev: %p\n", pid,
comm, event_name, dev_ptr);
} else {
bpf_printk("pid: %d, command: %s, %s called.\n", pid, comm,
event_name);
}
}
SEC("kprobe/ieee80211_register_hw")
int BPF_KPROBE(kprobe_ieee80211_register_hw)
{
log_event("ieee80211_register_hw", NULL);
return 0;
}
SEC("kprobe/ieee80211_unregister_hw")
int BPF_KPROBE(kprobe_ieee80211_unregister_hw)
{
log_event("ieee80211_unregister_hw", NULL);
return 0;
}
SEC("kprobe/register_netdev")
int BPF_KPROBE(kprobe_register_netdev, struct net_device *dev)
{
log_event("register_netdev", dev);
return 0;
}
SEC("kprobe/unregister_netdev")
int BPF_KPROBE(kprobe_unregister_netdev, struct net_device *dev)
{
log_event("unregister_netdev", dev);
return 0;
}
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, u32);
__type(value, u64);
} map_start_time SEC(".maps");
#define SCAN_ID 15170
SEC("kprobe/ieee80211_request_scan")
int BPF_KPROBE(kprobe_ieee80211_request_scan, struct net_device *dev)
{
if (!dev) {
bpf_printk("ieee80211_request_scan: dev is NULL\n");
return 0;
}
u32 hc_scan_id = SCAN_ID;
bpf_printk("ieee80211_request_scan hc_scan_id var=%d\n", &hc_scan_id);
u64 ts = bpf_ktime_get_ns();
int result =
bpf_map_update_elem(&map_start_time, &hc_scan_id, &ts, BPF_ANY);
if (result != 0) {
bpf_printk(
"ieee80211_request_scan: map update failed, hc_scan_id=%u, error=%d\n",
hc_scan_id, result);
}
u64 *start_ts = bpf_map_lookup_elem(&map_start_time, &hc_scan_id);
bpf_printk(
"ieee80211_request_scan: map updated for key->hc_scan_id=%u, value->=%d\n",
hc_scan_id, start_ts);
return 0;
}
SEC("kprobe/ieee80211_scan_completed")
int BPF_KPROBE(kprobe_ieee80211_scan_completed, struct net_device *dev)
{
if (!dev) {
bpf_printk("ieee80211_scan_completed: dev is NULL\n");
return 0;
}
u32 hc_scan_id = SCAN_ID;
bpf_printk("ieee80211_scan_completed hc_scan_id var=%d\n", hc_scan_id);
u64 *start_ts = bpf_map_lookup_elem(&map_start_time, &hc_scan_id);
if (start_ts) {
u64 duration = bpf_ktime_get_ns() - *start_ts;
bpf_printk(
"scan completed! duration is %llu ns, hc_scan_id=%u\n",
duration, hc_scan_id);
int result = bpf_map_delete_elem(&map_start_time, &hc_scan_id);
if (result != 0) {
bpf_printk(
"ieee80211_scan_completed: map delete failed, hc_scan_id=%u, error=%d\n",
hc_scan_id, result);
}
} else {
bpf_printk(
"ieee80211_scan_completed: no start time found for hc_scan_id=%u\n",
hc_scan_id);
}
return 0;
}
SEC("kretprobe/ieee80211_get_channel_khz")
int BPF_KRETPROBE(kretprobe_ieee80211_get_channel_khz,
struct ieee80211_channel *ch)
{
// implement channel tracing logic here
// note: direct dereferencing of ch may not work due to verifier constraints
return 0;
}